add_filter( 'map_meta_cap', 'wpcf7_map_meta_cap', 10, 4 );
function wpcf7_map_meta_cap( $caps, $cap, $user_id, $args ) {
$meta_caps = array(
'wpcf7_edit_contact_form' => WPCF7_ADMIN_READ_WRITE_CAPABILITY,
'wpcf7_edit_contact_forms' => WPCF7_ADMIN_READ_WRITE_CAPABILITY,
'wpcf7_read_contact_form' => WPCF7_ADMIN_READ_CAPABILITY,
'wpcf7_read_contact_forms' => WPCF7_ADMIN_READ_CAPABILITY,
'wpcf7_delete_contact_form' => WPCF7_ADMIN_READ_WRITE_CAPABILITY,
'wpcf7_delete_contact_forms' => WPCF7_ADMIN_READ_WRITE_CAPABILITY,
'wpcf7_manage_integration' => 'manage_options',
'wpcf7_submit' => 'read',
);
$meta_caps = apply_filters( 'wpcf7_map_meta_cap', $meta_caps );
$caps = array_diff( $caps, array_keys( $meta_caps ) );
if ( isset( $meta_caps[$cap] ) ) {
$caps[] = $meta_caps[$cap];
}
return $caps;
}
/**
* Returns path to a plugin file.
*
* @param string $path File path relative to the plugin root directory.
* @return string Absolute file path.
*/
function wpcf7_plugin_path( $path = '' ) {
return path_join( WPCF7_PLUGIN_DIR, trim( $path, '/' ) );
}
/**
* Returns the URL to a plugin file.
*
* @param string $path File path relative to the plugin root directory.
* @return string URL.
*/
function wpcf7_plugin_url( $path = '' ) {
$url = plugins_url( $path, WPCF7_PLUGIN );
if ( is_ssl()
and 'http:' == substr( $url, 0, 5 ) ) {
$url = 'https:' . substr( $url, 5 );
}
return $url;
}
/**
* Include a file under WPCF7_PLUGIN_MODULES_DIR.
*
* @param string $path File path relative to the module dir.
* @return bool True on success, false on failure.
*/
function wpcf7_include_module_file( $path ) {
$dir = WPCF7_PLUGIN_MODULES_DIR;
if ( empty( $dir ) or ! is_dir( $dir ) ) {
return false;
}
$path = path_join( $dir, ltrim( $path, '/' ) );
if ( file_exists( $path ) ) {
include_once $path;
return true;
}
return false;
}
/**
* Retrieves uploads directory information.
*
* @param string|bool $type Optional. Type of output. Default false.
* @return array|string Information about the upload directory.
*/
function wpcf7_upload_dir( $type = false ) {
$uploads = wp_get_upload_dir();
$uploads = apply_filters( 'wpcf7_upload_dir', array(
'dir' => $uploads['basedir'],
'url' => $uploads['baseurl'],
) );
if ( 'dir' == $type ) {
return $uploads['dir'];
} if ( 'url' == $type ) {
return $uploads['url'];
}
return $uploads;
}
/**
* Verifies that a correct security nonce was used with time limit.
*
* @param string $nonce Nonce value that was used for verification.
* @param string $action Optional. Context to what is taking place.
* Default 'wp_rest'.
* @return int|bool 1 if the nonce is generated between 0-12 hours ago,
* 2 if the nonce is generated between 12-24 hours ago.
* False if the nonce is invalid.
*/
function wpcf7_verify_nonce( $nonce, $action = 'wp_rest' ) {
return wp_verify_nonce( $nonce, $action );
}
/**
* Creates a cryptographic token tied to a specific action, user, user session,
* and window of time.
*
* @param string $action Optional. Context to what is taking place.
* Default 'wp_rest'.
* @return string The token.
*/
function wpcf7_create_nonce( $action = 'wp_rest' ) {
return wp_create_nonce( $action );
}
/**
* Converts multi-dimensional array to a flat array.
*
* @param mixed $input Array or item of array.
* @return array Flatten array.
*/
function wpcf7_array_flatten( $input ) {
if ( ! is_array( $input ) ) {
return array( $input );
}
$output = array();
foreach ( $input as $value ) {
$output = array_merge( $output, wpcf7_array_flatten( $value ) );
}
return $output;
}
/**
* Excludes unset or blank text values from the given array.
*
* @param array $input The array.
* @return array Array without blank text values.
*/
function wpcf7_exclude_blank( $input ) {
$output = array_filter( $input,
static function ( $i ) {
return isset( $i ) && '' !== $i;
}
);
return array_values( $output );
}
/**
* Creates a comma-separated list from a multi-dimensional array.
*
* @param mixed $input Array or item of array.
* @param string|array $args Optional. Output options.
* @return string Comma-separated list.
*/
function wpcf7_flat_join( $input, $args = '' ) {
$args = wp_parse_args( $args, array(
'separator' => ', ',
) );
$input = wpcf7_array_flatten( $input );
$output = array();
foreach ( (array) $input as $value ) {
if ( is_scalar( $value ) ) {
$output[] = trim( (string) $value );
}
}
return implode( $args['separator'], $output );
}
/**
* Returns true if HTML5 is supported.
*/
function wpcf7_support_html5() {
return (bool) wpcf7_apply_filters_deprecated(
'wpcf7_support_html5',
array( true ),
'5.6',
''
);
}
/**
* Returns true if HTML5 fallback is active.
*/
function wpcf7_support_html5_fallback() {
return (bool) apply_filters( 'wpcf7_support_html5_fallback', false );
}
/**
* Returns true if the Really Simple CAPTCHA plugin is used for contact forms.
*/
function wpcf7_use_really_simple_captcha() {
return apply_filters( 'wpcf7_use_really_simple_captcha',
WPCF7_USE_REALLY_SIMPLE_CAPTCHA
);
}
/**
* Returns true if config validation is active.
*/
function wpcf7_validate_configuration() {
return apply_filters( 'wpcf7_validate_configuration',
WPCF7_VALIDATE_CONFIGURATION
);
}
/**
* Returns true if wpcf7_autop() is applied.
*/
function wpcf7_autop_or_not( $options = '' ) {
$options = wp_parse_args( $options, array(
'for' => 'form',
) );
return (bool) apply_filters( 'wpcf7_autop_or_not', WPCF7_AUTOP, $options );
}
/**
* Returns true if JavaScript for this plugin is loaded.
*/
function wpcf7_load_js() {
return apply_filters( 'wpcf7_load_js', WPCF7_LOAD_JS );
}
/**
* Returns true if CSS for this plugin is loaded.
*/
function wpcf7_load_css() {
return apply_filters( 'wpcf7_load_css', WPCF7_LOAD_CSS );
}
/**
* Builds an HTML anchor element.
*
* @param string $url Link URL.
* @param string $anchor_text Anchor label text.
* @param string|array $args Optional. Link options.
* @return string Formatted anchor element.
*/
function wpcf7_link( $url, $anchor_text, $args = '' ) {
$args = wp_parse_args( $args, array(
'id' => null,
'class' => null,
) );
$atts = array_merge( $args, array(
'href' => esc_url( $url ),
) );
return sprintf(
'%2$s',
wpcf7_format_atts( $atts ),
esc_html( $anchor_text )
);
}
/**
* Returns the current request URL.
*/
function wpcf7_get_request_uri() {
static $request_uri = '';
if ( empty( $request_uri ) ) {
$request_uri = add_query_arg( array() );
}
return sanitize_url( $request_uri );
}
/**
* Registers post types used for this plugin.
*/
function wpcf7_register_post_types() {
if ( class_exists( 'WPCF7_ContactForm' ) ) {
WPCF7_ContactForm::register_post_type();
return true;
} else {
return false;
}
}
/**
* Returns the version string of this plugin.
*
* @param string|array $args Optional. Output options.
* @return string Version string.
*/
function wpcf7_version( $args = '' ) {
$defaults = array(
'limit' => -1,
'only_major' => false,
);
$args = wp_parse_args( $args, $defaults );
if ( $args['only_major'] ) {
$args['limit'] = 2;
}
$args['limit'] = (int) $args['limit'];
$ver = WPCF7_VERSION;
$ver = strtr( $ver, '_-+', '...' );
$ver = preg_replace( '/[^0-9.]+/', ".$0.", $ver );
$ver = preg_replace( '/[.]+/', ".", $ver );
$ver = trim( $ver, '.' );
$ver = explode( '.', $ver );
if ( -1 < $args['limit'] ) {
$ver = array_slice( $ver, 0, $args['limit'] );
}
$ver = implode( '.', $ver );
return $ver;
}
/**
* Returns array entries that match the given version.
*
* @param string $version The version to search for.
* @param array $input Search target array.
* @return array|bool Array of matched entries. False on failure.
*/
function wpcf7_version_grep( $version, array $input ) {
$pattern = '/^' . preg_quote( (string) $version, '/' ) . '(?:\.|$)/';
return preg_grep( $pattern, $input );
}
/**
* Returns an enctype attribute value.
*
* @param string $enctype Enctype value.
* @return string Enctype value. Empty if not a valid enctype.
*/
function wpcf7_enctype_value( $enctype ) {
$enctype = trim( $enctype );
if ( empty( $enctype ) ) {
return '';
}
$valid_enctypes = array(
'application/x-www-form-urlencoded',
'multipart/form-data',
'text/plain',
);
if ( in_array( $enctype, $valid_enctypes ) ) {
return $enctype;
}
$pattern = '%^enctype="(' . implode( '|', $valid_enctypes ) . ')"$%';
if ( preg_match( $pattern, $enctype, $matches ) ) {
return $matches[1]; // for back-compat
}
return '';
}
/**
* Removes directory recursively.
*
* @param string $dir Directory path.
* @return bool True on success, false on failure.
*/
function wpcf7_rmdir_p( $dir ) {
if ( is_file( $dir ) ) {
$file = $dir;
if ( @unlink( $file ) ) {
return true;
}
$stat = stat( $file );
if ( @chmod( $file, $stat['mode'] | 0200 ) ) { // add write for owner
if ( @unlink( $file ) ) {
return true;
}
@chmod( $file, $stat['mode'] );
}
return false;
}
if ( ! is_dir( $dir ) ) {
return false;
}
if ( $handle = opendir( $dir ) ) {
while ( false !== ( $file = readdir( $handle ) ) ) {
if ( $file == "."
or $file == ".." ) {
continue;
}
wpcf7_rmdir_p( path_join( $dir, $file ) );
}
closedir( $handle );
}
if ( false !== ( $files = scandir( $dir ) )
and ! array_diff( $files, array( '.', '..' ) ) ) {
return rmdir( $dir );
}
return false;
}
/**
* Builds a URL-encoded query string.
*
* @link https://developer.wordpress.org/reference/functions/_http_build_query/
*
* @param array $args URL query parameters.
* @param string $key Optional. If specified, used to prefix key name.
* @return string Query string.
*/
function wpcf7_build_query( $args, $key = '' ) {
$sep = '&';
$ret = array();
foreach ( (array) $args as $k => $v ) {
$k = urlencode( $k );
if ( ! empty( $key ) ) {
$k = $key . '%5B' . $k . '%5D';
}
if ( null === $v ) {
continue;
} elseif ( false === $v ) {
$v = '0';
}
if ( is_array( $v ) or is_object( $v ) ) {
array_push( $ret, wpcf7_build_query( $v, $k ) );
} else {
array_push( $ret, $k . '=' . urlencode( $v ) );
}
}
return implode( $sep, $ret );
}
/**
* Returns the number of code units in a string.
*
* @link http://www.w3.org/TR/html5/infrastructure.html#code-unit-length
*
* @param string $text Input string.
* @return int|bool The number of code units, or false if
* mb_convert_encoding is not available.
*/
function wpcf7_count_code_units( $text ) {
static $use_mb = null;
if ( is_null( $use_mb ) ) {
$use_mb = function_exists( 'mb_convert_encoding' );
}
if ( ! $use_mb ) {
return false;
}
$text = (string) $text;
$text = str_replace( "\r\n", "\n", $text );
$encoding = mb_detect_encoding( $text, mb_detect_order(), true );
if ( $encoding ) {
$text = mb_convert_encoding( $text, 'UTF-16', $encoding );
} else {
$text = mb_convert_encoding( $text, 'UTF-16', 'UTF-8' );
}
$byte_count = mb_strlen( $text, '8bit' );
return floor( $byte_count / 2 );
}
/**
* Returns true if WordPress is running on the localhost.
*/
function wpcf7_is_localhost() {
$sitename = wp_parse_url( network_home_url(), PHP_URL_HOST );
return in_array( strtolower( $sitename ), array( 'localhost', '127.0.0.1' ) );
}
/**
* Marks a function as deprecated and informs when it has been used.
*
* @param string $function_name The function that was called.
* @param string $version The version of Contact Form 7 that deprecated
* the function.
* @param string $replacement The function that should have been called.
*/
function wpcf7_deprecated_function( $function_name, $version, $replacement ) {
if ( WP_DEBUG ) {
if ( function_exists( '__' ) ) {
trigger_error(
sprintf(
/* translators: 1: PHP function name, 2: version number, 3: alternative function name */
__( 'Function %1$s is deprecated since Contact Form 7 version %2$s! Use %3$s instead.', 'contact-form-7' ),
$function_name, $version, $replacement
),
E_USER_DEPRECATED
);
} else {
trigger_error(
sprintf(
'Function %1$s is deprecated since Contact Form 7 version %2$s! Use %3$s instead.',
$function_name, $version, $replacement
),
E_USER_DEPRECATED
);
}
}
}
/**
* Fires functions attached to a deprecated filter hook.
*
* @param string $hook_name The name of the filter hook.
* @param array $args Array of additional function arguments to be
* passed to apply_filters().
* @param string $version The version of Contact Form 7 that deprecated
* the hook.
* @param string $replacement The hook that should have been used.
*/
function wpcf7_apply_filters_deprecated( $hook_name, $args, $version, $replacement = '' ) {
if ( ! has_filter( $hook_name ) ) {
return $args[0];
}
if ( WP_DEBUG and apply_filters( 'deprecated_hook_trigger_error', true ) ) {
if ( $replacement ) {
trigger_error(
sprintf(
/* translators: 1: WordPress hook name, 2: version number, 3: alternative hook name */
__( 'Hook %1$s is deprecated since Contact Form 7 version %2$s! Use %3$s instead.', 'contact-form-7' ),
$hook_name,
$version,
$replacement
),
E_USER_DEPRECATED
);
} else {
trigger_error(
sprintf(
/* translators: 1: WordPress hook name, 2: version number */
__( 'Hook %1$s is deprecated since Contact Form 7 version %2$s with no alternative available.', 'contact-form-7' ),
$hook_name,
$version
),
E_USER_DEPRECATED
);
}
}
return apply_filters_ref_array( $hook_name, $args );
}
/**
* Marks something as being incorrectly called.
*
* @param string $function_name The function that was called.
* @param string $message A message explaining what has been done incorrectly.
* @param string $version The version of Contact Form 7 where the message
* was added.
*/
function wpcf7_doing_it_wrong( $function_name, $message, $version ) {
if ( WP_DEBUG ) {
if ( function_exists( '__' ) ) {
if ( $version ) {
$version = sprintf(
/* translators: %s: Contact Form 7 version number. */
__( '(This message was added in Contact Form 7 version %s.)', 'contact-form-7' ),
$version
);
}
trigger_error(
sprintf(
/* translators: Developer debugging message. 1: PHP function name, 2: Explanatory message, 3: Contact Form 7 version number. */
__( 'Function %1$s was called incorrectly. %2$s %3$s', 'contact-form-7' ),
$function_name,
$message,
$version
),
E_USER_NOTICE
);
} else {
if ( $version ) {
$version = sprintf(
'(This message was added in Contact Form 7 version %s.)',
$version
);
}
trigger_error(
sprintf(
'Function %1$s was called incorrectly. %2$s %3$s',
$function_name,
$message,
$version
),
E_USER_NOTICE
);
}
}
}
/**
* Triggers an error about a remote HTTP request and response.
*
* @param string $url The resource URL.
* @param array $request Request arguments.
* @param array|WP_Error $response The response or WP_Error on failure.
*/
function wpcf7_log_remote_request( $url, $request, $response ) {
$log = sprintf(
/* translators: 1: response code, 2: message, 3: body, 4: URL */
__( 'HTTP Response: %1$s %2$s %3$s from %4$s', 'contact-form-7' ),
(int) wp_remote_retrieve_response_code( $response ),
wp_remote_retrieve_response_message( $response ),
wp_remote_retrieve_body( $response ),
$url
);
$log = apply_filters( 'wpcf7_log_remote_request',
$log, $url, $request, $response
);
if ( $log ) {
trigger_error( $log );
}
}
/**
* Anonymizes an IP address by masking local part.
*
* @param string $ip_addr The original IP address.
* @return string|bool Anonymized IP address, or false on failure.
*/
function wpcf7_anonymize_ip_addr( $ip_addr ) {
if ( ! function_exists( 'inet_ntop' )
or ! function_exists( 'inet_pton' ) ) {
return $ip_addr;
}
$packed = inet_pton( $ip_addr );
if ( false === $packed ) {
return $ip_addr;
}
if ( 4 == strlen( $packed ) ) { // IPv4
$mask = '255.255.255.0';
} elseif ( 16 == strlen( $packed ) ) { // IPv6
$mask = 'ffff:ffff:ffff:0000:0000:0000:0000:0000';
} else {
return $ip_addr;
}
return inet_ntop( $packed & inet_pton( $mask ) );
}
/**
* Pipe-related classes.
*
* @link https://contactform7.com/selectable-recipient-with-pipes/
*/
/**
* Class representing a pair of pipe.
*/
class WPCF7_Pipe {
public $before = '';
public $after = '';
public function __construct( $text ) {
$text = (string) $text;
$pipe_pos = strpos( $text, '|' );
if ( false === $pipe_pos ) {
$this->before = $this->after = trim( $text );
} else {
$this->before = trim( substr( $text, 0, $pipe_pos ) );
$this->after = trim( substr( $text, $pipe_pos + 1 ) );
}
}
}
/**
* Class representing a list of pipes.
*/
class WPCF7_Pipes {
private $pipes = array();
public function __construct( array $texts ) {
foreach ( $texts as $text ) {
$this->add_pipe( $text );
}
}
private function add_pipe( $text ) {
$pipe = new WPCF7_Pipe( $text );
$this->pipes[] = $pipe;
}
public function do_pipe( $input ) {
$input_canonical = wpcf7_canonicalize( $input, array(
'strto' => 'as-is',
) );
foreach ( $this->pipes as $pipe ) {
$before_canonical = wpcf7_canonicalize( $pipe->before, array(
'strto' => 'as-is',
) );
if ( $input_canonical === $before_canonical ) {
return $pipe->after;
}
}
return $input;
}
public function collect_befores() {
$befores = array();
foreach ( $this->pipes as $pipe ) {
$befores[] = $pipe->before;
}
return $befores;
}
public function collect_afters() {
$afters = array();
foreach ( $this->pipes as $pipe ) {
$afters[] = $pipe->after;
}
return $afters;
}
public function zero() {
return empty( $this->pipes );
}
public function random_pipe() {
if ( $this->zero() ) {
return null;
}
return $this->pipes[array_rand( $this->pipes )];
}
public function to_array() {
return array_map(
static function ( WPCF7_Pipe $pipe ) {
return array(
$pipe->before,
$pipe->after,
);
},
$this->pipes
);
}
}
/**
* Handy trait provides methods to handle dynamic properties.
*/
trait WPCF7_PocketHolder {
protected $pocket = array();
public function pull( $key ) {
if ( isset( $this->pocket[$key] ) ) {
return $this->pocket[$key];
}
}
public function push( $key, $value ) {
$this->pocket[$key] = $value;
}
}
add_action(
'wp_enqueue_scripts',
static function () {
$assets = array();
$asset_file = wpcf7_plugin_path( 'includes/swv/js/index.asset.php' );
if ( file_exists( $asset_file ) ) {
$assets = include( $asset_file );
}
$assets = wp_parse_args( $assets, array(
'dependencies' => array(),
'version' => WPCF7_VERSION,
) );
wp_register_script( 'swv',
wpcf7_plugin_url( 'includes/swv/js/index.js' ),
$assets['dependencies'],
$assets['version'],
true
);
},
10, 0
);
/**
* Contact form helper functions
*/
/**
* Wrapper function of WPCF7_ContactForm::get_instance().
*
* @param WPCF7_ContactForm|WP_Post|int $post Object or post ID.
* @return WPCF7_ContactForm|null Contact form object. Null if unset.
*/
function wpcf7_contact_form( $post ) {
return WPCF7_ContactForm::get_instance( $post );
}
/**
* Searches for a contact form by an old unit ID.
*
* @param int $old_id Old unit ID.
* @return WPCF7_ContactForm Contact form object.
*/
function wpcf7_get_contact_form_by_old_id( $old_id ) {
global $wpdb;
$q = "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '_old_cf7_unit_id'"
. $wpdb->prepare( " AND meta_value = %d", $old_id );
if ( $new_id = $wpdb->get_var( $q ) ) {
return wpcf7_contact_form( $new_id );
}
}
/**
* Searches for a contact form by a hash string.
*
* @param string $hash Part of a hash string.
* @return WPCF7_ContactForm Contact form object.
*/
function wpcf7_get_contact_form_by_hash( $hash ) {
global $wpdb;
$hash = trim( $hash );
if ( strlen( $hash ) < 7 ) {
return null;
}
$like = $wpdb->esc_like( $hash ) . '%';
$q = "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '_hash'"
. $wpdb->prepare( " AND meta_value LIKE %s", $like );
if ( $post_id = $wpdb->get_var( $q ) ) {
return wpcf7_contact_form( $post_id );
}
}
/**
* Searches for a contact form by title.
*
* @param string $title Title of contact form.
* @return WPCF7_ContactForm|null Contact form object if found, null otherwise.
*/
function wpcf7_get_contact_form_by_title( $title ) {
if ( ! is_string( $title ) or '' === $title ) {
return null;
}
$contact_forms = WPCF7_ContactForm::find( array(
'title' => $title,
'posts_per_page' => 1,
) );
if ( $contact_forms ) {
return wpcf7_contact_form( reset( $contact_forms ) );
}
}
/**
* Wrapper function of WPCF7_ContactForm::get_current().
*
* @return WPCF7_ContactForm Contact form object.
*/
function wpcf7_get_current_contact_form() {
if ( $current = WPCF7_ContactForm::get_current() ) {
return $current;
}
}
/**
* Returns true if it is in the state that a non-Ajax submission is accepted.
*/
function wpcf7_is_posted() {
if ( ! $contact_form = wpcf7_get_current_contact_form() ) {
return false;
}
return $contact_form->is_posted();
}
/**
* Retrieves the user input value through a non-Ajax submission.
*
* @param string $name Name of form control.
* @param string $default_value Optional default value.
* @return string The user input value through the form-control.
*/
function wpcf7_get_hangover( $name, $default_value = null ) {
if ( ! wpcf7_is_posted() ) {
return $default_value;
}
$submission = WPCF7_Submission::get_instance();
if ( ! $submission
or $submission->is( 'mail_sent' ) ) {
return $default_value;
}
return isset( $_POST[$name] ) ? wp_unslash( $_POST[$name] ) : $default_value;
}
/**
* Retrieves an HTML snippet of validation error on the given form control.
*
* @param string $name Name of form control.
* @return string Validation error message in a form of HTML snippet.
*/
function wpcf7_get_validation_error( $name ) {
if ( ! $contact_form = wpcf7_get_current_contact_form() ) {
return '';
}
return $contact_form->validation_error( $name );
}
/**
* Returns a reference key to a validation error message.
*
* @param string $name Name of form control.
* @param string $unit_tag Optional. Unit tag of the contact form.
* @return string Reference key code.
*/
function wpcf7_get_validation_error_reference( $name, $unit_tag = '' ) {
if ( '' === $unit_tag ) {
$contact_form = wpcf7_get_current_contact_form();
if ( $contact_form and $contact_form->validation_error( $name ) ) {
$unit_tag = $contact_form->unit_tag();
} else {
return null;
}
}
return preg_replace( '/[^0-9a-z_-]+/i', '',
sprintf(
'%1$s-ve-%2$s',
$unit_tag,
$name
)
);
}
/**
* Retrieves a message for the given status.
*/
function wpcf7_get_message( $status ) {
if ( ! $contact_form = wpcf7_get_current_contact_form() ) {
return '';
}
return $contact_form->message( $status );
}
/**
* Returns a class names list for a form-tag of the specified type.
*
* @param string $type Form-tag type.
* @param string $default_classes Optional default classes.
* @return string Whitespace-separated list of class names.
*/
function wpcf7_form_controls_class( $type, $default_classes = '' ) {
$type = trim( $type );
if ( is_string( $default_classes ) ) {
$default_classes = explode( ' ', $default_classes );
}
$classes = array(
'wpcf7-form-control',
sprintf( 'wpcf7-%s', rtrim( $type, '*' ) ),
);
if ( str_ends_with( $type, '*' ) ) {
$classes[] = 'wpcf7-validates-as-required';
}
$classes = array_merge( $classes, $default_classes );
$classes = array_filter( array_unique( $classes ) );
return implode( ' ', $classes );
}
/**
* Callback function for the contact-form-7 shortcode.
*/
function wpcf7_contact_form_tag_func( $atts, $content = null, $code = '' ) {
if ( is_feed() ) {
return '[contact-form-7]';
}
if ( 'contact-form-7' === $code ) {
$atts = shortcode_atts(
array(
'id' => '',
'title' => '',
'html_id' => '',
'html_name' => '',
'html_title' => '',
'html_class' => '',
'output' => 'form',
),
$atts, 'wpcf7'
);
$id = trim( $atts['id'] );
$title = trim( $atts['title'] );
$contact_form = wpcf7_get_contact_form_by_hash( $id );
if ( ! $contact_form ) {
$contact_form = wpcf7_contact_form( $id );
}
if ( ! $contact_form ) {
$contact_form = wpcf7_get_contact_form_by_title( $title );
}
} else {
if ( is_string( $atts ) ) {
$atts = explode( ' ', $atts, 2 );
}
$id = (int) array_shift( $atts );
$contact_form = wpcf7_get_contact_form_by_old_id( $id );
}
if ( ! $contact_form ) {
return sprintf(
'
%1$s %2$s
',
esc_html( __( 'Error:', 'contact-form-7' ) ),
esc_html( __( "Contact form not found.", 'contact-form-7' ) )
);
}
$callback = static function ( $contact_form, $atts ) {
return $contact_form->form_html( $atts );
};
$output = wpcf7_switch_locale(
$contact_form->locale(),
$callback,
$contact_form, $atts
);
do_action( 'wpcf7_shortcode_callback', $contact_form, $atts );
return $output;
}
/**
* Saves the contact form data.
*/
function wpcf7_save_contact_form( $args = '', $context = 'save' ) {
$args = wp_parse_args( $args, array(
'id' => -1,
'title' => null,
'locale' => null,
'form' => null,
'mail' => null,
'mail_2' => null,
'messages' => null,
'additional_settings' => null,
) );
$args = wp_unslash( $args );
$args['id'] = (int) $args['id'];
if ( -1 == $args['id'] ) {
$contact_form = WPCF7_ContactForm::get_template();
} else {
$contact_form = wpcf7_contact_form( $args['id'] );
}
if ( empty( $contact_form ) ) {
return false;
}
if ( null !== $args['title'] ) {
$contact_form->set_title( $args['title'] );
}
if ( null !== $args['locale'] ) {
$contact_form->set_locale( $args['locale'] );
}
$properties = array();
if ( null !== $args['form'] ) {
$properties['form'] = wpcf7_sanitize_form( $args['form'] );
}
if ( null !== $args['mail'] ) {
$properties['mail'] = wpcf7_sanitize_mail( $args['mail'] );
$properties['mail']['active'] = true;
}
if ( null !== $args['mail_2'] ) {
$properties['mail_2'] = wpcf7_sanitize_mail( $args['mail_2'] );
}
if ( null !== $args['messages'] ) {
$properties['messages'] = wpcf7_sanitize_messages( $args['messages'] );
}
if ( null !== $args['additional_settings'] ) {
$properties['additional_settings'] = wpcf7_sanitize_additional_settings(
$args['additional_settings']
);
}
$contact_form->set_properties( $properties );
do_action( 'wpcf7_save_contact_form', $contact_form, $args, $context );
if ( 'save' == $context ) {
$contact_form->save();
}
return $contact_form;
}
/**
* Sanitizes the form property data.
*/
function wpcf7_sanitize_form( $input, $default_template = '' ) {
if ( null === $input ) {
return $default_template;
}
$output = trim( $input );
if ( ! current_user_can( 'unfiltered_html' ) ) {
$output = wpcf7_kses( $output, 'form' );
}
return $output;
}
/**
* Sanitizes the mail property data.
*/
function wpcf7_sanitize_mail( $input, $defaults = array() ) {
$input = wp_parse_args( $input, array(
'active' => false,
'subject' => '',
'sender' => '',
'recipient' => '',
'body' => '',
'additional_headers' => '',
'attachments' => '',
'use_html' => false,
'exclude_blank' => false,
) );
$input = wp_parse_args( $input, $defaults );
$output = array();
$output['active'] = (bool) $input['active'];
$output['subject'] = trim( $input['subject'] );
$output['sender'] = trim( $input['sender'] );
$output['recipient'] = trim( $input['recipient'] );
$output['body'] = trim( $input['body'] );
if ( ! current_user_can( 'unfiltered_html' ) ) {
$output['body'] = wpcf7_kses( $output['body'], 'mail' );
}
$output['additional_headers'] = '';
$headers = str_replace( "\r\n", "\n", $input['additional_headers'] );
$headers = explode( "\n", $headers );
foreach ( $headers as $header ) {
$header = trim( $header );
if ( '' !== $header ) {
$output['additional_headers'] .= $header . "\n";
}
}
$output['additional_headers'] = trim( $output['additional_headers'] );
$output['attachments'] = trim( $input['attachments'] );
$output['use_html'] = (bool) $input['use_html'];
$output['exclude_blank'] = (bool) $input['exclude_blank'];
return $output;
}
/**
* Sanitizes the messages property data.
*/
function wpcf7_sanitize_messages( $input, $defaults = array() ) {
$output = array();
foreach ( wpcf7_messages() as $key => $val ) {
if ( isset( $input[$key] ) ) {
$output[$key] = trim( $input[$key] );
} elseif ( isset( $defaults[$key] ) ) {
$output[$key] = $defaults[$key];
}
}
return $output;
}
/**
* Sanitizes the additional settings property data.
*/
function wpcf7_sanitize_additional_settings( $input, $default_template = '' ) {
if ( null === $input ) {
return $default_template;
}
$output = trim( $input );
return $output;
}
/**
* Generates a random hash string for a contact form.
*
* @param int $post_id Post ID.
* @return string SHA-1 hash.
*/
function wpcf7_generate_contact_form_hash( $post_id ) {
return sha1( implode( '|', array(
get_current_user_id(),
$post_id,
time(),
home_url(),
) ) );
}
class WPCF7_ContactForm {
use WPCF7_SWV_SchemaHolder;
const post_type = 'wpcf7_contact_form';
private static $found_items = 0;
private static $current = null;
private $id;
private $name;
private $title;
private $locale;
private $properties = array();
private $unit_tag;
private $responses_count = 0;
private $scanned_form_tags;
private $shortcode_atts = array();
private $hash = '';
/**
* Returns count of contact forms found by the previous retrieval.
*
* @return int Count of contact forms.
*/
public static function count() {
return self::$found_items;
}
/**
* Returns the contact form that is currently processed.
*
* @return WPCF7_ContactForm|null Current contact form object. Null if unset.
*/
public static function get_current() {
return self::$current;
}
/**
* Registers the post type for contact forms.
*/
public static function register_post_type() {
register_post_type( self::post_type, array(
'labels' => array(
'name' => __( 'Contact Forms', 'contact-form-7' ),
'singular_name' => __( 'Contact Form', 'contact-form-7' ),
),
'rewrite' => false,
'query_var' => false,
'public' => false,
'capability_type' => 'page',
'capabilities' => array(
'edit_post' => 'wpcf7_edit_contact_form',
'read_post' => 'wpcf7_read_contact_form',
'delete_post' => 'wpcf7_delete_contact_form',
'edit_posts' => 'wpcf7_edit_contact_forms',
'edit_others_posts' => 'wpcf7_edit_contact_forms',
'publish_posts' => 'wpcf7_edit_contact_forms',
'read_private_posts' => 'wpcf7_edit_contact_forms',
),
) );
}
/**
* Retrieves contact form data that match given conditions.
*
* @param string|array $args Optional. Arguments to be passed to WP_Query.
* @return array Array of WPCF7_ContactForm objects.
*/
public static function find( $args = '' ) {
$defaults = array(
'post_status' => 'any',
'posts_per_page' => -1,
'offset' => 0,
'orderby' => 'ID',
'order' => 'ASC',
);
$args = wp_parse_args( $args, $defaults );
$args['post_type'] = self::post_type;
$q = new WP_Query();
$posts = $q->query( $args );
self::$found_items = $q->found_posts;
$objs = array();
foreach ( (array) $posts as $post ) {
$objs[] = new self( $post );
}
return $objs;
}
/**
* Returns a contact form data filled by default template contents.
*
* @param string|array $args Optional. Contact form options.
* @return WPCF7_ContactForm A new contact form object.
*/
public static function get_template( $args = '' ) {
$args = wp_parse_args( $args, array(
'locale' => null,
'title' => __( 'Untitled', 'contact-form-7' ),
) );
if ( ! isset( $args['locale'] ) ) {
$args['locale'] = determine_locale();
}
$callback = static function ( $args ) {
$contact_form = new self;
$contact_form->title = $args['title'];
$contact_form->locale = $args['locale'];
$properties = $contact_form->get_properties();
foreach ( $properties as $key => $value ) {
$default_template = WPCF7_ContactFormTemplate::get_default( $key );
if ( isset( $default_template ) ) {
$properties[$key] = $default_template;
}
}
$contact_form->properties = $properties;
return $contact_form;
};
$contact_form = wpcf7_switch_locale(
$args['locale'],
$callback,
$args
);
self::$current = apply_filters( 'wpcf7_contact_form_default_pack',
$contact_form, $args
);
return self::$current;
}
/**
* Creates a WPCF7_ContactForm object and sets it as the current instance.
*
* @param WPCF7_ContactForm|WP_Post|int $post Object or post ID.
* @return WPCF7_ContactForm|null Contact form object. Null if unset.
*/
public static function get_instance( $post ) {
$contact_form = null;
if ( $post instanceof self ) {
$contact_form = $post;
} elseif ( ! empty( $post ) ) {
$post = get_post( $post );
if ( isset( $post ) and self::post_type === get_post_type( $post ) ) {
$contact_form = new self( $post );
}
}
return self::$current = $contact_form;
}
/**
* Generates a "unit-tag" for the given contact form ID.
*
* @return string Unit-tag.
*/
private static function generate_unit_tag( $id = 0 ) {
static $global_count = 0;
$global_count += 1;
if ( in_the_loop() ) {
$unit_tag = sprintf( 'wpcf7-f%1$d-p%2$d-o%3$d',
absint( $id ),
get_the_ID(),
$global_count
);
} else {
$unit_tag = sprintf( 'wpcf7-f%1$d-o%2$d',
absint( $id ),
$global_count
);
}
return $unit_tag;
}
/**
* Constructor.
*/
private function __construct( $post = null ) {
$post = get_post( $post );
if ( $post
and self::post_type === get_post_type( $post ) ) {
$this->id = $post->ID;
$this->name = $post->post_name;
$this->title = $post->post_title;
$this->locale = get_post_meta( $post->ID, '_locale', true );
$this->hash = get_post_meta( $post->ID, '_hash', true );
$this->construct_properties( $post );
$this->upgrade();
} else {
$this->construct_properties();
}
do_action( 'wpcf7_contact_form', $this );
}
/**
* Magic method for property overloading.
*/
public function __get( $name ) {
$message = __( '%1$s property of a WPCF7_ContactForm object is no longer accessible. Use %2$s method instead.', 'contact-form-7' );
if ( 'id' == $name ) {
if ( WP_DEBUG ) {
trigger_error(
sprintf( $message, 'id', 'id()' ),
E_USER_DEPRECATED
);
}
return $this->id;
} elseif ( 'title' == $name ) {
if ( WP_DEBUG ) {
trigger_error(
sprintf( $message, 'title', 'title()' ),
E_USER_DEPRECATED
);
}
return $this->title;
} elseif ( $prop = $this->prop( $name ) ) {
if ( WP_DEBUG ) {
trigger_error(
sprintf( $message, $name, 'prop(\'' . $name . '\')' ),
E_USER_DEPRECATED
);
}
return $prop;
}
}
/**
* Returns true if this contact form is not yet saved to the database.
*/
public function initial() {
return empty( $this->id );
}
/**
* Constructs contact form properties. This is called only once
* from the constructor.
*/
private function construct_properties( $post = null ) {
$builtin_properties = array(
'form' => '',
'mail' => array(),
'mail_2' => array(),
'messages' => array(),
'additional_settings' => '',
);
$properties = apply_filters(
'wpcf7_pre_construct_contact_form_properties',
$builtin_properties, $this
);
// Filtering out properties with invalid name
$properties = array_filter(
$properties,
static function ( $key ) {
$sanitized_key = sanitize_key( $key );
return $key === $sanitized_key;
},
ARRAY_FILTER_USE_KEY
);
foreach ( $properties as $name => $val ) {
$prop = $this->retrieve_property( $name );
if ( isset( $prop ) ) {
$properties[$name] = $prop;
}
}
$this->properties = $properties;
foreach ( $properties as $name => $val ) {
$properties[$name] = apply_filters(
"wpcf7_contact_form_property_{$name}",
$val, $this
);
}
$this->properties = $properties;
$properties = (array) apply_filters(
'wpcf7_contact_form_properties',
$properties, $this
);
$this->properties = $properties;
}
/**
* Retrieves contact form property of the specified name from the database.
*
* @param string $name Property name.
* @return array|string|null Property value. Null if property does not exist.
*/
private function retrieve_property( $name ) {
$property = null;
if ( ! $this->initial() ) {
$post_id = $this->id;
if ( metadata_exists( 'post', $post_id, '_' . $name ) ) {
$property = get_post_meta( $post_id, '_' . $name, true );
} elseif ( metadata_exists( 'post', $post_id, $name ) ) {
$property = get_post_meta( $post_id, $name, true );
}
}
return $property;
}
/**
* Returns the value for the given property name.
*
* @param string $name Property name.
* @return array|string|null Property value. Null if property does not exist.
*/
public function prop( $name ) {
$props = $this->get_properties();
return isset( $props[$name] ) ? $props[$name] : null;
}
/**
* Returns all the properties.
*
* @return array This contact form's properties.
*/
public function get_properties() {
return (array) $this->properties;
}
/**
* Updates properties.
*
* @param array $properties New properties.
*/
public function set_properties( $properties ) {
$defaults = $this->get_properties();
$properties = wp_parse_args( $properties, $defaults );
$properties = array_intersect_key( $properties, $defaults );
$this->properties = $properties;
}
/**
* Returns ID of this contact form.
*
* @return int The ID.
*/
public function id() {
return $this->id;
}
/**
* Returns unit-tag for this contact form.
*
* @return string Unit-tag.
*/
public function unit_tag() {
return $this->unit_tag;
}
/**
* Returns name (slug) of this contact form.
*
* @return string Name.
*/
public function name() {
return $this->name;
}
/**
* Returns title of this contact form.
*
* @return string Title.
*/
public function title() {
return $this->title;
}
/**
* Set a title for this contact form.
*
* @param string $title Title.
*/
public function set_title( $title ) {
$title = strip_tags( $title );
$title = trim( $title );
if ( '' === $title ) {
$title = __( 'Untitled', 'contact-form-7' );
}
$this->title = $title;
}
/**
* Returns the locale code of this contact form.
*
* @return string Locale code. Empty string if no valid locale is set.
*/
public function locale() {
if ( wpcf7_is_valid_locale( $this->locale ) ) {
return $this->locale;
} else {
return '';
}
}
/**
* Sets a locale for this contact form.
*
* @param string $locale Locale code.
*/
public function set_locale( $locale ) {
$locale = trim( $locale );
if ( wpcf7_is_valid_locale( $locale ) ) {
$this->locale = $locale;
} else {
$this->locale = 'en_US';
}
}
/**
* Retrieves the random hash string tied to this contact form.
*
* @param int $length Length of hash string.
* @return string Hash string unique to this contact form.
*/
public function hash( $length = 7 ) {
return substr( $this->hash, 0, absint( $length ) );
}
/**
* Returns the specified shortcode attribute value.
*
* @param string $name Shortcode attribute name.
* @return string|null Attribute value. Null if the attribute does not exist.
*/
public function shortcode_attr( $name ) {
if ( isset( $this->shortcode_atts[$name] ) ) {
return (string) $this->shortcode_atts[$name];
}
}
/**
* Returns true if this contact form is identical to the submitted one.
*/
public function is_posted() {
if ( ! WPCF7_Submission::get_instance() ) {
return false;
}
if ( empty( $_POST['_wpcf7_unit_tag'] ) ) {
return false;
}
return $this->unit_tag() === $_POST['_wpcf7_unit_tag'];
}
/**
* Generates HTML that represents a form.
*
* @param string|array $args Optional. Form options.
* @return string HTML output.
*/
public function form_html( $args = '' ) {
$args = wp_parse_args( $args, array(
'html_id' => '',
'html_name' => '',
'html_title' => '',
'html_class' => '',
'output' => 'form',
) );
$this->shortcode_atts = $args;
if ( 'raw_form' == $args['output'] ) {
return sprintf(
'
%s
',
esc_html( $this->prop( 'form' ) )
);
}
if ( $this->is_true( 'subscribers_only' )
and ! current_user_can( 'wpcf7_submit', $this->id() ) ) {
$notice = __(
"This contact form is available only for logged in users.",
'contact-form-7'
);
$notice = sprintf(
'