Plugin Directory

Changeset 3270191


Ignore:
Timestamp:
04/10/2025 07:45:04 AM (12 months ago)
Author:
expresstech
Message:

10.1.0 to trunk

Location:
quiz-master-next/trunk
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • quiz-master-next/trunk/js/qsm-quiz.js

    r3248261 r3270191  
    21262126    qmn_count_upward_status : false
    21272127}
     2128
     2129const userAnswers = {};
     2130
     2131jQuery(document).on('qsm_after_select_answer', (event, quizID, question_id, value, $this, answer_type) => {
     2132    const variableName = `%USER_ANSWER_${parseInt(question_id)}%`;
     2133
     2134    let replacementValue;
     2135
     2136    if (answer_type === 'radio') {
     2137        if (jQuery('.qsm_select.qsm_dropdown').length) {
     2138            replacementValue = jQuery(`option[value="${value}"]`).text().trim();
     2139        } else {
     2140            const ansValue = ++value;
     2141            const forValue = `question${question_id}_${ansValue}`;
     2142            replacementValue = jQuery(`label[for="${forValue}"]`).text().trim();
     2143        }
     2144    } else {
     2145        replacementValue = value;
     2146    }
     2147
     2148    if (replacementValue !== undefined) {
     2149        userAnswers[variableName] = replacementValue;
     2150
     2151        jQuery('.qsm-quiz-container-' + quizID).each((_, container) => {
     2152            const replacePlaceholders = (node) => {
     2153                if (node.nodeType === Node.TEXT_NODE) {
     2154                    if (!node.hasOwnProperty('__originalText')) {
     2155                        node.__originalText = node.nodeValue;
     2156                    }
     2157
     2158                    let newValue = node.__originalText;
     2159                    for (const [varName, answer] of Object.entries(userAnswers)) {
     2160                        newValue = newValue.replace(new RegExp(varName, 'g'), answer);
     2161                    }
     2162                    node.nodeValue = newValue;
     2163
     2164                } else if (node.nodeType === Node.ELEMENT_NODE && !['INPUT', 'TEXTAREA'].includes(node.tagName)) {
     2165                    Array.from(node.childNodes).forEach(child => replacePlaceholders(child));
     2166                }
     2167            };
     2168
     2169            replacePlaceholders(container);
     2170        });
     2171    }
     2172});
  • quiz-master-next/trunk/mlw_quizmaster2.php

    r3257129 r3270191  
    33 * Plugin Name: Quiz And Survey Master
    44 * Description: Easily and quickly add quizzes and surveys to your website.
    5  * Version: 10.0.3
     5 * Version: 10.1.0
    66 * Author: ExpressTech
    77 * Author URI: https://quizandsurveymaster.com/
     
    4444     * @since 4.0.0
    4545     */
    46     public $version = '10.0.3';
     46    public $version = '10.1.0';
    4747
    4848    /**
  • quiz-master-next/trunk/php/classes/class-qmn-quiz-manager.php

    r3248261 r3270191  
    17361736
    17371737    /**
     1738     * Validate Contact Fields
     1739     *
     1740     * Validates the contact fields in the request
     1741     *
     1742     * @since  10.0.3
     1743     * @param  array $contact_form The contact form fields
     1744     * @param  array $request      The request data
     1745     * @return bool               Whether the contact fields are valid
     1746     */
     1747    public function qsm_validate_contact_fields( $contact_form, $request ) {
     1748        $errors = [];
     1749        foreach ( $contact_form as $index => $field ) {
     1750            if ( 'true' === $field['enable'] ) {
     1751                $contact_key = "contact_field_" . $index;
     1752                $value = isset( $request[ $contact_key ] ) ? trim( $request[ $contact_key ] ) : '';
     1753
     1754                if ( 'true' === $field['required'] && empty( $value ) ) {
     1755                    $errors[] = __( "Enter ", 'quiz-master-next' ) . $field['label'];
     1756                }
     1757
     1758                if ( ! empty( $field['minlength'] ) && strlen( $value ) < (int) $field['minlength'] ) {
     1759                    $errors[] = $field['label'] . __( " must be at least ", 'quiz-master-next' ) . $field['minlength'] . __( " characters long.", 'quiz-master-next' );
     1760                }
     1761
     1762                if ( ! empty( $field['maxlength'] ) && strlen( $value ) > (int) $field['maxlength'] ) {
     1763                    $errors[] = $field['label'] . __( " must be no more than ", 'quiz-master-next' ) . $field['maxlength'] . __( " characters long.", 'quiz-master-next' );
     1764                }
     1765
     1766                if ( 'email' === $field['type'] && ! empty( $value ) ) {
     1767                    if ( ! filter_var( $value, FILTER_VALIDATE_EMAIL ) ) {
     1768                        $errors[] = __( "Email must be a valid e-mail.", 'quiz-master-next' );
     1769                    } else {
     1770                        $email_domain = substr( strrchr( $value, "@" ), 1 );
     1771
     1772                        if ( ! empty( $field['allowdomains'] ) ) {
     1773                            $allowed_domains = array_map( 'trim', explode( ',', $field['allowdomains'] ) );
     1774                            if ( ! in_array( $email_domain, $allowed_domains, true ) ) {
     1775                                $errors[] = __( "Email must be from an allowed domain (", 'quiz-master-next' ) . $field['allowdomains'] . ").";
     1776                            }
     1777                        }
     1778
     1779                        if ( ! empty( $field['blockdomains'] ) ) {
     1780                            $blocked_domains = array_map( 'trim', explode( ',', $field['blockdomains'] ) );
     1781                            if ( in_array( $email_domain, $blocked_domains, true ) ) {
     1782                                $errors[] = __( "Email cannot be from a blocked domain (", 'quiz-master-next' ) . $field['blockdomains'] . ").";
     1783                            }
     1784                        }
     1785                    }
     1786                }
     1787            }
     1788        }
     1789        return empty( $errors ) ? 1 : "<strong>" . __( 'There was an error with your submission:', 'quiz-master-next' ) . "</strong><ul style='left: -20px; position: relative;'><li>" . implode( "</li><li>", $errors ) . "</li></ul>";
     1790    }
     1791
     1792    /**
    17381793     * Calls the results page from ajax
    17391794     *
     
    18041859        $timezone   = isset( $_POST['currentuserTimeZone'] ) ? sanitize_text_field( wp_unslash( $_POST['currentuserTimeZone'] ) ) : '';
    18051860        $dtUtcDate  = strtotime( $dateStr . ' ' . $timezone );
     1861        $missing_contact_fields = $this->qsm_validate_contact_fields( $qsm_option['contact_form'], $_REQUEST );
     1862        if ( 1 !== $missing_contact_fields ) {
     1863            echo wp_json_encode(
     1864                array(
     1865                    'display'       => '<div class="qsm-result-page-warning">' . wp_kses_post( $missing_contact_fields ) . '</div>',
     1866                    'redirect'      => false,
     1867                    'result_status' => array(
     1868                        'save_response' => false,
     1869                    ),
     1870                )
     1871            );
     1872            wp_die();
     1873        }
    18061874
    18071875        if ( isset($qsm_option['quiz_options']['not_allow_after_expired_time']) && '1' === $qsm_option['quiz_options']['not_allow_after_expired_time'] && isset( $_POST['currentuserTime'] ) && sanitize_text_field( wp_unslash( $_POST['currentuserTime'] ) ) > $dtUtcDate && ! empty($dateStr) ) {
  • quiz-master-next/trunk/php/template-variables.php

    r3248261 r3270191  
    158158        $content = str_replace( '%ANSWER_' . $question_id . '%',$answerstr , $content );
    159159    }
     160    while ( false !== strpos($content, '%USER_ANSWER_') ) {
     161        $question_id = mlw_qmn_get_string_between($content, '%USER_ANSWER_', '%');
     162        $question_answers_array = $mlw_quiz_array['question_answers_array'] ?? [];
     163       
     164        foreach ( $question_answers_array as $question ) {
     165            if ( $question['id'] == $question_id ) {
     166                $user_answer = is_array($question['user_answer']) ? implode(", ", $question['user_answer']) : '';
     167                $content = str_replace('%USER_ANSWER_' . $question_id . '%', $user_answer, $content);
     168                break;
     169            }
     170        }
     171    }
    160172    return $content;
    161173}
     
    170182 */
    171183function qsm_variable_total_possible_points( $content, $mlw_quiz_array ) {
    172     if ( isset( $mlw_quiz_array['total_possible_points'] ) && qsm_is_allow_score_roundoff() ) {
    173         $content = str_replace( '%MAXIMUM_POINTS%', round( $mlw_quiz_array['total_possible_points'] ), $content );
    174     } elseif ( isset( $mlw_quiz_array['total_possible_points'] ) ) {
    175         $content = str_replace( '%MAXIMUM_POINTS%', round( $mlw_quiz_array['total_possible_points'], 2 ), $content );
     184    if ( isset($mlw_quiz_array['total_possible_points']) && is_numeric($mlw_quiz_array['total_possible_points']) ) {
     185        $points = floatval($mlw_quiz_array['total_possible_points']);
     186        $rounded = qsm_is_allow_score_roundoff() ? round($points) : round($points, 2);
     187        $content = str_replace('%MAXIMUM_POINTS%', $rounded, $content);
     188    } else {
     189        $content = str_replace('%MAXIMUM_POINTS%', '0', $content);
    176190    }
    177191    return $content;
     
    10751089    // Get question setting
    10761090    $question_settings    = isset( $questions[ $answer['id'] ]['settings'] ) ? $questions[ $answer['id'] ]['settings'] : array();
    1077     $question_title       = $mlwQuizMasterNext->pluginHelper->qsm_language_support( $answer['question_title'], "Question-{$answer['id']}", 'QSM Questions' );
     1091    $question_title = isset($answer['question_title'])
     1092    ? $mlwQuizMasterNext->pluginHelper->qsm_language_support($answer['question_title'], "Question-{$answer['id']}", 'QSM Questions')
     1093    : '';
    10781094    $question_description = '';
    10791095    if ( 14 == $answer['question_type'] ) {
  • quiz-master-next/trunk/readme.txt

    r3257129 r3270191  
    55Tested up to: 6.7
    66Requires PHP: 5.4
    7 Stable tag: 10.0.3
     7Stable tag: 10.1.0
    88License: GPLv2
    99License URI: http://www.gnu.org/licenses/gpl-2.0.html
     
    222222
    223223== Changelog ==
     224= 10.1.0 ( April 08, 2025 ) =
     225* Feature: Implemented server-side validation for contact form fields
     226* Feature: Added option to use responses in other questions
     227* Enhancement: Refined the user interface to align with the WordPress 2024 Dark Theme
     228
    224229= 10.0.3 ( March 17, 2025 ) =
    225230* Feature: Added an option to remove orphaned questions and results
  • quiz-master-next/trunk/templates/qmn_primary.css

    r3248261 r3270191  
    109109  -moz-box-sizing: border-box;
    110110  box-sizing: border-box;
    111   color: #222;
    112111}
    113112
Note: See TracChangeset for help on using the changeset viewer.