PluginProbe ʕ •ᴥ•ʔ
Contact Form 7 / 5.9.3
Contact Form 7 v5.9.3
6.1.6 5.0.2 5.0.3 5.0.4 5.0.5 5.1 5.1.1 5.1.2 5.1.3 5.1.4 5.1.5 5.1.6 5.1.7 5.1.8 5.1.9 5.2 5.2.1 5.2.2 5.3 5.3.1 5.3.2 5.4 5.4.1 5.4.2 5.5 5.5.1 5.5.2 5.5.3 5.5.4 5.5.5 5.5.6 5.5.6.1 5.6 5.6.1 5.6.2 5.6.3 5.6.4 5.7 5.7.1 5.7.2 5.7.3 5.7.4 5.7.5 5.7.5.1 5.7.6 5.7.7 5.8 5.8.1 5.8.2 5.8.3 5.8.4 5.8.5 5.8.6 5.8.7 5.9 5.9.2 5.9.3 5.9.4 5.9.5 5.9.6 5.9.7 5.9.8 6.0 6.0.1 6.0.2 6.0.3 6.0.4 6.0.5 6.0.6 6.1 6.1.1 6.1.2 6.1.3 6.1.4 6.1.5 trunk 1.1 1.10 1.10.0.1 1.10.1 1.2 1.3 1.3.1 1.3.2 1.4 1.4.1 1.4.2 1.4.3 1.4.4 1.5 1.6 1.6.1 1.7 1.7.1 1.7.2 1.7.4 1.7.5 1.7.6 1.7.6.1 1.7.7 1.7.7.1 1.7.8 1.8 1.8.0.1 1.8.0.2 1.8.0.3 1.8.0.4 1.8.1 1.8.1.1 1.9 1.9.1 1.9.2 1.9.2.1 1.9.2.2 1.9.3 1.9.4 1.9.5 1.9.5.1 2.0 2.0-beta 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.1 2.1.1 2.1.2 2.2 2.2.1 2.3 2.3.1 2.4 2.4.1 2.4.2 2.4.3 2.4.4 2.4.5 2.4.6 3.0 3.0-beta 3.0.1 3.0.2 3.0.2.1 3.1 3.1.1 3.1.2 3.2 3.2.1 3.3 3.3.1 3.3.2 3.3.3 3.4 3.4.1 3.4.2 3.5 3.5.1 3.5.2 3.5.3 3.5.4 3.6 3.7 3.7.1 3.7.2 3.8 3.8.1 3.9 3.9-beta 3.9.1 3.9.2 3.9.3 4.0 4.0.1 4.0.2 4.0.3 4.1 4.1-beta 4.1.1 4.1.2 4.2 4.2-beta 4.2.1 4.2.2 4.3 4.3.1 4.4 4.4.1 4.4.2 4.5 4.5.1 4.6 4.6.1 4.7 4.8 4.8.1 4.9 4.9.1 4.9.2 5.0 5.0.1
contact-form-7 / includes / form-tag.php
contact-form-7 / includes Last commit date
block-editor 2 years ago config-validator 2 years ago css 2 years ago js 2 years ago swv 2 years ago capabilities.php 7 years ago contact-form-functions.php 2 years ago contact-form-template.php 2 years ago contact-form.php 2 years ago controller.php 2 years ago file.php 2 years ago form-tag.php 2 years ago form-tags-manager.php 3 years ago formatting.php 2 years ago functions.php 2 years ago html-formatter.php 3 years ago integration.php 2 years ago l10n.php 3 years ago mail-tag.php 2 years ago mail.php 2 years ago pipe.php 2 years ago pocket-holder.php 3 years ago rest-api.php 2 years ago shortcodes.php 3 years ago special-mail-tags.php 2 years ago submission.php 2 years ago upgrade.php 2 years ago validation-functions.php 2 years ago validation.php 3 years ago
form-tag.php
581 lines
1 <?php
2
3 /**
4 * A form-tag.
5 *
6 * @link https://contactform7.com/tag-syntax/#form_tag
7 */
8 class WPCF7_FormTag implements ArrayAccess {
9
10 public $type;
11 public $basetype;
12 public $raw_name = '';
13 public $name = '';
14 public $options = array();
15 public $raw_values = array();
16 public $values = array();
17 public $pipes;
18 public $labels = array();
19 public $attr = '';
20 public $content = '';
21
22 public function __construct( $tag = array() ) {
23 if ( is_array( $tag )
24 or $tag instanceof self ) {
25 foreach ( $tag as $key => $value ) {
26 if ( property_exists( __CLASS__, $key ) ) {
27 $this->{$key} = $value;
28 }
29 }
30 }
31 }
32
33
34 /**
35 * Returns true if the type has a trailing asterisk.
36 */
37 public function is_required() {
38 return str_ends_with( $this->type, '*' );
39 }
40
41
42 /**
43 * Returns true if the form-tag has a specified option.
44 */
45 public function has_option( $option_name ) {
46 $pattern = sprintf( '/^%s(:.+)?$/i', preg_quote( $option_name, '/' ) );
47 return (bool) preg_grep( $pattern, $this->options );
48 }
49
50
51 /**
52 * Retrieves option values with the specified option name.
53 *
54 * @param string $option_name Option name.
55 * @param string $pattern Optional. A regular expression pattern or one of
56 * the keys of preset patterns. If specified, only options
57 * whose value part matches this pattern will be returned.
58 * @param bool $single Optional. If true, only the first matching option
59 * will be returned. Default false.
60 * @return string|array|bool The option value or an array of option values.
61 * False if there is no option matches the pattern.
62 */
63 public function get_option( $option_name, $pattern = '', $single = false ) {
64 $preset_patterns = array(
65 'date' => '[0-9]{4}-[0-9]{2}-[0-9]{2}',
66 'int' => '[0-9]+',
67 'signed_int' => '[-]?[0-9]+',
68 'num' => '(?:[0-9]+|(?:[0-9]+)?[.][0-9]+)',
69 'signed_num' => '[-]?(?:[0-9]+|(?:[0-9]+)?[.][0-9]+)',
70 'class' => '[-0-9a-zA-Z_]+',
71 'id' => '[-0-9a-zA-Z_]+',
72 );
73
74 if ( isset( $preset_patterns[$pattern] ) ) {
75 $pattern = $preset_patterns[$pattern];
76 }
77
78 if ( '' == $pattern ) {
79 $pattern = '.+';
80 }
81
82 $pattern = sprintf(
83 '/^%s:%s$/i',
84 preg_quote( $option_name, '/' ),
85 $pattern
86 );
87
88 if ( $single ) {
89 $matches = $this->get_first_match_option( $pattern );
90
91 if ( ! $matches ) {
92 return false;
93 }
94
95 return substr( $matches[0], strlen( $option_name ) + 1 );
96 } else {
97 $matches_a = $this->get_all_match_options( $pattern );
98
99 if ( ! $matches_a ) {
100 return false;
101 }
102
103 $results = array();
104
105 foreach ( $matches_a as $matches ) {
106 $results[] = substr( $matches[0], strlen( $option_name ) + 1 );
107 }
108
109 return $results;
110 }
111 }
112
113
114 /**
115 * Retrieves the id option value from the form-tag.
116 */
117 public function get_id_option() {
118 static $used = array();
119
120 $option = $this->get_option( 'id', 'id', true );
121
122 if (
123 ! $option or
124 str_starts_with( $option, 'wpcf7' ) or
125 in_array( $option, $used, true )
126 ) {
127 return false;
128 }
129
130 $used[] = $option;
131
132 return $option;
133 }
134
135
136 /**
137 * Retrieves the class option value from the form-tag.
138 *
139 * @param string|array $default_classes Optional. Preset classes as an array
140 * or a whitespace-separated list. Default empty string.
141 * @return string|bool A whitespace-separated list of classes.
142 * False if there is no class to return.
143 */
144 public function get_class_option( $default_classes = '' ) {
145 if ( is_string( $default_classes ) ) {
146 $default_classes = explode( ' ', $default_classes );
147 }
148
149 $options = array_merge(
150 (array) $default_classes,
151 (array) $this->get_option( 'class' )
152 );
153
154 $options = array_map( 'sanitize_html_class', $options );
155 $options = array_filter( array_unique( $options ) );
156
157 if ( empty( $options ) ) {
158 return false;
159 }
160
161 return implode( ' ', $options );
162 }
163
164
165 /**
166 * Retrieves the size option value from the form-tag.
167 *
168 * @param string $default_value Optional default value.
169 * @return string The option value.
170 */
171 public function get_size_option( $default_value = false ) {
172 $option = $this->get_option( 'size', 'int', true );
173
174 if ( $option ) {
175 return $option;
176 }
177
178 $matches_a = $this->get_all_match_options( '%^([0-9]*)/[0-9]*$%' );
179
180 foreach ( (array) $matches_a as $matches ) {
181 if ( isset( $matches[1] ) and '' !== $matches[1] ) {
182 return $matches[1];
183 }
184 }
185
186 return $default_value;
187 }
188
189
190 /**
191 * Retrieves the maxlength option value from the form-tag.
192 *
193 * @param string $default_value Optional default value.
194 * @return string The option value.
195 */
196 public function get_maxlength_option( $default_value = false ) {
197 $option = $this->get_option( 'maxlength', 'int', true );
198
199 if ( $option ) {
200 return $option;
201 }
202
203 $matches_a = $this->get_all_match_options(
204 '%^(?:[0-9]*x?[0-9]*)?/([0-9]+)$%'
205 );
206
207 foreach ( (array) $matches_a as $matches ) {
208 if ( isset( $matches[1] ) and '' !== $matches[1] ) {
209 return $matches[1];
210 }
211 }
212
213 return $default_value;
214 }
215
216
217 /**
218 * Retrieves the minlength option value from the form-tag.
219 *
220 * @param string $default_value Optional default value.
221 * @return string The option value.
222 */
223 public function get_minlength_option( $default_value = false ) {
224 $option = $this->get_option( 'minlength', 'int', true );
225
226 if ( $option ) {
227 return $option;
228 } else {
229 return $default_value;
230 }
231 }
232
233
234 /**
235 * Retrieves the cols option value from the form-tag.
236 *
237 * @param string $default_value Optional default value.
238 * @return string The option value.
239 */
240 public function get_cols_option( $default_value = false ) {
241 $option = $this->get_option( 'cols', 'int', true );
242
243 if ( $option ) {
244 return $option;
245 }
246
247 $matches_a = $this->get_all_match_options(
248 '%^([0-9]*)x([0-9]*)(?:/[0-9]+)?$%'
249 );
250
251 foreach ( (array) $matches_a as $matches ) {
252 if ( isset( $matches[1] ) and '' !== $matches[1] ) {
253 return $matches[1];
254 }
255 }
256
257 return $default_value;
258 }
259
260
261 /**
262 * Retrieves the rows option value from the form-tag.
263 *
264 * @param string $default_value Optional default value.
265 * @return string The option value.
266 */
267 public function get_rows_option( $default_value = false ) {
268 $option = $this->get_option( 'rows', 'int', true );
269
270 if ( $option ) {
271 return $option;
272 }
273
274 $matches_a = $this->get_all_match_options(
275 '%^([0-9]*)x([0-9]*)(?:/[0-9]+)?$%'
276 );
277
278 foreach ( (array) $matches_a as $matches ) {
279 if ( isset( $matches[2] ) and '' !== $matches[2] ) {
280 return $matches[2];
281 }
282 }
283
284 return $default_value;
285 }
286
287
288 /**
289 * Retrieves a date-type option value from the form-tag.
290 *
291 * @param string $option_name A date-type option name, such as 'min' or 'max'.
292 * @return string|bool The option value in YYYY-MM-DD format. False if the
293 * option does not exist or the date value is invalid.
294 */
295 public function get_date_option( $option_name ) {
296 $option_value = $this->get_option( $option_name, '', true );
297
298 if ( empty( $option_value ) ) {
299 return false;
300 }
301
302 $date = apply_filters( 'wpcf7_form_tag_date_option',
303 null,
304 array( $option_name => $option_value )
305 );
306
307 if ( $date ) {
308 $date_pattern = '/^([0-9]{4})-([0-9]{2})-([0-9]{2})$/';
309
310 if ( preg_match( $date_pattern, $date, $matches )
311 and checkdate( $matches[2], $matches[3], $matches[1] ) ) {
312 return $date;
313 }
314 } else {
315 $datetime_obj = date_create_immutable(
316 preg_replace( '/[_]+/', ' ', $option_value ),
317 wp_timezone()
318 );
319
320 if ( $datetime_obj ) {
321 return $datetime_obj->format( 'Y-m-d' );
322 }
323 }
324
325 return false;
326 }
327
328
329 /**
330 * Retrieves the default option value from the form-tag.
331 *
332 * @param string|array $default_value Optional default value.
333 * @param string|array $args Optional options for the option value retrieval.
334 * @return string|array The option value. If the multiple option is enabled,
335 * an array of option values.
336 */
337 public function get_default_option( $default_value = '', $args = '' ) {
338 $args = wp_parse_args( $args, array(
339 'multiple' => false,
340 'shifted' => false,
341 ) );
342
343 $options = (array) $this->get_option( 'default' );
344 $values = array();
345
346 if ( empty( $options ) ) {
347 return $args['multiple'] ? $values : $default_value;
348 }
349
350 foreach ( $options as $opt ) {
351 $opt = sanitize_key( $opt );
352
353 if ( 'user_' == substr( $opt, 0, 5 ) and is_user_logged_in() ) {
354 $primary_props = array( 'user_login', 'user_email', 'user_url' );
355 $opt = in_array( $opt, $primary_props ) ? $opt : substr( $opt, 5 );
356
357 $user = wp_get_current_user();
358 $user_prop = $user->get( $opt );
359
360 if ( ! empty( $user_prop ) ) {
361 if ( $args['multiple'] ) {
362 $values[] = $user_prop;
363 } else {
364 return $user_prop;
365 }
366 }
367
368 } elseif ( 'post_meta' === $opt and in_the_loop() ) {
369 if ( $args['multiple'] ) {
370 $values = array_merge( $values,
371 get_post_meta( get_the_ID(), $this->name )
372 );
373 } else {
374 $val = (string) get_post_meta( get_the_ID(), $this->name, true );
375
376 if ( strlen( $val ) ) {
377 return $val;
378 }
379 }
380
381 } elseif ( 'get' === $opt and isset( $_GET[$this->name] ) ) {
382 $vals = (array) $_GET[$this->name];
383 $vals = array_map( 'wpcf7_sanitize_query_var', $vals );
384
385 if ( $args['multiple'] ) {
386 $values = array_merge( $values, $vals );
387 } else {
388 $val = isset( $vals[0] ) ? (string) $vals[0] : '';
389
390 if ( strlen( $val ) ) {
391 return $val;
392 }
393 }
394
395 } elseif ( 'post' === $opt and isset( $_POST[$this->name] ) ) {
396 $vals = (array) $_POST[$this->name];
397 $vals = array_map( 'wpcf7_sanitize_query_var', $vals );
398
399 if ( $args['multiple'] ) {
400 $values = array_merge( $values, $vals );
401 } else {
402 $val = isset( $vals[0] ) ? (string) $vals[0] : '';
403
404 if ( strlen( $val ) ) {
405 return $val;
406 }
407 }
408
409 } elseif ( 'shortcode_attr' === $opt ) {
410 if ( $contact_form = WPCF7_ContactForm::get_current() ) {
411 $val = $contact_form->shortcode_attr( $this->name );
412
413 if ( isset( $val ) and strlen( $val ) ) {
414 if ( $args['multiple'] ) {
415 $values[] = $val;
416 } else {
417 return $val;
418 }
419 }
420 }
421
422 } elseif ( preg_match( '/^[0-9_]+$/', $opt ) ) {
423 $nums = explode( '_', $opt );
424
425 foreach ( $nums as $num ) {
426 $num = absint( $num );
427 $num = $args['shifted'] ? $num : $num - 1;
428
429 if ( isset( $this->values[$num] ) ) {
430 if ( $args['multiple'] ) {
431 $values[] = $this->values[$num];
432 } else {
433 return $this->values[$num];
434 }
435 }
436 }
437 }
438 }
439
440 if ( $args['multiple'] ) {
441 $values = array_unique( $values );
442 return $values;
443 } else {
444 return $default_value;
445 }
446 }
447
448
449 /**
450 * Retrieves the data option value from the form-tag.
451 *
452 * @param string|array $args Optional options for the option value retrieval.
453 * @return mixed The option value.
454 */
455 public function get_data_option( $args = '' ) {
456 $options = (array) $this->get_option( 'data' );
457
458 return apply_filters( 'wpcf7_form_tag_data_option', null, $options, $args );
459 }
460
461
462 /**
463 * Retrieves the limit option value from the form-tag.
464 *
465 * @param int $default_value Optional default value. Default 1048576.
466 * @return int The option value.
467 */
468 public function get_limit_option( $default_value = MB_IN_BYTES ) {
469 $pattern = '/^limit:([1-9][0-9]*)([kKmM]?[bB])?$/';
470
471 $matches = $this->get_first_match_option( $pattern );
472
473 if ( $matches ) {
474 $size = (int) $matches[1];
475
476 if ( ! empty( $matches[2] ) ) {
477 $kbmb = strtolower( $matches[2] );
478
479 if ( 'kb' === $kbmb ) {
480 $size *= KB_IN_BYTES;
481 } elseif ( 'mb' === $kbmb ) {
482 $size *= MB_IN_BYTES;
483 }
484 }
485
486 return $size;
487 }
488
489 return (int) $default_value;
490 }
491
492
493 /**
494 * Retrieves the value of the first option matches the given
495 * regular expression pattern.
496 *
497 * @param string $pattern Regular expression pattern.
498 * @return array|bool Option value as an array of matched strings.
499 * False if there is no option matches the pattern.
500 */
501 public function get_first_match_option( $pattern ) {
502 foreach( (array) $this->options as $option ) {
503 if ( preg_match( $pattern, $option, $matches ) ) {
504 return $matches;
505 }
506 }
507
508 return false;
509 }
510
511
512 /**
513 * Retrieves values of options that match the given
514 * regular expression pattern.
515 *
516 * @param string $pattern Regular expression pattern.
517 * @return array Array of arrays of strings that match the pattern.
518 */
519 public function get_all_match_options( $pattern ) {
520 $result = array();
521
522 foreach( (array) $this->options as $option ) {
523 if ( preg_match( $pattern, $option, $matches ) ) {
524 $result[] = $matches;
525 }
526 }
527
528 return $result;
529 }
530
531
532 /**
533 * Assigns a value to the specified offset.
534 *
535 * @link https://www.php.net/manual/en/arrayaccess.offsetset.php
536 */
537 #[ReturnTypeWillChange]
538 public function offsetSet( $offset, $value ) {
539 if ( property_exists( __CLASS__, $offset ) ) {
540 $this->{$offset} = $value;
541 }
542 }
543
544
545 /**
546 * Returns the value at specified offset.
547 *
548 * @link https://www.php.net/manual/en/arrayaccess.offsetget.php
549 */
550 #[ReturnTypeWillChange]
551 public function offsetGet( $offset ) {
552 if ( property_exists( __CLASS__, $offset ) ) {
553 return $this->{$offset};
554 }
555
556 return null;
557 }
558
559
560 /**
561 * Returns true if the specified offset exists.
562 *
563 * @link https://www.php.net/manual/en/arrayaccess.offsetexists.php
564 */
565 #[ReturnTypeWillChange]
566 public function offsetExists( $offset ) {
567 return property_exists( __CLASS__, $offset );
568 }
569
570
571 /**
572 * Unsets an offset.
573 *
574 * @link https://www.php.net/manual/en/arrayaccess.offsetunset.php
575 */
576 #[ReturnTypeWillChange]
577 public function offsetUnset( $offset ) {
578 }
579
580 }
581