File: /var/www/html/bwcdev/wp-content/plugins/quiz-master-next/php/classes/class-qmn-plugin-helper.php
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
include_once ABSPATH . 'wp-admin/includes/plugin.php';
/**
* This class is a helper class to be used for extending the plugin
*
* This class contains many functions for extending the plugin
*
* @since 4.0.0
*/
class QMNPluginHelper {
/**
* Addon Page tabs array
*
* @var array
* @since 4.0.0
*/
public $addon_tabs = array();
/**
* Stats Page tabs array
*
* @var array
* @since 4.0.0
*/
public $stats_tabs = array();
/**
* Admin Results Page tabs array
*
* @var array
* @since 5.0.0
*/
public $admin_results_tabs = array();
/**
* Results Details Page tabs array
*
* @var array
* @since 4.1.0
*/
public $results_tabs = array();
/**
* Settings Page tabs array
*
* @var array
* @since 4.0.0
*/
public $settings_tabs = array();
/**
* Question types array
*
* @var array
* @since 4.0.0
*/
public $question_types = array();
/**
* Template array
*
* @var array
* @since 4.5.0
*/
public $quiz_templates = array();
/**
* Main Construct Function
*
* Call functions within class
*
* @since 4.0.0
* @return void
*/
public function __construct() {
add_action( 'wp_ajax_qmn_question_type_change', array( $this, 'get_question_type_edit_content' ) );
add_action( 'admin_init', array( $this, 'qsm_add_default_translations' ), 9999 );
add_action( 'qsm_saved_question', array( $this, 'qsm_add_question_translations' ), 10, 2 );
add_action( 'qsm_saved_text_message', array( $this, 'qsm_add_text_message_translations' ), 10, 3 );
add_action( 'qsm_saved_quiz_settings', array( $this, 'qsm_add_quiz_settings_translations' ), 10, 3 );
add_action( 'qsm_register_language_support', array( $this, 'qsm_register_language_support' ), 10, 3 );
add_filter( 'qsm_language_support', array( $this, 'qsm_language_support' ), 10, 3 );
}
/**
* Calls all class functions to check if quiz is setup properly
*
* @param int $quiz_id The ID of the quiz or survey to load.
* @return array An array which contains boolean result of has_proper_quiz, message and/or qmn_quiz_options
*/
public function has_proper_quiz( $quiz_id ) {
if ( empty( $quiz_id ) ) {
return array(
'res' => false,
'message' => __( 'Empty Quiz ID.', 'quiz-master-next' ),
);
}
$quiz_id = intval( $quiz_id );
// Tries to load quiz name to ensure this is a valid ID.
global $mlwQuizMasterNext, $qmn_allowed_visit, $qmn_json_data;
$qmn_json_data = array();
$qmn_allowed_visit = true;
if ( false === $this->prepare_quiz( $quiz_id ) ) {
return array(
'res' => false,
'message' => __( 'It appears that this quiz is not set up correctly.', 'quiz-master-next' ),
);
}
$has_result_id = ( ! isset( $_GET['result_id'] ) || '' === $_GET['result_id'] );
if ( $has_result_id ) {
global $mlw_qmn_quiz;
$mlw_qmn_quiz = $quiz_id;
}
$qmn_quiz_options = $mlwQuizMasterNext->quiz_settings->get_quiz_options();
if ( $has_result_id ) {
/**
* Filter Quiz Options before Quiz Display
*/
$qmn_quiz_options = apply_filters( 'qsm_shortcode_quiz_options', $qmn_quiz_options );
}
// If quiz options isn't found, stop function.
if ( is_null( $qmn_quiz_options ) || ( ! empty( $qmn_quiz_options->deleted ) && 1 == $qmn_quiz_options->deleted ) ) {
return array(
'res' => false,
'message' => __( 'This quiz is no longer available.', 'quiz-master-next' ),
);
}
// If quiz options isn't found, stop function.
if ( is_null( $qmn_quiz_options ) || empty( $qmn_quiz_options->quiz_name ) ) {
return array(
'res' => false,
'message' => __( 'It appears that this quiz is not set up correctly.', 'quiz-master-next' ),
);
}
return array(
'res' => true,
'message' => __( 'Quiz is setup properly.', 'quiz-master-next' ),
'qmn_quiz_options' => $qmn_quiz_options,
);
}
/**
* Calls all class functions to initialize quiz
*
* @param int $quiz_id The ID of the quiz or survey to load.
* @return bool True or False if ID is valid.
*/
public function prepare_quiz( $quiz_id ) {
$quiz_id = intval( $quiz_id );
// Tries to load quiz name to ensure this is a valid ID.
global $wpdb;
$quiz_name = $wpdb->get_var( $wpdb->prepare( "SELECT quiz_name FROM {$wpdb->prefix}mlw_quizzes WHERE quiz_id=%d LIMIT 1", $quiz_id ) );
if ( is_null( $quiz_name ) ) {
return false;
}
global $mlwQuizMasterNext;
$mlwQuizMasterNext->quizCreator->set_id( $quiz_id );
$mlwQuizMasterNext->quiz_settings->prepare_quiz( $quiz_id );
return true;
}
/**
* Retrieves all quizzes.
*
* @param bool $include_deleted If set to true, returned array will include all deleted quizzes
* @param string $order_by The column the quizzes should be ordered by
* @param string $order whether the $order_by should be ordered as ascending or decending. Can be "ASC" or "DESC"
* @param arr $user_role role of current user
* @param int $user_id Get the quiz based on user id
* @return array All of the quizzes as a numerical array of objects
*/
public function get_quizzes( $include_deleted = false, $order_by = 'quiz_id', $order = 'DESC', $user_role = array(), $user_id = '', $limit = '', $offset = '', $where = '' ) {
global $wpdb;
// Set order direction
$order_direction = 'DESC';
if ( 'ASC' === $order ) {
$order_direction = 'ASC';
}
// Set field to sort by
switch ( $order_by ) {
case 'last_activity':
$order_field = 'last_activity';
break;
case 'quiz_views':
$order_field = 'quiz_views';
break;
case 'quiz_taken':
$order_field = 'quiz_taken';
break;
case 'title':
$order_field = 'quiz_name';
break;
default:
$order_field = 'quiz_id';
break;
}
// Should we include deleted?
$delete = 'WHERE deleted=0';
if ( '' !== $where ) {
$delete = $delete . ' AND ' . $where;
}
if ( $include_deleted ) {
$delete = '';
}
$user_str = '';
if ( in_array( 'author', (array) $user_role, true ) ) {
if ( $user_id && '' === $delete ) {
$user_str = "WHERE quiz_author_id = '$user_id'";
} elseif ( $user_id && '' !== $delete ) {
$user_str = " AND quiz_author_id = '$user_id'";
}
}
if ( '' !== $where && '' !== $user_str ) {
$user_str = $user_str . ' AND ' . $where;
}
$where_str = '';
if ( '' === $user_str && '' === $delete && '' !== $where ) {
$where_str = "WHERE $where";
}
if ( '' !== $limit ) {
$limit = ' limit ' . $offset . ', ' . $limit;
}
// Get quizzes and return them
$delete = apply_filters( 'quiz_query_delete_clause', $delete );
$quizzes = $wpdb->get_results( stripslashes( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}mlw_quizzes %1s %2s %3s ORDER BY %4s %5s %6s", $delete, $user_str, $where_str, $order_field, $order_direction, $limit ) ) );
return $quizzes;
}
/**
* Registers a quiz setting
*
* @since 5.0.0
* @param array $field_array An array of the components for the settings field
*/
public function register_quiz_setting( $field_array, $section = 'quiz_options' ) {
global $mlwQuizMasterNext;
$mlwQuizMasterNext->quiz_settings->register_setting( $field_array, $section );
}
/**
* Retrieves a setting value from a section based on name of section and setting
*
* @since 5.0.0
* @param string $section The name of the section the setting is registered in
* @param string $setting The name of the setting whose value we need to retrieve
* @param mixed $default What we need to return if no setting exists with given $setting
* @return $mixed Value set for $setting or $default if setting does not exist
*/
public function get_section_setting( $section, $setting, $default = false ) {
global $mlwQuizMasterNext;
return apply_filters( 'qsm_section_setting_text', $mlwQuizMasterNext->quiz_settings->get_section_setting( $section, $setting, $default ) );
}
/**
* Retrieves setting value based on name of setting
*
* @since 4.0.0
* @param string $setting The name of the setting whose value we need to retrieve
* @param mixed $default What we need to return if no setting exists with given $setting
* @return $mixed Value set for $setting or $default if setting does not exist
*/
public function get_quiz_setting( $setting, $default = false ) {
global $mlwQuizMasterNext;
return $mlwQuizMasterNext->quiz_settings->get_setting( $setting, $default );
}
/**
* Updates a settings value, adding it if it didn't already exist
*
* @since 4.0.0
* @param string $setting The name of the setting whose value we need to retrieve
* @param mixed $value The value that needs to be stored for the setting
* @return bool True if successful or false if fails
*/
public function update_quiz_setting( $setting, $value ) {
global $mlwQuizMasterNext;
return $mlwQuizMasterNext->quiz_settings->update_setting( $setting, $value );
}
/**
* Outputs the section of input fields
*
* @since 5.0.0
* @since 7.0 Added new parameter settings_fields for default setting
* @param string $section The section that the settings were registered with
*/
public function generate_settings_section( $section = 'quiz_options', $settings_fields = array() ) {
global $mlwQuizMasterNext;
if ( empty( $settings_fields ) ) {
$settings_fields = $mlwQuizMasterNext->quiz_settings->load_setting_fields( $section );
}
QSM_Fields::generate_section( $settings_fields, $section );
}
/**
* Registers Quiz Templates
*
* @since 4.5.0
* @param $name String of the name of the template
* @param $file_path String of the path to the css file
*/
public function register_quiz_template( $name, $file_path ) {
$slug = strtolower( str_replace( ' ', '-', $name ) );
$this->quiz_templates[ $slug ] = array(
'name' => $name,
'path' => $file_path,
);
}
/**
* Returns Template Array
*
* @since 4.5.0
* @param $name String of the name of the template. If left empty, will return all templates
* @return array The array of quiz templates
*/
public function get_quiz_templates( $slug = null ) {
if ( is_null( $slug ) ) {
return $this->quiz_templates;
} elseif ( isset( $this->quiz_templates[ $slug ] ) ) {
return $this->quiz_templates[ $slug ];
} else {
return false;
}
}
/**
* Register Question Types
*
* Adds a question type to the question type array using the parameters given
*
* @since 4.0.0
* @param string $name The name of the Question Type which will be shown when selecting type
* @param string $display_function The name of the function to call when displaying the question
* @param bool $graded Tells the plugin if this question is graded or not. This will affect scoring.
* @param string $review_function The name of the function to call when scoring the question
* @param string $slug The slug of the question type to be stored with question in database
* @param array $options The options for show and hide question validation settings and answer types
* @return void
*/
public function register_question_type( $name, $display_function, $graded, $review_function = null, $edit_args = null, $save_edit_function = null, $slug = null, $options = array() ) {
if ( is_null( $slug ) ) {
$slug = strtolower( str_replace( ' ', '-', $name ) );
} else {
$slug = strtolower( str_replace( ' ', '-', $slug ) );
}
if ( is_null( $edit_args ) || ! is_array( $edit_args ) ) {
$validated_edit_function = array(
'inputs' => array(
'question',
'answer',
'hint',
'correct_info',
'comments',
'category',
'required',
),
'information' => '',
'extra_inputs' => array(),
'function' => '',
);
} else {
$validated_edit_function = array(
'inputs' => $edit_args['inputs'],
'information' => $edit_args['information'],
'extra_inputs' => $edit_args['extra_inputs'],
'function' => $edit_args['function'],
);
}
if ( is_null( $save_edit_function ) ) {
$save_edit_function = '';
}
$new_type = array(
'name' => $name,
'display' => $display_function,
'review' => $review_function,
'graded' => $graded,
'edit' => $validated_edit_function,
'save' => $save_edit_function,
'slug' => $slug,
'options' => $options,
);
$new_type = apply_filters( 'register_question_type_new_type',$new_type );
$this->question_types[ $slug ] = $new_type;
}
/**
* Retrieves List Of Question Types
*
* retrieves a list of the slugs and names of the question types
*
* @since 4.0.0
* @return array An array which contains the slug and name of question types that have been registered
*/
public function get_question_type_options() {
$type_array = array();
foreach ( $this->question_types as $type ) {
$type_array[] = array(
'slug' => $type['slug'],
'name' => $type['name'],
'options' => $type['options'],
);
}
return $type_array;
}
/**
*
*/
public function set_question_type_meta( $type_id, $meta_key, $meta_value ) {
$this->question_types[ $type_id ][ $meta_key ] = $meta_value;
}
public function get_question_type_edit_fields() {
$type_array = array();
foreach ( $this->question_types as $type ) {
$type_array[ $type['slug'] ] = $type['edit'];
}
return $type_array;
}
/**
* Displays A Question
*
* Retrieves the question types display function and creates the HTML for the question
*
* @since 4.0.0
* @param string $slug The slug of the question type that the question is
* @param int $question_id The id of the question
* @param array $quiz_options An array of the columns of the quiz row from the database
* @return string The HTML for the question
*/
public function display_question( $slug, $question_id, $quiz_options ) {
global $wpdb;
global $qmn_total_questions, $qmn_all_questions_count;
$question = $wpdb->get_row( $wpdb->prepare( 'SELECT * FROM ' . $wpdb->prefix . 'mlw_questions WHERE question_id=%d', intval( $question_id ) ) );
$answers = array();
if ( is_serialized( $question->answer_array ) && is_array( maybe_unserialize( $question->answer_array ) ) ) {
$answers = maybe_unserialize( $question->answer_array );
} else {
$mlw_answer_array_correct = array( 0, 0, 0, 0, 0, 0 );
$mlw_answer_array_correct[ $question->correct_answer - 1 ] = 1;
$answers = array(
array( $question->answer_one, $question->answer_one_points, $mlw_answer_array_correct[0] ),
array( $question->answer_two, $question->answer_two_points, $mlw_answer_array_correct[1] ),
array( $question->answer_three, $question->answer_three_points, $mlw_answer_array_correct[2] ),
array( $question->answer_four, $question->answer_four_points, $mlw_answer_array_correct[3] ),
array( $question->answer_five, $question->answer_five_points, $mlw_answer_array_correct[4] ),
array( $question->answer_six, $question->answer_six_points, $mlw_answer_array_correct[5] ),
);
}
$answers_original = $answers;
if ( 2 === intval( $quiz_options->randomness_order ) || 3 === intval( $quiz_options->randomness_order ) ) {
$answers = self::qsm_shuffle_assoc( $answers );
global $quiz_answer_random_ids;
$answer_ids = array_keys($answers);
$quiz_answer_random_ids[ $question_id ] = $answer_ids;
}
// convert answer array into key value pair
$answers_kvpair = array();
foreach ( $answers as $answer_item ) {
$key = array_search( $answer_item, $answers_original, true );
$answers_kvpair[ $key ] = $answer_item;
}
unset( $answer_item );
$answers = $answers_kvpair;
/**
* Filter Answers of specific question before display
*/
$answers = apply_filters( 'qsm_single_question_answers', $answers, $question, $quiz_options );
foreach ( $this->question_types as $type ) {
if ( strtolower( str_replace( ' ', '-', $slug ) ) === $type['slug'] && ! empty( $type['display'] ) && function_exists( $type['display'] ) ) {
$qmn_all_questions_count += 1;
if ( $type['graded'] ) {
$qmn_total_questions += 1;
if ( 1 === intval( $quiz_options->question_numbering ) ) { ?>
<span class='mlw_qmn_question_number'><?php echo esc_html( $qmn_total_questions ); ?>. </span>
<?php
}
}
if ( $quiz_options->show_category_on_front ) {
$categories = QSM_Questions::get_question_categories( $question_id );
if ( ! empty( $categories['category_name'] ) ) {
$cat_name = implode( ',', $categories['category_name'] );
?>
<div class="quiz-cat"><?php echo esc_html( $cat_name ); ?></div>
<?php
}
}
call_user_func( $type['display'], intval( $question_id ), $question->question_name, $answers );
do_action( 'qsm_after_question', $question );
}
}
}
public function get_questions_count( $quiz_id = 0 ) {
global $wpdb;
$quiz_id = intval( $quiz_id );
$count = 0;
if ( empty( $quiz_id ) || 0 == $quiz_id ) {
return $count;
}
$quiz_settings = $wpdb->get_var( $wpdb->prepare( "SELECT `quiz_settings` FROM `{$wpdb->prefix}mlw_quizzes` WHERE `quiz_id`=%d", $quiz_id ) );
if ( ! empty( $quiz_settings ) ) {
$settings = maybe_unserialize( $quiz_settings );
$pages = isset( $settings['pages'] ) ? maybe_unserialize( $settings['pages'] ) : array();
if ( ! empty( $pages ) ) {
foreach ( $pages as $page ) {
$count += count( $page );
}
}
}
return $count;
}
public function get_questions_ids( $quiz_id = 0 ) {
global $wpdb;
$quiz_id = intval( $quiz_id );
$ids = array();
if ( empty( $quiz_id ) || 0 == $quiz_id ) {
return $ids;
}
$quiz_settings = $wpdb->get_var( $wpdb->prepare( "SELECT `quiz_settings` FROM `{$wpdb->prefix}mlw_quizzes` WHERE `quiz_id`=%d", $quiz_id ) );
if ( ! empty( $quiz_settings ) ) {
$settings = maybe_unserialize( $quiz_settings );
$pages = isset( $settings['pages'] ) ? maybe_unserialize( $settings['pages'] ) : array();
if ( ! empty( $pages ) ) {
foreach ( $pages as $page ) {
$ids = array_merge($ids, $page );
}
}
}
return $ids;
}
/**
* Shuffle assoc array
*
* @since 7.3.11
* @param array $list An array
* @return array
*/
public static function qsm_shuffle_assoc( $list ) {
if ( ! is_array( $list ) ) {
return $list;
}
$keys = array_keys( $list );
shuffle( $keys );
$random = array();
foreach ( $keys as $key ) {
$random[ $key ] = $list[ $key ];
}
return $random;
}
/**
* Find the key of the first occurrence of a substring in an array
*/
public static function qsm_stripos_array( $str, array $arr ) {
if ( is_array( $arr ) ) {
foreach ( $arr as $a ) {
if ( stripos( $str, $a ) !== false ) {
return $a;
}
}
}
return false;
}
/**
* Default strings
* Translation not added in empty string due to warning ( WordPress.WP.I18n.NoEmptyStrings )
*/
public static function get_default_texts() {
$defaults = array(
'message_before' => __('Welcome to your %QUIZ_NAME%', 'quiz-master-next'),
'message_comment' => __('Please fill in the comment box below.', 'quiz-master-next'),
'message_end_template' => '',
'question_answer_template' => __('%QUESTION%<br />%USER_ANSWERS_DEFAULT%<br/>%CORRECT_ANSWER_INFO%', 'quiz-master-next'),
'question_answer_email_template' => __('%QUESTION%<br />Answer Provided: %USER_ANSWER%<br/>Correct Answer: %CORRECT_ANSWER%<br/>Comments Entered: %USER_COMMENTS%', 'quiz-master-next'),
'total_user_tries_text' => __('You have utilized all of your attempts to pass this quiz.', 'quiz-master-next'),
'require_log_in_text' => __('This quiz is for logged in users only.', 'quiz-master-next'),
'limit_total_entries_text' => __('Unfortunately, this quiz has a limited amount of entries it can recieve and has already reached that limit.', 'quiz-master-next'),
'scheduled_timeframe_text' => '',
'twitter_sharing_text' => __('I just scored %CORRECT_SCORE%% on %QUIZ_NAME%!', 'quiz-master-next'),
'facebook_sharing_text' => __('I just scored %CORRECT_SCORE%% on %QUIZ_NAME%!', 'quiz-master-next'),
'submit_button_text' => __('Submit', 'quiz-master-next'),
'retake_quiz_button_text' => __('Retake Quiz', 'quiz-master-next'),
'previous_button_text' => __('Previous', 'quiz-master-next'),
'next_button_text' => __('Next', 'quiz-master-next'),
'deselect_answer_text' => __('Deselect Answer', 'quiz-master-next'),
'empty_error_text' => __('Please complete all required fields!', 'quiz-master-next'),
'email_error_text' => __('Not a valid e-mail address!', 'quiz-master-next'),
'number_error_text' => __('This field must be a number!', 'quiz-master-next'),
'incorrect_error_text' => __('The entered text is not correct!', 'quiz-master-next'),
'url_error_text' => __('The entered URL is not valid!', 'quiz-master-next'),
'minlength_error_text' => __('Required atleast %minlength% characters.', 'quiz-master-next'),
'maxlength_error_text' => __('Minimum %maxlength% characters allowed.', 'quiz-master-next'),
'comment_field_text' => __('Comments', 'quiz-master-next'),
'hint_text' => __('Hint', 'quiz-master-next'),
'quick_result_correct_answer_text' => __('Correct! You have selected correct answer.', 'quiz-master-next'),
'quick_result_wrong_answer_text' => __('Wrong! You have selected wrong answer.', 'quiz-master-next'),
'quiz_processing_message' => '',
'quiz_limit_choice' => __('Limit of choice is reached.', 'quiz-master-next'),
'name_field_text' => __('Name', 'quiz-master-next'),
'business_field_text' => __('Business', 'quiz-master-next'),
'email_field_text' => __('Email', 'quiz-master-next'),
'phone_field_text' => __('Phone Number', 'quiz-master-next'),
'start_quiz_text' => __('Start Quiz', 'quiz-master-next'),
'start_survey_text' => __('Start Survey', 'quiz-master-next'),
);
return apply_filters( 'qsm_default_texts', $defaults );
}
/**
* Register string in WPML for translation
*/
public static function qsm_register_language_support( $translation_text = '', $translation_slug = '', $domain = 'QSM Meta' ) {
if ( ! empty( $translation_text ) && is_plugin_active( 'wpml-string-translation/plugin.php' ) ) {
$translation_slug = sanitize_title( $translation_slug );
/**
* Register the string for translation
*/
do_action( 'wpml_register_single_string', $domain, $translation_slug, $translation_text );
}
}
/**
* Translate string before display
*/
public static function qsm_language_support( $translation_text = '', $translation_slug = '', $domain = 'QSM Meta' ) {
/**
* Check if WPML String Translation plugin is activated.
*/
if ( ! empty( $translation_text ) && is_plugin_active( 'wpml-string-translation/plugin.php' ) ) {
/**
* Decode HTML Special characters.
*/
$translation_text = wp_kses_post( htmlspecialchars_decode( $translation_text, ENT_QUOTES ) );
$translation_slug = sanitize_title( $translation_slug );
$new_text = apply_filters( 'wpml_translate_single_string', $translation_text, $domain, $translation_slug );
if ( 'QSM Answers' === $domain && $new_text == $translation_text ) {
if ( 0 === strpos($translation_slug, 'caption-') ) {
$translation_slug = sanitize_title( 'caption-' . $translation_text );
}else {
$translation_slug = sanitize_title( 'answer-' . $translation_text );
}
$new_text = apply_filters( 'wpml_translate_single_string', $translation_text, $domain, $translation_slug );
}
$new_text = wp_kses_post( htmlspecialchars_decode( $new_text, ENT_QUOTES ) );
/**
* Return translation for non-default strings.
*/
if ( "QSM Meta" != $domain ) {
return $new_text;
}
/**
* Check if translation exist.
*/
if ( 0 !== strcasecmp( $translation_text, $new_text ) ) {
return $new_text;
}
/**
* Check if translation exist for default string.
*/
$default_texts = self::get_default_texts();
$default_key = self::qsm_stripos_array( $translation_slug, array_keys( $default_texts ) );
if ( false !== $default_key && 0 === strcasecmp( $translation_text, $default_texts[ $default_key ] ) ) {
return apply_filters( 'wpml_translate_single_string', $translation_text, 'QSM Defaults', 'quiz_' . $default_key );
}
} elseif ( ! empty( $translation_text ) ) {
$translation_text = wp_kses_post( $translation_text );
}
return $translation_text;
}
public function qsm_add_default_translations() {
$default_texts = self::get_default_texts();
if ( empty( $default_texts ) ) {
return;
}
if ( is_plugin_active( 'wpml-string-translation/plugin.php' ) ) {
foreach ( $default_texts as $key => $text ) {
if ( ! empty( $text ) ) {
$translation_slug = sanitize_title( 'quiz_' . $key );
/**
* Register the string for translation
*/
do_action( 'wpml_register_single_string', 'QSM Defaults', $translation_slug, $text );
}
}
}
}
public function qsm_add_question_translations( $question_id, $question_data ) {
$settings = isset( $question_data['question_settings'] ) ? maybe_unserialize( $question_data['question_settings'] ) : array();
$hints = isset( $question_data['hints'] ) ? $question_data['hints'] : '';
$answer_info = isset( $question_data['question_answer_info'] ) ? html_entity_decode( $question_data['question_answer_info'] ) : '';
$this->qsm_register_language_support( htmlspecialchars_decode( $settings['question_title'], ENT_QUOTES ), "Question-{$question_id}", "QSM Questions" );
$this->qsm_register_language_support( htmlspecialchars_decode( $question_data['question_name'], ENT_QUOTES ), "question-description-{$question_id}", "QSM Questions" );
$this->qsm_register_language_support( $hints, "hint-{$question_id}" );
$this->qsm_register_language_support( $answer_info, "correctanswerinfo-{$question_id}" );
$answers = isset( $question_data['answer_array'] ) ? maybe_unserialize( $question_data['answer_array'] ) : array();
if ( ! empty( $answers ) ) {
$answerEditor = isset( $settings['answerEditor'] ) ? $settings['answerEditor'] : 'text';
foreach ( $answers as $key => $ans ) {
if ( 'image' === $answerEditor ) {
$caption_text = trim( htmlspecialchars_decode( $ans[3], ENT_QUOTES ) );
$this->qsm_register_language_support( $caption_text, 'caption-' . $question_id . '-' . $key, 'QSM Answers' );
} else {
$answer_text = trim( htmlspecialchars_decode( $ans[0], ENT_QUOTES ) );
$this->qsm_register_language_support( $answer_text, 'answer-' . $question_id . '-' . $key, 'QSM Answers' );
}
}
}
}
public function qsm_add_text_message_translations( $quiz_id, $text_id, $message ) {
$message = htmlspecialchars_decode( $message, ENT_QUOTES );
$this->qsm_register_language_support( $message, "quiz_{$text_id}-{$quiz_id}" );
}
public function qsm_add_quiz_settings_translations( $quiz_id, $section, $settings_array ) {
if ( 'quiz_text' == $section && ! empty( $settings_array ) ) {
foreach ( $settings_array as $key => $val ) {
if ( ! empty( $val ) ) {
$this->qsm_register_language_support( htmlspecialchars_decode( $val, ENT_QUOTES ), "quiz_{$key}-{$quiz_id}" );
}
}
}
}
/**
* Calculates Score For Question
*
* Calculates the score for the question based on the question type
*
* @since 4.0.0
* @param string $slug The slug of the question type that the question is
* @param int $question_id The id of the question
* @return array An array of the user's score from the question
*/
public function display_review( $slug, $question_id ) {
$results_array = array();
global $wpdb;
$question = $wpdb->get_row( $wpdb->prepare( 'SELECT * FROM ' . $wpdb->prefix . 'mlw_questions WHERE question_id=%d', intval( $question_id ) ) );
$answers = maybe_unserialize( $question->answer_array );
if ( empty( $answers ) || ! is_array( $answers ) ) {
$mlw_answer_array_correct = array( 0, 0, 0, 0, 0, 0 );
$mlw_answer_array_correct[ $question->correct_answer - 1 ] = 1;
$answers = array(
array( $question->answer_one, $question->answer_one_points, $mlw_answer_array_correct[0] ),
array( $question->answer_two, $question->answer_two_points, $mlw_answer_array_correct[1] ),
array( $question->answer_three, $question->answer_three_points, $mlw_answer_array_correct[2] ),
array( $question->answer_four, $question->answer_four_points, $mlw_answer_array_correct[3] ),
array( $question->answer_five, $question->answer_five_points, $mlw_answer_array_correct[4] ),
array( $question->answer_six, $question->answer_six_points, $mlw_answer_array_correct[5] ),
);
}
foreach ( $this->question_types as $type ) {
if ( strtolower( str_replace( ' ', '-', $slug ) ) === $type['slug'] ) {
if ( ! is_null( $type['review'] ) ) {
$results_array = call_user_func( $type['review'], intval( $question_id ), $question->question_name, $answers );
} else {
$results_array = array( 'null_review' => true );
}
}
}
return $results_array;
}
/**
* Retrieves A Question Setting
*
* Retrieves a setting stored in the question settings array
*
* @since 4.0.0
* @param int $question_id The id of the question
* @param string $setting The name of the setting
* @return string The value stored for the setting
*/
public function get_question_setting( $question_id, $setting ) {
global $wpdb;
$settings = $wpdb->get_var( $wpdb->prepare( 'SELECT question_settings FROM ' . $wpdb->prefix . 'mlw_questions WHERE question_id=%d', $question_id ) );
$qmn_settings_array = maybe_unserialize( $settings );
if ( is_array( $qmn_settings_array ) && isset( $qmn_settings_array[ $setting ] ) ) {
return $qmn_settings_array[ $setting ];
} else {
return '';
}
}
/**
* Registers Addon Settings Tab
*
* Registers a new tab on the addon settings page
*
* @since 4.0.0
* @param string $title The name of the tab
* @param string $function The function that displays the tab's content
* @return void
*/
public function register_addon_settings_tab( $title, $function ) {
$slug = strtolower( str_replace( ' ', '-', $title ) );
$new_tab = array(
'title' => $title,
'function' => $function,
'slug' => $slug,
);
$this->addon_tabs[] = $new_tab;
}
/**
* Retrieves Addon Settings Tab Array
*
* Retrieves the array of titles and functions of the registered tabs
*
* @since 4.0.0
* @return array The array of registered tabs
*/
public function get_addon_tabs() {
return $this->addon_tabs;
}
/**
* Registers Stats Tab
*
* Registers a new tab on the stats page
*
* @since 4.3.0
* @param string $title The name of the tab
* @param string $function The function that displays the tab's content
* @return void
*/
public function register_stats_settings_tab( $title, $function ) {
$slug = strtolower( str_replace( ' ', '-', $title ) );
$new_tab = array(
'title' => $title,
'function' => $function,
'slug' => $slug,
);
$this->stats_tabs[] = $new_tab;
}
/**
* Retrieves Stats Tab Array
*
* Retrieves the array of titles and functions of the registered tabs
*
* @since 4.3.0
* @return array The array of registered tabs
*/
public function get_stats_tabs() {
return $this->stats_tabs;
}
/**
* Registers tabs for the Admin Results page
*
* Registers a new tab on the admin results page
*
* @since 5.0.0
* @param string $title The name of the tab
* @param string $function The function that displays the tab's content
* @return void
*/
public function register_admin_results_tab( $title, $function, $priority = 10 ) {
$slug = strtolower( str_replace( ' ', '-', $title ) );
$new_tab = array(
'title' => $title,
'function' => $function,
'slug' => $slug,
'priority' => $priority,
);
$this->admin_results_tabs[] = $new_tab;
}
/**
* Retrieves Admin Results Tab Array
*
* Retrieves the array of titles and functions for the tabs registered for the admin results page
*
* @since 5.0.0
* @return array The array of registered tabs
*/
public function get_admin_results_tabs() {
/**
* Sort tabs by priority
*/
array_multisort( array_column($this->admin_results_tabs, 'priority'), SORT_ASC, $this->admin_results_tabs);
return apply_filters( 'qmn_admin_results_tabs', $this->admin_results_tabs );
}
/**
* Registers Results Tab
*
* Registers a new tab on the results page
*
* @since 4.1.0
* @param string $title The name of the tab
* @param string $function The function that displays the tab's content
* @return void
*/
public function register_results_settings_tab( $title, $function ) {
$slug = strtolower( str_replace( ' ', '-', $title ) );
$new_tab = array(
'title' => $title,
'function' => $function,
'slug' => $slug,
);
$this->results_tabs[] = $new_tab;
}
/**
* Retrieves Results Tab Array
*
* Retrieves the array of titles and functions of the registered tabs
*
* @since 4.1.0
* @return array The array of registered tabs
*/
public function get_results_tabs() {
return $this->results_tabs;
}
/**
* Registers Quiz Settings Tab
*
* Registers a new tab on the quiz settings page
*
* @since 4.0.0
* @param string $title The name of the tab
* @param string $function The function that displays the tab's content
* @return void
*/
public function register_quiz_settings_tabs( $title, $function, $slug = '' ) {
if ( '' === $slug ) {
$slug = strtolower( str_replace( ' ', '-', $title ) );
}
$new_tab = array(
'title' => $title,
'function' => $function,
'slug' => $slug,
);
$this->settings_tabs[] = $new_tab;
}
/**
* Echos Registered Tabs Title Link
*
* Echos the title link of the registered tabs
*
* @since 4.0.0
* @return array The array of registered tabs
*/
public function get_settings_tabs() {
return apply_filters( 'qmn_quiz_setting_tabs', $this->settings_tabs );
}
/**
* global animatiocv array return
*
* @since 4.7.1
*/
public function quiz_animation_effect() {
return array(
array(
'label' => __( 'bounce', 'quiz-master-next' ),
'value' => 'bounce',
),
array(
'label' => __( 'flash', 'quiz-master-next' ),
'value' => 'flash',
),
array(
'label' => __( 'pulse', 'quiz-master-next' ),
'value' => 'pulse',
),
array(
'label' => __( 'rubberBand', 'quiz-master-next' ),
'value' => 'rubberBand',
),
array(
'label' => __( 'shake', 'quiz-master-next' ),
'value' => 'shake',
),
array(
'label' => __( 'swing', 'quiz-master-next' ),
'value' => 'swing',
),
array(
'label' => __( 'tada', 'quiz-master-next' ),
'value' => 'tada',
),
array(
'label' => __( 'wobble', 'quiz-master-next' ),
'value' => 'wobble',
),
array(
'label' => __( 'jello', 'quiz-master-next' ),
'value' => 'jello',
),
array(
'label' => __( 'heartBeat', 'quiz-master-next' ),
'value' => 'heartBeat',
),
array(
'label' => __( 'Select Quiz Animation', 'quiz-master-next' ),
'value' => '',
),
);
}
/**
* converts dates into preferred date format
*
* @since 7.3.3
* @param array $qsm_qna_array The array of results for the quiz
* @uses QMNQuizManager:submit_results() submits and displays results
* @uses qsm_generate_results_details_tab() generates admin results page
* @return array $qsm_qna_array date formatted array of results for the quiz
*/
public function convert_to_preferred_date_format( $qsm_qna_array ) {
global $mlwQuizMasterNext;
$quiz_options = $mlwQuizMasterNext->quiz_settings->get_quiz_options();
$qsm_quiz_settings = maybe_unserialize( $quiz_options->quiz_settings );
$qsm_quiz_options = maybe_unserialize( $qsm_quiz_settings['quiz_options'] );
$qsm_global_settings = get_option( 'qsm-quiz-settings' );
// check if preferred date format is set at quiz level or plugin level. Default to WP date format otherwise
if ( isset( $qsm_quiz_options['preferred_date_format'] ) ) {
$preferred_date_format = $qsm_quiz_options['preferred_date_format'];
} elseif ( isset( $qsm_global_settings['preferred_date_format'] ) ) {
$preferred_date_format = isset( $qsm_global_settings['preferred_date_format'] );
} else {
$preferred_date_format = get_option( 'date_format' );
}
// filter date format
$GLOBALS['qsm_date_format'] = apply_filters( 'qms_preferred_date_format', $preferred_date_format );
$qsm_qna_array = $this->convert_contacts_to_preferred_date_format( $qsm_qna_array );
$qsm_qna_array = $this->convert_answers_to_preferred_date_format( $qsm_qna_array );
$this->convert_questions_to_preferred_date_format();
return $qsm_qna_array;
}
/**
* converts contacts into preferred date format
*
* @since 7.3.3
* @param array $qsm_qna_array The array of results for the quiz
* @uses convert_to_preferred_date_format()
* @return array $qsm_qna_array date formatted array of results for the quiz
*/
public function convert_contacts_to_preferred_date_format( $qsm_qna_array ) {
$qsm_contact_array = $qsm_qna_array['contact'];
foreach ( $qsm_contact_array as $qsm_contact_id => $qsm_contact ) {
if ( 'date' === $qsm_contact['type'] && '' !== $qsm_contact['value'] && null !== $GLOBALS['qsm_date_format'] ) {
$qsm_qna_array['contact'][ $qsm_contact_id ]['value'] = date_i18n( $GLOBALS['qsm_date_format'], strtotime( ( $qsm_contact['value'] ) ) );
}
}
return $qsm_qna_array;
}
/**
* converts answers into preferred date format
*
* @since 7.3.3
* @param array $qsm_qna_array The array of results for the quiz
* @uses convert_to_preferred_date_format()
* @return array $qsm_qna_array date formatted array of results for the quiz
*/
public function convert_answers_to_preferred_date_format( $qsm_qna_array ) {
$qsm_qna_list = $qsm_qna_array['question_answers_array'];
foreach ( $qsm_qna_list as $qna_id => $qna ) {
if ( '12' === $qna['question_type'] && null !== $GLOBALS['qsm_date_format'] ) {
$qsm_qna_array['question_answers_array'][ $qna_id ]['1'] = date_i18n( $GLOBALS['qsm_date_format'], strtotime( ( $qna['1'] ) ) );
$qsm_qna_array['question_answers_array'][ $qna_id ]['2'] = date_i18n( $GLOBALS['qsm_date_format'], strtotime( ( $qna['2'] ) ) );
}
}
return $qsm_qna_array;
}
/**
* converts questions into preferred date format
*
* @since 7.3.3
* @param array $qsm_qna_array The array of results for the quiz
* @uses convert_to_preferred_date_format()
* @return array $qsm_qna_array date formatted array of results for the quiz
*/
public function convert_questions_to_preferred_date_format() {
if ( ! function_exists( 'qsm_convert_question_array_date_format' ) ) {
function qsm_convert_question_array_date_format( $questions ) {
foreach ( $questions as $question_id => $question_to_convert ) {
if ( '12' === $question_to_convert['question_type_new'] ) {
foreach ( $question_to_convert['answers'] as $answer_id => $answer_value ) {
$questions[ $question_id ]['answers'][ $answer_id ][0] = date_i18n( $GLOBALS['qsm_date_format'], strtotime( $answer_value[0] ) );
}
}
}
return $questions;
}
}
add_filter( 'qsm_load_questions_by_pages', 'qsm_convert_question_array_date_format' );
}
/**
*
*
* @since 7.3.5
* @param array
* @uses
* @return array
*/
public function qsm_results_css_inliner( $html ) {
global $mlwQuizMasterNext;
$grading = $mlwQuizMasterNext->pluginHelper->get_section_setting( 'quiz_options', 'system' );
$wr_sign = 1 != $grading ? "✕ " : "";
$html = str_replace( '<br/>', '<br>', $html );
$html = str_replace( '<br />', '<br>', $html );
$html = str_replace( "class='qmn_question_answer", "style='margin-bottom:30px' class='", $html );
$html = preg_replace( '/<span class="qsm-text-simple-option(.*?)">(.*?)<\/span>/', "<span style='color:#808080;display:block;margin-bottom:5px;'>• $2</span>", $html );
$html = preg_replace( '/<span class="qsm-text-wrong-option(.*?)">(.*?)<\/span>/', "<span style='color:red;display:block;margin-bottom:5px;'>✕ $2</span>", $html );
$html = preg_replace( '/<span class="qmn_user_incorrect_answer(.*?)">(.*?)<\/span>/', "<span style='color:red;display:block;margin-bottom:5px;'>".$wr_sign."$2</span>", $html );
$html = preg_replace( '/<span class="qsm-text-correct-option(.*?)">(.*?)<\/span>/', "<span style='color:green;display:block;margin-bottom:5px;'>✓ $2</span>", $html );
$html = preg_replace( '/<span class="qmn_user_correct_answer(.*?)">(.*?)<\/span>/', "<span style='color:green;display:block;margin-bottom:5px;'>✓ $2</span>", $html );
return $html;
}
/** */
public function categorize_question_types() {
$question_type_categorized = array();
$question_type_uncategorized = array();
foreach ( $this->question_types as $question_type ) {
$is_categorized = isset( $question_type ['category'] ) && '' !== $question_type ['category'];
if ( $is_categorized ) {
$question_type_categorized[ $question_type ['category'] ] [ $question_type['slug'] ] = array(
'slug' => $question_type['slug'],
'name' => $question_type['name'],
'disabled' => (isset( $question_type['display'] ) && '-1' == $question_type['display']) ? true : false,
);
} else {
$question_type_uncategorized['uncategorized'][ $question_type['slug'] ] = array(
'slug' => $question_type['slug'],
'name' => $question_type['name'],
'disabled' => (isset( $question_type['display'] ) && '-1' == $question_type['display']) ? true : false,
);
}
}
$question_type_categorized = array_merge( $question_type_categorized, $question_type_uncategorized );
return $question_type_categorized;
}
public function description_array() {
return array(
array(
'question_type_id' => 11,
'description' => __( 'For this question type, users will see a file upload field on front end.', 'quiz-master-next' ),
),
array(
'question_type_id' => '14',
'description' => __( 'Use %BLANK% variable in the description field to display input boxes.', 'quiz-master-next' ),
),
array(
'question_type_id' => '12',
'description' => __( 'For this question type, users will see a date input field on front end.', 'quiz-master-next' ),
),
array(
'question_type_id' => '3',
'description' => __( 'For this question type, users will see a standard input box on front end.', 'quiz-master-next' ),
),
array(
'question_type_id' => '5',
'description' => __( 'For this question type, users will see a standard textarea input box on front end.', 'quiz-master-next' ),
),
array(
'question_type_id' => '6',
'description' => __( 'Displays a simple section on front end. Description is mandatory. ', 'quiz-master-next' ),
),
array(
'question_type_id' => '7',
'description' => __( 'For this question type, users will see an input box which accepts only number values on front end.', 'quiz-master-next' ),
),
array(
'question_type_id' => '8',
'description' => __( "For this question type, users will see a checkbox on front end. The text in description field will act like it's label.", 'quiz-master-next' ),
),
array(
'question_type_id' => '9',
'description' => __( 'For this question type, users will see a Captcha field on front end.', 'quiz-master-next' ),
),
// array(
// 'question_type_id' => '13',
// 'description' => __( 'Use points based grading system for Polar questions.', 'quiz-master-next' ),
// ),
);
}
}