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

Version Description

(May 7, 2018) = * Closed Bug: %QUESTIONS_ANSWERS% variable is displaying questions in order of creation - (Issue #660) * Closed Bug: Extra spacing is being added to questions when multiple lines are in question - (Issue #659) * Closed Bug: Tabs pages stop working when translated - (Issue #582)

Download this release

Release Info

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

Code changes from version 5.2.3 to 5.2.4

CONTRIBUTING.md CHANGED
@@ -35,7 +35,7 @@ If you are reporting a bug, please follow these guidlines first to see if any of
35
  * Make the changes to your forked repository
36
  * Ensure you stick to the [WordPress Coding Standards](https://codex.wordpress.org/WordPress_Coding_Standards)
37
  * When committing, reference your issue (if present) and include a note about the fix
38
- * Push the changes to your fork and submit a pull request to the 'master' branch of the QMN repository
39
 
40
  ## Code Documentation
41
 
35
  * Make the changes to your forked repository
36
  * Ensure you stick to the [WordPress Coding Standards](https://codex.wordpress.org/WordPress_Coding_Standards)
37
  * When committing, reference your issue (if present) and include a note about the fix
38
+ * Push the changes to your fork and submit a pull request to the 'master' branch of the QSM repository
39
 
40
  ## Code Documentation
41
 
assets/screenshot-1.png CHANGED
Binary file
assets/screenshot-2.png CHANGED
Binary file
assets/screenshot-6.png CHANGED
Binary file
js/qsm-admin-question.js CHANGED
@@ -277,7 +277,9 @@ var QSMQuestion;
277
  var questionText = QSMQuestion.prepareQuestionText( question.get( 'name' ) );
278
  $( '#edit_question_id' ).val( questionID );
279
  var question_editor = tinyMCE.get( 'question-text' );
280
- if ( question_editor ) {
 
 
281
  tinyMCE.get( 'question-text' ).setContent( questionText );
282
  } else {
283
  jQuery( "#question-text" ).val( questionText );
@@ -328,6 +330,7 @@ var QSMQuestion;
328
  var settings = {
329
  mediaButtons: true,
330
  tinymce: {
 
331
  toolbar1: 'formatselect,bold,italic,bullist,numlist,link,blockquote,alignleft,aligncenter,alignright,strikethrough,hr,forecolor,pastetext,removeformat,codeformat,undo,redo'
332
  },
333
  quicktags: true,
277
  var questionText = QSMQuestion.prepareQuestionText( question.get( 'name' ) );
278
  $( '#edit_question_id' ).val( questionID );
279
  var question_editor = tinyMCE.get( 'question-text' );
280
+ if ($('#wp-question-text-wrap').hasClass('html-active')) {
281
+ jQuery( "#question-text" ).val( questionText );
282
+ } else if ( question_editor ) {
283
  tinyMCE.get( 'question-text' ).setContent( questionText );
284
  } else {
285
  jQuery( "#question-text" ).val( questionText );
330
  var settings = {
331
  mediaButtons: true,
332
  tinymce: {
333
+ forced_root_block : '',
334
  toolbar1: 'formatselect,bold,italic,bullist,numlist,link,blockquote,alignleft,aligncenter,alignright,strikethrough,hr,forecolor,pastetext,removeformat,codeformat,undo,redo'
335
  },
336
  quicktags: true,
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.2.3
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.2.3
13
  * @package QSM
14
  */
15
 
@@ -33,7 +33,7 @@ class MLWQuizMasterNext {
33
  * @var string
34
  * @since 4.0.0
35
  */
36
- public $version = '5.2.3';
37
 
38
  /**
39
  * QSM Alert Manager Object
@@ -138,7 +138,7 @@ class MLWQuizMasterNext {
138
  include 'php/admin/options-page-preview-tab.php';
139
  include 'php/admin/addons-page.php';
140
  include 'php/admin/settings-page.php';
141
- include 'php/classes/class-qmn-tracking.php';
142
  include 'php/classes/class-qmn-review-message.php';
143
  }
144
  include 'php/classes/class-qsm-questions.php';
2
  /**
3
  * Plugin Name: Quiz And Survey Master
4
  * Description: Easily and quickly add quizzes and surveys to your website.
5
+ * Version: 5.2.4
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.2.4
13
  * @package QSM
14
  */
15
 
33
  * @var string
34
  * @since 4.0.0
35
  */
36
+ public $version = '5.2.4';
37
 
38
  /**
39
  * QSM Alert Manager Object
138
  include 'php/admin/options-page-preview-tab.php';
139
  include 'php/admin/addons-page.php';
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';
php/admin/about-page.php CHANGED
@@ -49,6 +49,7 @@ function mlw_generate_about_page() {
49
  </div>
50
  <div class="qsm-tab-content tab-2" style="display: none;">
51
  <h2>Changelog</h2>
 
52
  <?php QSM_Changelog_Generator::get_changelog_list( 'fpcorso/quiz_master_next', 48 ); ?>
53
  <?php QSM_Changelog_Generator::get_changelog_list( 'fpcorso/quiz_master_next', 32 ); ?>
54
  </div>
49
  </div>
50
  <div class="qsm-tab-content tab-2" style="display: none;">
51
  <h2>Changelog</h2>
52
+ <?php QSM_Changelog_Generator::get_changelog_list( 'fpcorso/quiz_master_next', 49 ); ?>
53
  <?php QSM_Changelog_Generator::get_changelog_list( 'fpcorso/quiz_master_next', 48 ); ?>
54
  <?php QSM_Changelog_Generator::get_changelog_list( 'fpcorso/quiz_master_next', 32 ); ?>
55
  </div>
php/admin/addons-page.php CHANGED
@@ -14,7 +14,7 @@ function qmn_addons_page() {
14
  }
15
 
16
  global $mlwQuizMasterNext;
17
- $active_tab = isset( $_GET[ 'tab' ] ) ? $_GET[ 'tab' ] : 'featured-addons';
18
  $tab_array = $mlwQuizMasterNext->pluginHelper->get_addon_tabs();
19
  ?>
20
  <div class="wrap">
14
  }
15
 
16
  global $mlwQuizMasterNext;
17
+ $active_tab = strtolower(str_replace( " ", "-", isset( $_GET[ 'tab' ] ) ? $_GET[ 'tab' ] : __( "Featured Addons", 'quiz-master-next' )));
18
  $tab_array = $mlwQuizMasterNext->pluginHelper->get_addon_tabs();
19
  ?>
20
  <div class="wrap">
php/admin/admin-results-page.php CHANGED
@@ -16,7 +16,7 @@ function qsm_generate_admin_results_page() {
16
 
17
  // Retrieves the current stab and all registered tabs
18
  global $mlwQuizMasterNext;
19
- $active_tab = isset( $_GET[ 'tab' ] ) ? $_GET[ 'tab' ] : 'quiz-results';
20
  $tab_array = $mlwQuizMasterNext->pluginHelper->get_admin_results_tabs();
21
 
22
  ?>
@@ -319,6 +319,7 @@ function qsm_results_overview_tab_content() {
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
  </tr>
323
  </thead>
324
  <?php
@@ -370,6 +371,7 @@ function qsm_results_overview_tab_content() {
370
  $date = date_i18n( get_option( 'date_format' ), strtotime( $mlw_quiz_info->time_taken ) );
371
  $time = date( "h:i:s A", strtotime( $mlw_quiz_info->time_taken ) );
372
  $quotes_list .= "<td><span style='font-size:16px;'>$date $time</span></td>";
 
373
  $quotes_list .= "</tr>";
374
  }
375
  $display .= "<tbody id=\"the-list\">{$quotes_list}</tbody>";
16
 
17
  // Retrieves the current stab and all registered tabs
18
  global $mlwQuizMasterNext;
19
+ $active_tab = strtolower(str_replace( " ", "-", isset( $_GET[ 'tab' ] ) ? $_GET[ 'tab' ] : __( 'Quiz Results', 'quiz-master-next' )));
20
  $tab_array = $mlwQuizMasterNext->pluginHelper->get_admin_results_tabs();
21
 
22
  ?>
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>
324
  </thead>
325
  <?php
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>";
374
+ $quotes_list .= "<td><span style='font-size:16px;'>" . $mlw_quiz_info->user_ip . "</span></td>";
375
  $quotes_list .= "</tr>";
376
  }
377
  $display .= "<tbody id=\"the-list\">{$quotes_list}</tbody>";
php/admin/quiz-options-page.php CHANGED
@@ -21,7 +21,7 @@ function qsm_generate_quiz_options() {
21
 
22
  // Get registered tabs for the options page and set current tab
23
  $tab_array = $mlwQuizMasterNext->pluginHelper->get_settings_tabs();
24
- $active_tab = isset( $_GET[ 'tab' ] ) ? stripslashes( $_GET[ 'tab' ] ) : 'questions';
25
 
26
  // Prepares quiz.
27
  $quiz_id = isset( $_GET['quiz_id'] ) ? intval( $_GET['quiz_id'] ) : 0;
21
 
22
  // Get registered tabs for the options page and set current tab
23
  $tab_array = $mlwQuizMasterNext->pluginHelper->get_settings_tabs();
24
+ $active_tab = strtolower(str_replace( " ", "-", isset( $_GET[ 'tab' ] ) ? stripslashes( $_GET[ 'tab' ] ) : __( 'Questions', 'quiz-master-next' )));
25
 
26
  // Prepares quiz.
27
  $quiz_id = isset( $_GET['quiz_id'] ) ? intval( $_GET['quiz_id'] ) : 0;
php/classes/class-qmn-quiz-manager.php CHANGED
@@ -137,9 +137,7 @@ class QMNQuizManager {
137
  if ( $qmn_allowed_visit && ! isset( $_POST["complete_quiz"] ) && ! empty( $qmn_quiz_options->quiz_name ) ) {
138
  $return_display .= $this->display_quiz( $qmn_quiz_options, $qmn_array_for_variables, $question_amount );
139
  } elseif ( isset( $_POST["complete_quiz"] ) && 'confirmation' == $_POST["complete_quiz"] && $_POST["qmn_quiz_id"] == $qmn_array_for_variables["quiz_id"] ) {
140
- $qmn_quiz_questions = $this->load_questions( $quiz, $qmn_quiz_options, false );
141
- $qmn_quiz_answers = $this->create_answer_array( $qmn_quiz_questions );
142
- $return_display .= $this->display_results( $qmn_quiz_options, $qmn_quiz_questions, $qmn_quiz_answers, $qmn_array_for_variables );
143
  }
144
 
145
  $qmn_filtered_json = apply_filters( 'qmn_json_data', $qmn_json_data, $qmn_quiz_options, $qmn_array_for_variables );
@@ -666,15 +664,13 @@ class QMNQuizManager {
666
  * Generates the content for the results page part of the shortcode
667
  *
668
  * @since 4.0.0
669
- * @param array $qmn_quiz_options The database row of the quiz.
670
- * @param array $qmn_quiz_questions The questions of the quiz.
671
- * @param array $qmn_quiz_answers The answers of the quiz.
672
- * @param array $qmn_array_for_variables The array of results for the quiz.
673
  * @uses QMNQuizManager:submit_results() Perform The Quiz/Survey Submission
674
  * @return string The content for the results page section
675
  */
676
- public function display_results( $qmn_quiz_options, $qmn_quiz_questions, $qmn_quiz_answers, $qmn_array_for_variables ) {
677
- $result = $this->submit_results( $qmn_quiz_options, $qmn_quiz_questions, $qmn_quiz_answers, $qmn_array_for_variables );
678
  $results_array = $result;
679
  return $results_array['display'];
680
  }
@@ -693,15 +689,13 @@ class QMNQuizManager {
693
  $qmn_allowed_visit = true;
694
  $quiz = intval( $_POST["qmn_quiz_id"] );
695
  $mlwQuizMasterNext->pluginHelper->prepare_quiz( $quiz );
696
- $qmn_quiz_options = $mlwQuizMasterNext->quiz_settings->get_quiz_options();
697
- $qmn_quiz_questions = $this->load_questions( $quiz, $qmn_quiz_options, false );
698
- $qmn_quiz_answers = $this->create_answer_array( $qmn_quiz_questions, true );
699
- $qmn_array_for_variables = array(
700
- 'quiz_id' => $qmn_quiz_options->quiz_id,
701
- 'quiz_name' => $qmn_quiz_options->quiz_name,
702
- 'quiz_system' => $qmn_quiz_options->system,
703
  );
704
- echo json_encode( $this->submit_results( $qmn_quiz_options, $qmn_quiz_questions, $qmn_quiz_answers, $qmn_array_for_variables) );
705
  die();
706
  }
707
 
@@ -712,8 +706,6 @@ class QMNQuizManager {
712
  *
713
  * @since 4.6.0
714
  * @param array $qmn_quiz_options The database row of the quiz.
715
- * @param array $qmn_quiz_questions The questions of the quiz.
716
- * @param array $qmn_quiz_answers The answers of the quiz.
717
  * @param array $qmn_array_for_variables The array of results for the quiz.
718
  * @uses QMNQuizManager:check_answers() Creates display for beginning section
719
  * @uses QMNQuizManager:check_comment_section() Creates display for questions
@@ -723,7 +715,7 @@ class QMNQuizManager {
723
  * @uses QMNQuizManager:send_admin_email() Creates display for end section
724
  * @return string The content for the results page section
725
  */
726
- public function submit_results( $qmn_quiz_options, $qmn_quiz_questions, $qmn_quiz_answers, $qmn_array_for_variables ) {
727
  global $qmn_allowed_visit;
728
  $result_display = '';
729
 
@@ -769,7 +761,7 @@ class QMNQuizManager {
769
 
770
  if ( !isset( $_POST["mlw_code_captcha"] ) || ( isset( $_POST["mlw_code_captcha"] ) && $_POST["mlw_user_captcha"] == $_POST["mlw_code_captcha"] ) ) {
771
 
772
- $qmn_array_for_variables = array_merge($qmn_array_for_variables,$this->check_answers($qmn_quiz_questions, $qmn_quiz_answers, $qmn_quiz_options, $qmn_array_for_variables));
773
  $result_display = apply_filters('qmn_after_check_answers', $result_display, $qmn_quiz_options, $qmn_array_for_variables);
774
  $qmn_array_for_variables['comments'] = $this->check_comment_section($qmn_quiz_options, $qmn_array_for_variables);
775
  $result_display = apply_filters('qmn_after_check_comments', $result_display, $qmn_quiz_options, $qmn_array_for_variables);
@@ -793,23 +785,23 @@ class QMNQuizManager {
793
  $results_insert = $wpdb->insert(
794
  $table_name,
795
  array(
796
- 'quiz_id' => $qmn_array_for_variables['quiz_id'],
797
- 'quiz_name' => $qmn_array_for_variables['quiz_name'],
798
- 'quiz_system' => $qmn_array_for_variables['quiz_system'],
799
- 'point_score' => $qmn_array_for_variables['total_points'],
800
- 'correct_score' => $qmn_array_for_variables['total_score'],
801
- 'correct' => $qmn_array_for_variables['total_correct'],
802
- 'total' => $qmn_array_for_variables['total_questions'],
803
- 'name' => $qmn_array_for_variables['user_name'],
804
- 'business' => $qmn_array_for_variables['user_business'],
805
- 'email' => $qmn_array_for_variables['user_email'],
806
- 'phone' => $qmn_array_for_variables['user_phone'],
807
- 'user' => $qmn_array_for_variables['user_id'],
808
- 'user_ip' => $qmn_array_for_variables['user_ip'],
809
- 'time_taken' => $qmn_array_for_variables['time_taken'],
810
  'time_taken_real' => date( "Y-m-d H:i:s", strtotime( $qmn_array_for_variables['time_taken'] ) ),
811
- 'quiz_results' => $serialized_results,
812
- 'deleted' => 0
813
  ),
814
  array(
815
  '%d',
@@ -840,9 +832,7 @@ class QMNQuizManager {
840
  $result_display = apply_filters('qmn_end_results', $result_display, $qmn_quiz_options, $qmn_array_for_variables);
841
  //Legacy Code
842
  do_action('mlw_qmn_load_results_page', $wpdb->insert_id, $qmn_quiz_options->quiz_settings);
843
- }
844
- else
845
- {
846
  $result_display .= "Thank you.";
847
  }
848
 
@@ -902,92 +892,185 @@ class QMNQuizManager {
902
  }
903
 
904
  /**
905
- * Scores User Answers
906
- *
907
- * Calculates the users scores for the quiz
908
- *
909
- * @since 4.0.0
910
- * @param array $qmn_quiz_options The database row of the quiz
911
- * @param array $qmn_quiz_questions The questions of the quiz
912
- * @param array $qmn_quiz_answers The answers of the quiz
913
- * @param array $qmn_array_for_variables The array of results for the quiz
914
- * @uses QMNPluginHelper:display_review() Scores the question
915
- * @return array The results of the user's score
916
- */
917
- public function check_answers($qmn_quiz_questions, $qmn_quiz_answers, $qmn_quiz_options, $qmn_array_for_variables)
918
- {
919
- $mlw_points = 0;
920
- $mlw_correct = 0;
921
- $mlw_total_score = 0;
922
- $mlw_question_answers = "";
923
  global $mlwQuizMasterNext;
924
- isset($_POST["total_questions"]) ? $mlw_total_questions = intval($_POST["total_questions"]) : $mlw_total_questions = 0;
925
- isset($_POST["qmn_question_list"]) ? $question_list = explode('Q',$_POST["qmn_question_list"]) : $question_list = array();
926
- $mlw_user_text = "";
927
- $mlw_correct_text = "";
928
- $qmn_correct = "incorrect";
929
- $qmn_answer_points = 0;
930
- $mlw_qmn_answer_array = array();
931
- foreach($qmn_quiz_questions as $mlw_question)
932
- {
933
- foreach($question_list as $question_id)
934
- {
935
- if ($mlw_question->question_id == $question_id)
936
- {
937
- $mlw_user_text = "";
938
- $mlw_correct_text = "";
939
- $qmn_correct = "incorrect";
940
- $qmn_answer_points = 0;
941
 
942
- $results_array = $mlwQuizMasterNext->pluginHelper->display_review($mlw_question->question_type_new, $mlw_question->question_id);
943
- if (!isset($results_array["null_review"]))
944
- {
945
- $mlw_points += $results_array["points"];
946
- $qmn_answer_points += $results_array["points"];
947
- if ($results_array["correct"] == "correct")
948
- {
949
- $mlw_correct += 1;
950
- $qmn_correct = "correct";
951
- }
952
- $mlw_user_text = $results_array["user_text"];
953
- $mlw_correct_text = $results_array["correct_text"];
 
 
 
 
 
954
 
955
- if ( isset( $_POST["mlwComment".$mlw_question->question_id] ) ) {
956
- $mlw_qm_question_comment = htmlspecialchars( stripslashes( $_POST["mlwComment".$mlw_question->question_id] ), ENT_QUOTES );
957
- } else {
958
- $mlw_qm_question_comment = "";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
959
  }
960
- $question_text = $mlw_question->question_name;
961
- if (isset($results_array["question_text"]))
962
- {
963
- $question_text = $results_array["question_text"];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
964
  }
965
- $mlw_qmn_answer_array[] = apply_filters('qmn_answer_array', array($question_text, htmlspecialchars($mlw_user_text, ENT_QUOTES), htmlspecialchars($mlw_correct_text, ENT_QUOTES), $mlw_qm_question_comment, "correct" => $qmn_correct, "id" => $mlw_question->question_id, "points" => $qmn_answer_points, "category" => $mlw_question->category), $qmn_quiz_options, $qmn_array_for_variables);
966
  }
967
- break;
968
  }
969
  }
970
  }
971
 
972
- //Calculate Total Percent Score And Average Points Only If Total Questions Doesn't Equal Zero To Avoid Division By Zero Error
973
- if ($mlw_total_questions != 0)
974
- {
975
- $mlw_total_score = round((($mlw_correct/$mlw_total_questions)*100), 2);
976
- $mlw_average_points = round(($mlw_points/$mlw_total_questions), 2);
977
- }
978
- else
979
- {
980
- $mlw_total_score = 0;
981
- $mlw_average_points = 0;
982
  }
983
 
 
984
  return array(
985
- 'total_points' => $mlw_points,
986
- 'total_score' => $mlw_total_score,
987
- 'total_correct' => $mlw_correct,
988
- 'total_questions' => $mlw_total_questions,
989
- 'question_answers_display' => $mlw_question_answers,
990
- 'question_answers_array' => $mlw_qmn_answer_array,
991
  );
992
  }
993
 
137
  if ( $qmn_allowed_visit && ! isset( $_POST["complete_quiz"] ) && ! empty( $qmn_quiz_options->quiz_name ) ) {
138
  $return_display .= $this->display_quiz( $qmn_quiz_options, $qmn_array_for_variables, $question_amount );
139
  } elseif ( isset( $_POST["complete_quiz"] ) && 'confirmation' == $_POST["complete_quiz"] && $_POST["qmn_quiz_id"] == $qmn_array_for_variables["quiz_id"] ) {
140
+ $return_display .= $this->display_results( $qmn_quiz_options, $qmn_array_for_variables );
 
 
141
  }
142
 
143
  $qmn_filtered_json = apply_filters( 'qmn_json_data', $qmn_json_data, $qmn_quiz_options, $qmn_array_for_variables );
664
  * Generates the content for the results page part of the shortcode
665
  *
666
  * @since 4.0.0
667
+ * @param array $options The database row of the quiz.
668
+ * @param array $data The array of results for the quiz.
 
 
669
  * @uses QMNQuizManager:submit_results() Perform The Quiz/Survey Submission
670
  * @return string The content for the results page section
671
  */
672
+ public function display_results( $options, $data ) {
673
+ $result = $this->submit_results( $options, $data );
674
  $results_array = $result;
675
  return $results_array['display'];
676
  }
689
  $qmn_allowed_visit = true;
690
  $quiz = intval( $_POST["qmn_quiz_id"] );
691
  $mlwQuizMasterNext->pluginHelper->prepare_quiz( $quiz );
692
+ $options = $mlwQuizMasterNext->quiz_settings->get_quiz_options();
693
+ $data = array(
694
+ 'quiz_id' => $options->quiz_id,
695
+ 'quiz_name' => $options->quiz_name,
696
+ 'quiz_system' => $options->system,
 
 
697
  );
698
+ echo json_encode( $this->submit_results( $options, $data ) );
699
  die();
700
  }
701
 
706
  *
707
  * @since 4.6.0
708
  * @param array $qmn_quiz_options The database row of the quiz.
 
 
709
  * @param array $qmn_array_for_variables The array of results for the quiz.
710
  * @uses QMNQuizManager:check_answers() Creates display for beginning section
711
  * @uses QMNQuizManager:check_comment_section() Creates display for questions
715
  * @uses QMNQuizManager:send_admin_email() Creates display for end section
716
  * @return string The content for the results page section
717
  */
718
+ public function submit_results( $qmn_quiz_options, $qmn_array_for_variables ) {
719
  global $qmn_allowed_visit;
720
  $result_display = '';
721
 
761
 
762
  if ( !isset( $_POST["mlw_code_captcha"] ) || ( isset( $_POST["mlw_code_captcha"] ) && $_POST["mlw_user_captcha"] == $_POST["mlw_code_captcha"] ) ) {
763
 
764
+ $qmn_array_for_variables = array_merge( $qmn_array_for_variables, $this->check_answers( $qmn_quiz_options, $qmn_array_for_variables ) );
765
  $result_display = apply_filters('qmn_after_check_answers', $result_display, $qmn_quiz_options, $qmn_array_for_variables);
766
  $qmn_array_for_variables['comments'] = $this->check_comment_section($qmn_quiz_options, $qmn_array_for_variables);
767
  $result_display = apply_filters('qmn_after_check_comments', $result_display, $qmn_quiz_options, $qmn_array_for_variables);
785
  $results_insert = $wpdb->insert(
786
  $table_name,
787
  array(
788
+ 'quiz_id' => $qmn_array_for_variables['quiz_id'],
789
+ 'quiz_name' => $qmn_array_for_variables['quiz_name'],
790
+ 'quiz_system' => $qmn_array_for_variables['quiz_system'],
791
+ 'point_score' => $qmn_array_for_variables['total_points'],
792
+ 'correct_score' => $qmn_array_for_variables['total_score'],
793
+ 'correct' => $qmn_array_for_variables['total_correct'],
794
+ 'total' => $qmn_array_for_variables['total_questions'],
795
+ 'name' => $qmn_array_for_variables['user_name'],
796
+ 'business' => $qmn_array_for_variables['user_business'],
797
+ 'email' => $qmn_array_for_variables['user_email'],
798
+ 'phone' => $qmn_array_for_variables['user_phone'],
799
+ 'user' => $qmn_array_for_variables['user_id'],
800
+ 'user_ip' => $qmn_array_for_variables['user_ip'],
801
+ 'time_taken' => $qmn_array_for_variables['time_taken'],
802
  'time_taken_real' => date( "Y-m-d H:i:s", strtotime( $qmn_array_for_variables['time_taken'] ) ),
803
+ 'quiz_results' => $serialized_results,
804
+ 'deleted' => 0
805
  ),
806
  array(
807
  '%d',
832
  $result_display = apply_filters('qmn_end_results', $result_display, $qmn_quiz_options, $qmn_array_for_variables);
833
  //Legacy Code
834
  do_action('mlw_qmn_load_results_page', $wpdb->insert_id, $qmn_quiz_options->quiz_settings);
835
+ } else {
 
 
836
  $result_display .= "Thank you.";
837
  }
838
 
892
  }
893
 
894
  /**
895
+ * Scores User Answers
896
+ *
897
+ * Calculates the users scores for the quiz
898
+ *
899
+ * @since 4.0.0
900
+ * @param array $options The database row of the quiz
901
+ * @param array $quiz_data The array of results for the quiz
902
+ * @uses QMNPluginHelper:display_review() Scores the question
903
+ * @return array The results of the user's score
904
+ */
905
+ public function check_answers( $options, $quiz_data ) {
906
+
 
 
 
 
 
 
907
  global $mlwQuizMasterNext;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
908
 
909
+ // Load the pages and questions
910
+ $pages = $mlwQuizMasterNext->pluginHelper->get_quiz_setting( 'pages', array() );
911
+ $questions = QSM_Questions::load_questions_by_pages( $options->quiz_id );
912
+
913
+ // Retrieve data from submission
914
+ $total_questions = isset( $_POST["total_questions"] ) ? intval( $_POST["total_questions"] ) : 0;
915
+ $question_list = isset( $_POST["qmn_question_list"] ) ? explode( 'Q', $_POST["qmn_question_list"] ) : array();
916
+
917
+ // Prepare variables
918
+ $points_earned = 0;
919
+ $total_correct = 0;
920
+ $total_score = 0;
921
+ $user_answer = "";
922
+ $correct_answer = "";
923
+ $correct_status = "incorrect";
924
+ $answer_points = 0;
925
+ $question_data = array();
926
 
927
+ // If deprecated pagination setting is not used, use new system...
928
+ if ( 0 == $options->question_from_total && 0 !== count( $pages ) ) {
929
+
930
+ // Cycle through each page in quiz.
931
+ foreach ( $pages as $page ) {
932
+
933
+ // Cycle through each question on a page
934
+ foreach ( $page as $page_question_id ) {
935
+
936
+ // Cycle through each question that appeared to the user
937
+ foreach ( $question_list as $question_id ) {
938
+
939
+ // When the questions are the same...
940
+ if ( $page_question_id == $question_id ) {
941
+
942
+ $question = $questions[ $page_question_id ];
943
+
944
+ // Reset question-specific variables
945
+ $user_answer = "";
946
+ $correct_answer = "";
947
+ $correct_status = "incorrect";
948
+ $answer_points = 0;
949
+
950
+ // Send question to our grading function
951
+ $results_array = $mlwQuizMasterNext->pluginHelper->display_review( $question['question_type_new'], $question['question_id'] );
952
+
953
+ // If question was graded correctly.
954
+ if ( ! isset( $results_array["null_review"] ) ) {
955
+ $points_earned += $results_array["points"];
956
+ $answer_points += $results_array["points"];
957
+
958
+ // If the user's answer was correct
959
+ if ( 'correct' == $results_array["correct"] ) {
960
+ $total_correct += 1;
961
+ $correct_status = "correct";
962
+ }
963
+ $user_answer = $results_array["user_text"];
964
+ $correct_answer = $results_array["correct_text"];
965
+
966
+ // If a comment was submitted
967
+ if ( isset( $_POST["mlwComment" . $question['question_id'] ] ) ) {
968
+ $comment = htmlspecialchars( stripslashes( $_POST["mlwComment" . $question['question_id'] ] ), ENT_QUOTES );
969
+ } else {
970
+ $comment = "";
971
+ }
972
+
973
+ // Get text for question
974
+ $question_text = $question['question_name'];
975
+ if ( isset( $results_array["question_text"] ) ) {
976
+ $question_text = $results_array["question_text"];
977
+ }
978
+
979
+ // Save question data into new array in our array
980
+ $question_data[] = apply_filters( 'qmn_answer_array', array(
981
+ $question_text,
982
+ htmlspecialchars( $user_answer, ENT_QUOTES ),
983
+ htmlspecialchars( $correct_answer, ENT_QUOTES ),
984
+ $comment,
985
+ "correct" => $correct_status,
986
+ "id" => $question['question_id'],
987
+ "points" => $answer_points,
988
+ "category" => $question['category']
989
+ ), $options, $quiz_data);
990
+ }
991
+ break;
992
  }
993
+ }
994
+ }
995
+ }
996
+ } else {
997
+ // Cycle through each page in quiz.
998
+ foreach ( $questions as $question ) {
999
+
1000
+ // Cycle through each question that appeared to the user
1001
+ foreach ( $question_list as $question_id ) {
1002
+
1003
+ // When the questions are the same...
1004
+ if ( $question['question_id'] == $question_id ) {
1005
+
1006
+ // Reset question-specific variables
1007
+ $user_answer = "";
1008
+ $correct_answer = "";
1009
+ $correct_status = "incorrect";
1010
+ $answer_points = 0;
1011
+
1012
+ // Send question to our grading function
1013
+ $results_array = $mlwQuizMasterNext->pluginHelper->display_review( $question['question_type_new'], $question['question_id'] );
1014
+
1015
+ // If question was graded correctly.
1016
+ if ( ! isset( $results_array["null_review"] ) ) {
1017
+ $points_earned += $results_array["points"];
1018
+ $answer_points += $results_array["points"];
1019
+
1020
+ // If the user's answer was correct
1021
+ if ( 'correct' == $results_array["correct"] ) {
1022
+ $total_correct += 1;
1023
+ $correct_status = "correct";
1024
+ }
1025
+ $user_answer = $results_array["user_text"];
1026
+ $correct_answer = $results_array["correct_text"];
1027
+
1028
+ // If a comment was submitted
1029
+ if ( isset( $_POST["mlwComment" . $question['question_id'] ] ) ) {
1030
+ $comment = htmlspecialchars( stripslashes( $_POST["mlwComment" . $question['question_id'] ] ), ENT_QUOTES );
1031
+ } else {
1032
+ $comment = "";
1033
+ }
1034
+
1035
+ // Get text for question
1036
+ $question_text = $question['question_name'];
1037
+ if ( isset( $results_array["question_text"] ) ) {
1038
+ $question_text = $results_array["question_text"];
1039
+ }
1040
+
1041
+ // Save question data into new array in our array
1042
+ $question_data[] = apply_filters( 'qmn_answer_array', array(
1043
+ $question_text,
1044
+ htmlspecialchars( $user_answer, ENT_QUOTES ),
1045
+ htmlspecialchars( $correct_answer, ENT_QUOTES ),
1046
+ $comment,
1047
+ "correct" => $correct_status,
1048
+ "id" => $question['question_id'],
1049
+ "points" => $answer_points,
1050
+ "category" => $question['category']
1051
+ ), $options, $quiz_data);
1052
  }
1053
+ break;
1054
  }
 
1055
  }
1056
  }
1057
  }
1058
 
1059
+ // Calculate Total Percent Score And Average Points Only If Total Questions Doesn't Equal Zero To Avoid Division By Zero Error
1060
+ if ( 0 !== $total_questions ) {
1061
+ $total_score = round( ( ( $total_correct / $total_questions ) * 100 ), 2 );
1062
+ } else {
1063
+ $total_score = 0;
 
 
 
 
 
1064
  }
1065
 
1066
+ // Return array to be merged with main user response array
1067
  return array(
1068
+ 'total_points' => $points_earned,
1069
+ 'total_score' => $total_score,
1070
+ 'total_correct' => $total_correct,
1071
+ 'total_questions' => $total_questions,
1072
+ 'question_answers_display' => '', // Kept for backwards compatibility
1073
+ 'question_answers_array' => $question_data,
1074
  );
1075
  }
1076
 
php/classes/class-qmn-tracking.php DELETED
@@ -1,242 +0,0 @@
1
- <?php
2
- // Exit if accessed directly
3
- if ( ! defined( 'ABSPATH' ) ) exit;
4
-
5
- /**
6
- * Class To Send Tracking Information Back To My Website
7
- *
8
- * @since 4.1.0
9
- */
10
- class QMNTracking {
11
-
12
- /**
13
- * Date To Send Home
14
- *
15
- * @var array
16
- * @since 4.1.0
17
- */
18
- private $data;
19
-
20
- /**
21
- * Main Construct Function
22
- *
23
- * Call functions within class
24
- *
25
- * @since 4.1.0
26
- * @uses QMNTracking::load_dependencies() Loads required filed
27
- * @uses QMNTracking::add_hooks() Adds actions to hooks and filters
28
- * @return void
29
- */
30
- function __construct() {
31
- $this->load_dependencies();
32
- $this->add_hooks();
33
- }
34
-
35
- /**
36
- * Load File Dependencies
37
- *
38
- * @since 4.1.0
39
- * @return void
40
- */
41
- private function load_dependencies() {
42
-
43
- }
44
-
45
- /**
46
- * Add Hooks
47
- *
48
- * Adds functions to relavent hooks and filters
49
- *
50
- * @since 4.1.0
51
- * @return void
52
- */
53
- private function add_hooks() {
54
- add_action( 'admin_notices', array( $this, 'admin_notice' ) );
55
- add_action( 'admin_init', array( $this, 'admin_notice_check' ) );
56
- add_action( 'plugins_loaded', array( $this, 'track_check' ) );
57
- }
58
-
59
- /**
60
- * Determines If Ready To Send Data Home
61
- *
62
- * Determines if the plugin has been authorized to send the data home in the settings page. Then checks if it has been at least a week since the last send.
63
- *
64
- * @since 4.1.0
65
- * @uses QMNTracking::load_data()
66
- * @uses QMNTracking::send_data()
67
- * @return void
68
- */
69
- public function track_check() {
70
- $settings = (array) get_option( 'qmn-settings' );
71
- $tracking_allowed = '0';
72
- if ( isset( $settings['tracking_allowed'] ) ) {
73
- $tracking_allowed = $settings['tracking_allowed'];
74
- }
75
- $last_time = get_option( 'qmn_tracker_last_time' );
76
- if ( ( $tracking_allowed == '1' || $tracking_allowed == '2' ) && ( ( $last_time && $last_time < strtotime( '-1 week' ) ) || !$last_time ) ) {
77
- $this->load_data( $tracking_allowed );
78
- $this->send_data();
79
- update_option( 'qmn_tracker_last_time', time() );
80
- }
81
- }
82
-
83
- /**
84
- * Sends The Data Home
85
- *
86
- * @since 4.1.0
87
- * @return void
88
- */
89
- private function send_data() {
90
- $response = wp_remote_post( 'https://data.quizandsurveymaster.com/?usage_track=confirmation', array(
91
- 'method' => 'POST',
92
- 'timeout' => 45,
93
- 'redirection' => 5,
94
- 'httpversion' => '1.0',
95
- 'blocking' => true,
96
- 'body' => $this->data,
97
- 'user-agent' => 'QSM Usage Tracker'
98
- ) );
99
- if ( is_wp_error( $response ) ) {
100
- global $mlwQuizMasterNext;
101
- $error_message = $response->get_error_message();
102
- $mlwQuizMasterNext->log_manager->add( "Error 0024", "Usage tracker failed due to following reason: $error_message", 0, 'error' );
103
- }
104
- }
105
-
106
- /**
107
- * Prepares The Data To Be Sent
108
- *
109
- * @since 4.1.0
110
- * @return void
111
- */
112
- private function load_data( $tracking ) {
113
- global $wpdb;
114
- global $mlwQuizMasterNext;
115
- $data = array();
116
- $data["plugin"] = "QSM";
117
-
118
- $data['url'] = home_url();
119
- $data["wp_version"] = get_bloginfo( 'version' );
120
- $data["php_version"] = PHP_VERSION;
121
- $data["mysql_version"] = $wpdb->db_version();
122
- $data["server_app"] = $_SERVER['SERVER_SOFTWARE'];
123
-
124
- // Retrieve current plugin information
125
- if( ! function_exists( 'get_plugins' ) ) {
126
- include ABSPATH . '/wp-admin/includes/plugin.php';
127
- }
128
- $plugins = array_keys( get_plugins() );
129
- $active_plugins = get_option( 'active_plugins', array() );
130
- foreach ( $plugins as $key => $plugin ) {
131
- if ( in_array( $plugin, $active_plugins ) ) {
132
- // Remove active plugins from list so we can show active and inactive separately
133
- unset( $plugins[ $key ] );
134
- }
135
- }
136
- $data['active_plugins'] = $active_plugins;
137
- $data['inactive_plugins'] = $plugins;
138
-
139
- $theme_data = wp_get_theme();
140
- $data['theme'] = $theme_data->Name;
141
- $data['theme_version'] = $theme_data->Version;
142
-
143
- $mlw_stat_total_quiz = $wpdb->get_var( "SELECT COUNT(*) FROM ".$wpdb->prefix."mlw_quizzes" );
144
- $mlw_stat_total_active_quiz = $wpdb->get_var( "SELECT COUNT(*) FROM ".$wpdb->prefix."mlw_quizzes WHERE deleted=0" );
145
- $mlw_stat_total_questions = $wpdb->get_var( "SELECT COUNT(*) FROM ".$wpdb->prefix."mlw_questions" );
146
- $mlw_stat_total_active_questions = $wpdb->get_var( "SELECT COUNT(*) FROM ".$wpdb->prefix."mlw_questions WHERE deleted=0" );
147
- $mlw_stat_total_results = $wpdb->get_var( "SELECT COUNT(*) FROM ".$wpdb->prefix."mlw_results" );
148
- $mlw_stat_total_active_results = $wpdb->get_var( "SELECT COUNT(*) FROM ".$wpdb->prefix."mlw_results WHERE deleted=0" );
149
-
150
- $data["total_quizzes"] = $mlw_stat_total_quiz;
151
- $data["total_active_quizzes"] = $mlw_stat_total_active_quiz;
152
- $data["total_questions"] = $mlw_stat_total_questions;
153
- $data["total_active_questions"] = $mlw_stat_total_active_questions;
154
- $data["total_results"] = $mlw_stat_total_results;
155
- $data["total_active_results"] = $mlw_stat_total_active_results;
156
-
157
- $data['original_version'] = get_option('qmn_original_version');
158
- $data['current_version'] = get_option('mlw_quiz_master_version');
159
-
160
- $data['quiz_options'] = $wpdb->get_results( "SELECT quiz_name, system, randomness_order, loggedin_user_contact, show_score, send_user_email, send_admin_email, contact_info_location, user_name, user_comp,
161
- user_email, user_phone, comment_section, question_from_total, total_user_tries, certificate_template, pagination, timer_limit, question_numbering, theme_selected, last_activity, require_log_in, limit_total_entries, disable_answer_onselect, ajax_show_correct, quiz_views, quiz_taken FROM ".$wpdb->prefix."mlw_quizzes WHERE deleted=0" );
162
-
163
- $data['error_logs'] = $mlwQuizMasterNext->log_manager->get_logs();
164
-
165
- $data['site_title'] = get_bloginfo( 'name' );
166
- $data['site_desc'] = get_bloginfo( 'description' );
167
- $data['site_charset'] = get_bloginfo( 'charset' );
168
- $data['lang'] = get_bloginfo( 'language' );
169
-
170
- // Only add email if they opted into the newer optin message that includes joining the mailing list
171
- if ( $tracking == "2" ) {
172
- $data['email'] = get_bloginfo( 'admin_email' );
173
- }
174
-
175
- $this->data = $data;
176
- }
177
-
178
- /**
179
- * Adds Admin Notice To Dashboard
180
- *
181
- * Adds an admin notice asking for authorization to send data home
182
- *
183
- * @since 4.1.0
184
- * @return void
185
- */
186
- public function admin_notice() {
187
- $show_notice = get_option( 'qmn-tracking-notice' );
188
- $settings = (array) get_option( 'qmn-settings' );
189
-
190
- // If the notice has already been shown, return.
191
- if ( $show_notice ) {
192
- return;
193
- }
194
-
195
- // If the tracking variable has already been set, return.
196
- if ( isset( $settings['tracking_allowed'] ) && $settings['tracking_allowed'] == '1' ) {
197
- return;
198
- }
199
-
200
- // If the user does not have the required permissions, return.
201
- if( ! current_user_can( 'manage_options' ) ) {
202
- return;
203
- }
204
-
205
- if( stristr( network_site_url( '/' ), 'dev' ) !== false || stristr( network_site_url( '/' ), 'localhost' ) !== false || stristr( network_site_url( '/' ), ':8888' ) !== false ) {
206
- update_option( 'qmn-tracking-notice', '1' );
207
- } else {
208
- $optin_url = esc_url( add_query_arg( 'qmn_track_check', 'opt_into_tracking' ) );
209
- $optout_url = esc_url( add_query_arg( 'qmn_track_check', 'opt_out_of_tracking' ) );
210
- echo '<div class="updated">';
211
- echo '<p>' . __( "Allow Quiz And Survey Master to track this plugin's usage and help us make this plugin better? Opt-in to tracking and our newsletter and immediately be emailed a coupon to the QSM store, valid towards the purchase of addons.", 'quiz-master-next' ) . '<p>';
212
- echo '<p>' . __( "No sensitive data is tracked. Only feature usage and data about quizzes, surveys, and questions are collected. No user responses or data is ever collected.", 'quiz-master-next' ) . '<p>';
213
- echo '&nbsp;<a href="' . esc_url( $optin_url ) . '" class="button-secondary">' . __( 'Allow', 'quiz-master-next' ) . '</a>';
214
- echo '&nbsp;<a href="' . esc_url( $optout_url ) . '" class="button-secondary">' . __( 'Do not allow', 'quiz-master-next' ) . '</a>';
215
- echo '</div>';
216
- }
217
- }
218
-
219
- /**
220
- * Checks If User Has Clicked On Notice
221
- *
222
- * @since 4.1.0
223
- * @return void
224
- */
225
- public function admin_notice_check() {
226
- if ( isset( $_GET["qmn_track_check"] ) ) {
227
- if ( $_GET["qmn_track_check"] == 'opt_into_tracking' ) {
228
- $settings = (array) get_option( 'qmn-settings' );
229
- $settings['tracking_allowed'] = '2';
230
- update_option( 'qmn-settings', $settings );
231
- } else {
232
- $settings = (array) get_option( 'qmn-settings' );
233
- $settings['tracking_allowed'] = '0';
234
- update_option( 'qmn-settings', $settings );
235
- }
236
- update_option( 'qmn-tracking-notice', '1' );
237
- }
238
- }
239
- }
240
- $qmnTracking = new QMNTracking();
241
-
242
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
php/classes/class-qsm-tracking.php ADDED
@@ -0,0 +1,232 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // Exit if accessed directly
3
+ if ( ! defined( 'ABSPATH' ) ) exit;
4
+
5
+ /**
6
+ * Class To Send Tracking Information Back To My Website
7
+ *
8
+ * @since 4.1.0
9
+ */
10
+ class QSM_Tracking {
11
+
12
+ /**
13
+ * Date To Send Home
14
+ *
15
+ * @var array
16
+ * @since 4.1.0
17
+ */
18
+ private $data;
19
+
20
+ /**
21
+ * Main Construct Function
22
+ *
23
+ * Call functions within class
24
+ *
25
+ * @since 4.1.0
26
+ * @uses QSM_Tracking::add_hooks() Adds actions to hooks and filters
27
+ * @return void
28
+ */
29
+ function __construct() {
30
+ $this->add_hooks();
31
+ }
32
+
33
+ /**
34
+ * Add Hooks
35
+ *
36
+ * Adds functions to relavent hooks and filters
37
+ *
38
+ * @since 4.1.0
39
+ * @return void
40
+ */
41
+ private function add_hooks() {
42
+ add_action( 'admin_notices', array( $this, 'admin_notice' ) );
43
+ add_action( 'admin_init', array( $this, 'admin_notice_check' ) );
44
+ add_action( 'plugins_loaded', array( $this, 'track_check' ) );
45
+ }
46
+
47
+ /**
48
+ * Determines If Ready To Send Data Home
49
+ *
50
+ * Determines if the plugin has been authorized to send the data home in the settings page. Then checks if it has been at least a week since the last send.
51
+ *
52
+ * @since 4.1.0
53
+ * @uses QSM_Tracking::load_data()
54
+ * @uses QSM_Tracking::send_data()
55
+ * @return void
56
+ */
57
+ public function track_check() {
58
+ $settings = (array) get_option( 'qmn-settings' );
59
+ $tracking_allowed = '0';
60
+ if ( isset( $settings['tracking_allowed'] ) ) {
61
+ $tracking_allowed = $settings['tracking_allowed'];
62
+ }
63
+ $last_time = get_option( 'qmn_tracker_last_time' );
64
+
65
+ // We only send data if opted in. Opt-in designated by a value of 1 or 2.
66
+ // We send data once a week.
67
+ if ( ( $tracking_allowed == '1' || $tracking_allowed == '2' ) && ( ( $last_time && $last_time < strtotime( '-1 week' ) ) || !$last_time ) ) {
68
+ $this->load_data( $tracking_allowed );
69
+ $this->send_data();
70
+ update_option( 'qmn_tracker_last_time', time() );
71
+ }
72
+ }
73
+
74
+ /**
75
+ * Sends The Data Home
76
+ *
77
+ * @since 4.1.0
78
+ * @return void
79
+ */
80
+ private function send_data() {
81
+ $response = wp_remote_post( 'https://data.quizandsurveymaster.com/?usage_track=confirmation', array(
82
+ 'method' => 'POST',
83
+ 'timeout' => 45,
84
+ 'redirection' => 5,
85
+ 'httpversion' => '1.0',
86
+ 'blocking' => true,
87
+ 'body' => $this->data,
88
+ 'user-agent' => 'QSM Usage Tracker'
89
+ ) );
90
+ if ( is_wp_error( $response ) ) {
91
+ global $mlwQuizMasterNext;
92
+ $error_message = $response->get_error_message();
93
+ $mlwQuizMasterNext->log_manager->add( "Error 0024", "Usage tracker failed due to following reason: $error_message", 0, 'error' );
94
+ }
95
+ }
96
+
97
+ /**
98
+ * Prepares The Data To Be Sent
99
+ *
100
+ * @since 4.1.0
101
+ * @return void
102
+ */
103
+ private function load_data( $tracking ) {
104
+ global $wpdb;
105
+ global $mlwQuizMasterNext;
106
+ $data = array();
107
+ $data["plugin"] = "QSM";
108
+
109
+ $data['url'] = home_url();
110
+ $data["wp_version"] = get_bloginfo( 'version' );
111
+ $data["php_version"] = PHP_VERSION;
112
+ $data["mysql_version"] = $wpdb->db_version();
113
+ $data["server_app"] = $_SERVER['SERVER_SOFTWARE'];
114
+
115
+ // Retrieve current plugin information
116
+ if( ! function_exists( 'get_plugins' ) ) {
117
+ include ABSPATH . '/wp-admin/includes/plugin.php';
118
+ }
119
+ $plugins = array_keys( get_plugins() );
120
+ $active_plugins = get_option( 'active_plugins', array() );
121
+ foreach ( $plugins as $key => $plugin ) {
122
+ if ( in_array( $plugin, $active_plugins ) ) {
123
+ // Remove active plugins from list so we can show active and inactive separately
124
+ unset( $plugins[ $key ] );
125
+ }
126
+ }
127
+ $data['active_plugins'] = $active_plugins;
128
+ $data['inactive_plugins'] = $plugins;
129
+
130
+ // Active theme information
131
+ $theme_data = wp_get_theme();
132
+ $data['theme'] = $theme_data->Name;
133
+ $data['theme_version'] = $theme_data->Version;
134
+
135
+ // Aggregate information on number of quizzes, questions, and results
136
+ $data["total_quizzes"] = $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->prefix}mlw_quizzes" );
137
+ $data["total_active_quizzes"] = $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->prefix}mlw_quizzes WHERE deleted = 0" );
138
+ $data["total_questions"] = $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->prefix}mlw_questions" );
139
+ $data["total_active_questions"] = $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->prefix}mlw_questions WHERE deleted=0" );
140
+ $data["total_results"] = $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->prefix}mlw_results" );
141
+ $data["total_active_results"] = $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->prefix}mlw_results WHERE deleted=0" );
142
+
143
+ $data['original_version'] = get_option('qmn_original_version');
144
+ $data['current_version'] = get_option('mlw_quiz_master_version');
145
+
146
+ // Configurations of quizzes and surveys
147
+ $data['quiz_options'] = $wpdb->get_results( "SELECT quiz_name, system, randomness_order, loggedin_user_contact, show_score, send_user_email, send_admin_email, contact_info_location, user_name, user_comp, user_email, user_phone, comment_section, question_from_total, total_user_tries, certificate_template, pagination, timer_limit, question_numbering, theme_selected, last_activity, require_log_in, limit_total_entries, disable_answer_onselect, ajax_show_correct, quiz_views, quiz_taken FROM {$wpdb->prefix}mlw_quizzes WHERE deleted = 0" );
148
+
149
+ // All error logs from QSM
150
+ $data['error_logs'] = $mlwQuizMasterNext->log_manager->get_logs();
151
+
152
+ // Some meta info about the site
153
+ $data['site_title'] = get_bloginfo( 'name' );
154
+ $data['site_desc'] = get_bloginfo( 'description' );
155
+ $data['site_charset'] = get_bloginfo( 'charset' );
156
+ $data['lang'] = get_bloginfo( 'language' );
157
+
158
+ $this->data = $data;
159
+ }
160
+
161
+ /**
162
+ * Adds Admin Notice To Dashboard
163
+ *
164
+ * Adds an admin notice asking for authorization to send data home
165
+ *
166
+ * @since 4.1.0
167
+ * @return void
168
+ */
169
+ public function admin_notice() {
170
+ $show_notice = get_option( 'qmn-tracking-notice' );
171
+ $settings = (array) get_option( 'qmn-settings' );
172
+
173
+ // If the notice has already been shown, return.
174
+ if ( $show_notice ) {
175
+ return;
176
+ }
177
+
178
+ // If the tracking variable has already been set, return.
179
+ if ( isset( $settings['tracking_allowed'] ) && $settings['tracking_allowed'] == '1' ) {
180
+ return;
181
+ }
182
+
183
+ // If the user does not have the required permissions, return.
184
+ if( ! current_user_can( 'manage_options' ) ) {
185
+ return;
186
+ }
187
+
188
+ // If the site is on a dev or staging site, we do not need the data.
189
+ if( stristr( network_site_url( '/' ), 'dev' ) !== false || stristr( network_site_url( '/' ), 'localhost' ) !== false || stristr( network_site_url( '/' ), ':8888' ) !== false ) {
190
+ update_option( 'qmn-tracking-notice', '1' );
191
+ } else {
192
+ $optin_url = esc_url( add_query_arg( 'qmn_track_check', 'opt_into_tracking' ) );
193
+ $optout_url = esc_url( add_query_arg( 'qmn_track_check', 'opt_out_of_tracking' ) );
194
+ echo '<div class="updated">';
195
+ echo '<p>' . __( "Allow Quiz And Survey Master to track this plugin's usage and help us make this plugin better?", 'quiz-master-next' ) . '<p>';
196
+ echo '<p>' . __( "No sensitive data is tracked. Only feature usage and data about quizzes, surveys, and questions are collected. No questions or user responses is ever collected.", 'quiz-master-next' ) . '<p>';
197
+ echo '<p><a href="http://bit.ly/2w6f34x" target="_blank">' . __( 'Click here to learn more about why we need this data and what we collect', 'quiz-master-next' ) . '</a></p>';
198
+ echo '&nbsp;<a href="' . esc_url( $optin_url ) . '" class="button-secondary">' . __( 'Allow', 'quiz-master-next' ) . '</a>';
199
+ echo '&nbsp;<a href="' . esc_url( $optout_url ) . '" class="button-secondary">' . __( 'Do not allow', 'quiz-master-next' ) . '</a>';
200
+ echo '</div>';
201
+ }
202
+ }
203
+
204
+ /**
205
+ * Checks If User Has Clicked On Notice
206
+ *
207
+ * @since 4.1.0
208
+ * @return void
209
+ */
210
+ public function admin_notice_check() {
211
+ // Checks if the notice has been clicked on.
212
+ if ( isset( $_GET["qmn_track_check"] ) ) {
213
+
214
+ // Checks if user opted into tracking.
215
+ if ( $_GET["qmn_track_check"] == 'opt_into_tracking' ) {
216
+ $settings = (array) get_option( 'qmn-settings' );
217
+ $settings['tracking_allowed'] = '2';
218
+ update_option( 'qmn-settings', $settings );
219
+ } else {
220
+ $settings = (array) get_option( 'qmn-settings' );
221
+ $settings['tracking_allowed'] = '0';
222
+ update_option( 'qmn-settings', $settings );
223
+ }
224
+
225
+ // Prevents notice from being shown again.
226
+ update_option( 'qmn-tracking-notice', '1' );
227
+ }
228
+ }
229
+ }
230
+
231
+ $qsm_tracking = new QSM_Tracking();
232
+ ?>
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.2.3
8
  License: GPLv2
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -67,6 +67,7 @@ While Quiz And Survey Master is fully functional and is packed full of features
67
 
68
  **Premium Add-ons**
69
 
 
70
  * [Google Analytics Tracking](http://bit.ly/2AAgABs)
71
  * [Landing Page](https://quizandsurveymaster.com/downloads/landing-page/?utm_source=readme&utm_medium=plugin&utm_content=landing-page&utm_campaign=qsm_plugin)
72
  * [Export Results](https://quizandsurveymaster.com/downloads/export-results/?utm_source=readme&utm_medium=plugin&utm_content=export-results&utm_campaign=qsm_plugin)
@@ -110,6 +111,11 @@ This is usually a theme conflict. You can [checkout out our common conflict solu
110
 
111
  == Changelog ==
112
 
 
 
 
 
 
113
  = 5.2.3 (April 3, 2018) =
114
  * Closed Bug: Cannot save question on certain servers - ([Issue #651](https://github.com/fpcorso/quiz_master_next/issues/651))
115
  * Closed Bug: Questions/Answers Template Not Loaded In Admin Results Page - ([Issue #636](https://github.com/fpcorso/quiz_master_next/issues/636))
4
  Requires at least: 4.8
5
  Tested up to: 4.9
6
  Requires PHP: 5.2
7
+ Stable tag: 5.2.4
8
  License: GPLv2
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
67
 
68
  **Premium Add-ons**
69
 
70
+ * [URL Parameters](http://bit.ly/2I1ZM6g)
71
  * [Google Analytics Tracking](http://bit.ly/2AAgABs)
72
  * [Landing Page](https://quizandsurveymaster.com/downloads/landing-page/?utm_source=readme&utm_medium=plugin&utm_content=landing-page&utm_campaign=qsm_plugin)
73
  * [Export Results](https://quizandsurveymaster.com/downloads/export-results/?utm_source=readme&utm_medium=plugin&utm_content=export-results&utm_campaign=qsm_plugin)
111
 
112
  == Changelog ==
113
 
114
+ = 5.2.4 (May 7, 2018) =
115
+ * Closed Bug: %QUESTIONS_ANSWERS% variable is displaying questions in order of creation - ([Issue #660](https://github.com/fpcorso/quiz_master_next/issues/660))
116
+ * Closed Bug: Extra spacing is being added to questions when multiple lines are in question - ([Issue #659](https://github.com/fpcorso/quiz_master_next/issues/659))
117
+ * Closed Bug: Tabs pages stop working when translated - ([Issue #582](https://github.com/fpcorso/quiz_master_next/issues/582))
118
+
119
  = 5.2.3 (April 3, 2018) =
120
  * Closed Bug: Cannot save question on certain servers - ([Issue #651](https://github.com/fpcorso/quiz_master_next/issues/651))
121
  * Closed Bug: Questions/Answers Template Not Loaded In Admin Results Page - ([Issue #636](https://github.com/fpcorso/quiz_master_next/issues/636))