Auto commit: 2026-01-22T15:17:14.589Z
150
.htaccess
@ -1,3 +1,153 @@
|
||||
# BEGIN W3TC Browser Cache
|
||||
<IfModule mod_mime.c>
|
||||
AddType text/css .css
|
||||
AddType text/x-component .htc
|
||||
AddType application/x-javascript .js
|
||||
AddType application/javascript .js2
|
||||
AddType text/javascript .js3
|
||||
AddType text/x-js .js4
|
||||
AddType video/asf .asf .asx .wax .wmv .wmx
|
||||
AddType video/avi .avi
|
||||
AddType image/avif .avif
|
||||
AddType image/avif-sequence .avifs
|
||||
AddType image/bmp .bmp
|
||||
AddType application/java .class
|
||||
AddType video/divx .divx
|
||||
AddType application/msword .doc .docx
|
||||
AddType application/vnd.ms-fontobject .eot
|
||||
AddType application/x-msdownload .exe
|
||||
AddType image/gif .gif
|
||||
AddType application/x-gzip .gz .gzip
|
||||
AddType image/x-icon .ico
|
||||
AddType image/jpeg .jpg .jpeg .jpe
|
||||
AddType image/webp .webp
|
||||
AddType application/json .json
|
||||
AddType application/vnd.ms-access .mdb
|
||||
AddType audio/midi .mid .midi
|
||||
AddType video/quicktime .mov .qt
|
||||
AddType audio/mpeg .mp3 .m4a
|
||||
AddType video/mp4 .mp4 .m4v
|
||||
AddType video/mpeg .mpeg .mpg .mpe
|
||||
AddType video/webm .webm
|
||||
AddType application/vnd.ms-project .mpp
|
||||
AddType application/x-font-otf .otf
|
||||
AddType application/vnd.ms-opentype ._otf
|
||||
AddType application/vnd.oasis.opendocument.database .odb
|
||||
AddType application/vnd.oasis.opendocument.chart .odc
|
||||
AddType application/vnd.oasis.opendocument.formula .odf
|
||||
AddType application/vnd.oasis.opendocument.graphics .odg
|
||||
AddType application/vnd.oasis.opendocument.presentation .odp
|
||||
AddType application/vnd.oasis.opendocument.spreadsheet .ods
|
||||
AddType application/vnd.oasis.opendocument.text .odt
|
||||
AddType audio/ogg .ogg
|
||||
AddType video/ogg .ogv
|
||||
AddType application/pdf .pdf
|
||||
AddType image/png .png
|
||||
AddType application/vnd.ms-powerpoint .pot .pps .ppt .pptx
|
||||
AddType audio/x-realaudio .ra .ram
|
||||
AddType image/svg+xml .svg .svgz
|
||||
AddType application/x-shockwave-flash .swf
|
||||
AddType application/x-tar .tar
|
||||
AddType image/tiff .tif .tiff
|
||||
AddType application/x-font-ttf .ttf .ttc
|
||||
AddType application/vnd.ms-opentype ._ttf
|
||||
AddType audio/wav .wav
|
||||
AddType audio/wma .wma
|
||||
AddType application/vnd.ms-write .wri
|
||||
AddType application/font-woff .woff
|
||||
AddType application/font-woff2 .woff2
|
||||
AddType application/vnd.ms-excel .xla .xls .xlsx .xlt .xlw
|
||||
AddType application/zip .zip
|
||||
</IfModule>
|
||||
<IfModule mod_expires.c>
|
||||
ExpiresActive On
|
||||
ExpiresByType text/css A31536000
|
||||
ExpiresByType text/x-component A31536000
|
||||
ExpiresByType application/x-javascript A31536000
|
||||
ExpiresByType application/javascript A31536000
|
||||
ExpiresByType text/javascript A31536000
|
||||
ExpiresByType text/x-js A31536000
|
||||
ExpiresByType video/asf A31536000
|
||||
ExpiresByType video/avi A31536000
|
||||
ExpiresByType image/avif A31536000
|
||||
ExpiresByType image/avif-sequence A31536000
|
||||
ExpiresByType image/bmp A31536000
|
||||
ExpiresByType application/java A31536000
|
||||
ExpiresByType video/divx A31536000
|
||||
ExpiresByType application/msword A31536000
|
||||
ExpiresByType application/vnd.ms-fontobject A31536000
|
||||
ExpiresByType application/x-msdownload A31536000
|
||||
ExpiresByType image/gif A31536000
|
||||
ExpiresByType application/x-gzip A31536000
|
||||
ExpiresByType image/x-icon A31536000
|
||||
ExpiresByType image/jpeg A31536000
|
||||
ExpiresByType image/webp A31536000
|
||||
ExpiresByType application/json A31536000
|
||||
ExpiresByType application/vnd.ms-access A31536000
|
||||
ExpiresByType audio/midi A31536000
|
||||
ExpiresByType video/quicktime A31536000
|
||||
ExpiresByType audio/mpeg A31536000
|
||||
ExpiresByType video/mp4 A31536000
|
||||
ExpiresByType video/mpeg A31536000
|
||||
ExpiresByType video/webm A31536000
|
||||
ExpiresByType application/vnd.ms-project A31536000
|
||||
ExpiresByType application/x-font-otf A31536000
|
||||
ExpiresByType application/vnd.ms-opentype A31536000
|
||||
ExpiresByType application/vnd.oasis.opendocument.database A31536000
|
||||
ExpiresByType application/vnd.oasis.opendocument.chart A31536000
|
||||
ExpiresByType application/vnd.oasis.opendocument.formula A31536000
|
||||
ExpiresByType application/vnd.oasis.opendocument.graphics A31536000
|
||||
ExpiresByType application/vnd.oasis.opendocument.presentation A31536000
|
||||
ExpiresByType application/vnd.oasis.opendocument.spreadsheet A31536000
|
||||
ExpiresByType application/vnd.oasis.opendocument.text A31536000
|
||||
ExpiresByType audio/ogg A31536000
|
||||
ExpiresByType video/ogg A31536000
|
||||
ExpiresByType application/pdf A31536000
|
||||
ExpiresByType image/png A31536000
|
||||
ExpiresByType application/vnd.ms-powerpoint A31536000
|
||||
ExpiresByType audio/x-realaudio A31536000
|
||||
ExpiresByType image/svg+xml A31536000
|
||||
ExpiresByType application/x-shockwave-flash A31536000
|
||||
ExpiresByType application/x-tar A31536000
|
||||
ExpiresByType image/tiff A31536000
|
||||
ExpiresByType application/x-font-ttf A31536000
|
||||
ExpiresByType application/vnd.ms-opentype A31536000
|
||||
ExpiresByType audio/wav A31536000
|
||||
ExpiresByType audio/wma A31536000
|
||||
ExpiresByType application/vnd.ms-write A31536000
|
||||
ExpiresByType application/font-woff A31536000
|
||||
ExpiresByType application/font-woff2 A31536000
|
||||
ExpiresByType application/vnd.ms-excel A31536000
|
||||
ExpiresByType application/zip A31536000
|
||||
</IfModule>
|
||||
<IfModule mod_deflate.c>
|
||||
<IfModule mod_filter.c>
|
||||
AddOutputFilterByType DEFLATE text/css text/x-component application/x-javascript application/javascript text/javascript text/x-js text/html text/richtext text/plain text/xsd text/xsl text/xml image/bmp application/java application/msword application/vnd.ms-fontobject application/x-msdownload image/x-icon application/json application/vnd.ms-access video/webm application/vnd.ms-project application/x-font-otf application/vnd.ms-opentype application/vnd.oasis.opendocument.database application/vnd.oasis.opendocument.chart application/vnd.oasis.opendocument.formula application/vnd.oasis.opendocument.graphics application/vnd.oasis.opendocument.presentation application/vnd.oasis.opendocument.spreadsheet application/vnd.oasis.opendocument.text audio/ogg application/pdf application/vnd.ms-powerpoint image/svg+xml application/x-shockwave-flash image/tiff application/x-font-ttf application/vnd.ms-opentype audio/wav application/vnd.ms-write application/font-woff application/font-woff2 application/vnd.ms-excel
|
||||
<IfModule mod_mime.c>
|
||||
# DEFLATE by extension
|
||||
AddOutputFilter DEFLATE js css htm html xml
|
||||
</IfModule>
|
||||
</IfModule>
|
||||
</IfModule>
|
||||
<FilesMatch "\.(css|htc|less|js|js2|js3|js4|CSS|HTC|LESS|JS|JS2|JS3|JS4)$">
|
||||
FileETag MTime Size
|
||||
<IfModule mod_headers.c>
|
||||
Header unset Set-Cookie
|
||||
</IfModule>
|
||||
</FilesMatch>
|
||||
<FilesMatch "\.(html|htm|rtf|rtx|txt|xsd|xsl|xml|HTML|HTM|RTF|RTX|TXT|XSD|XSL|XML)$">
|
||||
FileETag MTime Size
|
||||
</FilesMatch>
|
||||
<FilesMatch "\.(asf|asx|wax|wmv|wmx|avi|avif|avifs|bmp|class|divx|doc|docx|eot|exe|gif|gz|gzip|ico|jpg|jpeg|jpe|webp|json|mdb|mid|midi|mov|qt|mp3|m4a|mp4|m4v|mpeg|mpg|mpe|webm|mpp|otf|_otf|odb|odc|odf|odg|odp|ods|odt|ogg|ogv|pdf|png|pot|pps|ppt|pptx|ra|ram|svg|svgz|swf|tar|tif|tiff|ttf|ttc|_ttf|wav|wma|wri|woff|woff2|xla|xls|xlsx|xlt|xlw|zip|ASF|ASX|WAX|WMV|WMX|AVI|AVIF|AVIFS|BMP|CLASS|DIVX|DOC|DOCX|EOT|EXE|GIF|GZ|GZIP|ICO|JPG|JPEG|JPE|WEBP|JSON|MDB|MID|MIDI|MOV|QT|MP3|M4A|MP4|M4V|MPEG|MPG|MPE|WEBM|MPP|OTF|_OTF|ODB|ODC|ODF|ODG|ODP|ODS|ODT|OGG|OGV|PDF|PNG|POT|PPS|PPT|PPTX|RA|RAM|SVG|SVGZ|SWF|TAR|TIF|TIFF|TTF|TTC|_TTF|WAV|WMA|WRI|WOFF|WOFF2|XLA|XLS|XLSX|XLT|XLW|ZIP)$">
|
||||
FileETag MTime Size
|
||||
<IfModule mod_headers.c>
|
||||
Header unset Set-Cookie
|
||||
</IfModule>
|
||||
</FilesMatch>
|
||||
<IfModule mod_headers.c>
|
||||
Header set Referrer-Policy "no-referrer-when-downgrade"
|
||||
</IfModule>
|
||||
# END W3TC Browser Cache
|
||||
# BEGIN WordPress
|
||||
<IfModule mod_rewrite.c>
|
||||
RewriteEngine On
|
||||
|
||||
@ -1,4 +1,7 @@
|
||||
<?php
|
||||
/** Enable W3 Total Cache */
|
||||
define('WP_CACHE', true); // Added by W3 Total Cache
|
||||
|
||||
if ( defined( 'WP_CLI' ) ) {
|
||||
$_SERVER['HTTP_HOST'] = 'localhost';
|
||||
}
|
||||
|
||||
46
wp-content/advanced-cache.php
Normal file
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
/**
|
||||
* File: advanced-cache.php
|
||||
*
|
||||
* W3 Total Cache advanced cache module.
|
||||
*
|
||||
* @package W3TC
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || die();
|
||||
|
||||
global $w3tc_start_microtime;
|
||||
$w3tc_start_microtime = microtime( true );
|
||||
|
||||
/**
|
||||
* Abort W3TC loading if WordPress is upgrading.
|
||||
*/
|
||||
if ( defined( 'WP_INSTALLING' ) && WP_INSTALLING ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! defined( 'W3TC_IN_MINIFY' ) ) {
|
||||
if ( ! defined( 'W3TC_DIR' ) ) {
|
||||
define( 'W3TC_DIR', ( defined( 'WP_PLUGIN_DIR' ) ? WP_PLUGIN_DIR : WP_CONTENT_DIR . '/plugins' ) . '/w3-total-cache' );
|
||||
}
|
||||
|
||||
if ( ! @is_dir( W3TC_DIR ) || ! file_exists( W3TC_DIR . '/w3-total-cache-api.php' ) ) {
|
||||
if ( defined( 'WP_ADMIN' ) ) {
|
||||
// Only display errors in wp-admin.
|
||||
printf( '<strong>W3 Total Cache Error:</strong> some files appear to be missing or out of place. Please re-install plugin or remove <strong>%s</strong>. <br />', __FILE__ );
|
||||
}
|
||||
} else {
|
||||
require_once W3TC_DIR . '/w3-total-cache-api.php';
|
||||
|
||||
if ( class_exists( '\W3TC\Dispatcher' ) ) {
|
||||
$w3tc_redirect = \W3TC\Dispatcher::component( 'Mobile_Redirect' );
|
||||
$w3tc_redirect->process();
|
||||
|
||||
$w3tc_config = \W3TC\Dispatcher::config();
|
||||
if ( $w3tc_config->get_boolean( 'pgcache.enabled' ) ) {
|
||||
$o = \W3TC\Dispatcher::component( 'PgCache_ContentGrabber' );
|
||||
$o->process();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
0
wp-content/cache/index.html
vendored
Normal file
759
wp-content/plugins/contact-form-7/admin/admin.php
Normal file
@ -0,0 +1,759 @@
|
||||
<?php
|
||||
|
||||
require_once WPCF7_PLUGIN_DIR . '/admin/includes/admin-functions.php';
|
||||
require_once WPCF7_PLUGIN_DIR . '/admin/includes/help-tabs.php';
|
||||
require_once WPCF7_PLUGIN_DIR . '/admin/includes/tag-generator.php';
|
||||
require_once WPCF7_PLUGIN_DIR . '/admin/includes/welcome-panel.php';
|
||||
require_once WPCF7_PLUGIN_DIR . '/admin/includes/config-validator.php';
|
||||
|
||||
|
||||
add_action(
|
||||
'admin_init',
|
||||
static function () {
|
||||
do_action( 'wpcf7_admin_init' );
|
||||
},
|
||||
10, 0
|
||||
);
|
||||
|
||||
|
||||
add_action(
|
||||
'admin_menu',
|
||||
'wpcf7_admin_menu',
|
||||
9, 0
|
||||
);
|
||||
|
||||
function wpcf7_admin_menu() {
|
||||
do_action( 'wpcf7_admin_menu' );
|
||||
|
||||
add_menu_page(
|
||||
__( 'Contact Form 7', 'contact-form-7' ),
|
||||
__( 'Contact', 'contact-form-7' )
|
||||
. wpcf7_admin_menu_change_notice(),
|
||||
'wpcf7_read_contact_forms',
|
||||
'wpcf7',
|
||||
'wpcf7_admin_management_page',
|
||||
'dashicons-email',
|
||||
30
|
||||
);
|
||||
|
||||
$edit = add_submenu_page( 'wpcf7',
|
||||
__( 'Edit Contact Form', 'contact-form-7' ),
|
||||
__( 'Contact Forms', 'contact-form-7' )
|
||||
. wpcf7_admin_menu_change_notice( 'wpcf7' ),
|
||||
'wpcf7_read_contact_forms',
|
||||
'wpcf7',
|
||||
'wpcf7_admin_management_page'
|
||||
);
|
||||
|
||||
add_action( 'load-' . $edit, 'wpcf7_load_contact_form_admin', 10, 0 );
|
||||
|
||||
$addnew = add_submenu_page( 'wpcf7',
|
||||
__( 'Add Contact Form', 'contact-form-7' ),
|
||||
__( 'Add Contact Form', 'contact-form-7' )
|
||||
. wpcf7_admin_menu_change_notice( 'wpcf7-new' ),
|
||||
'wpcf7_edit_contact_forms',
|
||||
'wpcf7-new',
|
||||
'wpcf7_admin_add_new_page'
|
||||
);
|
||||
|
||||
add_action( 'load-' . $addnew, 'wpcf7_load_contact_form_admin', 10, 0 );
|
||||
|
||||
$integration = WPCF7_Integration::get_instance();
|
||||
|
||||
if ( $integration->service_exists() ) {
|
||||
$integration = add_submenu_page( 'wpcf7',
|
||||
__( 'Integration with External API', 'contact-form-7' ),
|
||||
__( 'Integration', 'contact-form-7' )
|
||||
. wpcf7_admin_menu_change_notice( 'wpcf7-integration' ),
|
||||
'wpcf7_manage_integration',
|
||||
'wpcf7-integration',
|
||||
'wpcf7_admin_integration_page'
|
||||
);
|
||||
|
||||
add_action( 'load-' . $integration, 'wpcf7_load_integration_page', 10, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function wpcf7_admin_menu_change_notice( $menu_slug = '' ) {
|
||||
$counts = apply_filters( 'wpcf7_admin_menu_change_notice',
|
||||
array(
|
||||
'wpcf7' => 0,
|
||||
'wpcf7-new' => 0,
|
||||
'wpcf7-integration' => 0,
|
||||
)
|
||||
);
|
||||
|
||||
if ( empty( $menu_slug ) ) {
|
||||
$count = absint( array_sum( $counts ) );
|
||||
} elseif ( isset( $counts[$menu_slug] ) ) {
|
||||
$count = absint( $counts[$menu_slug] );
|
||||
} else {
|
||||
$count = 0;
|
||||
}
|
||||
|
||||
if ( $count ) {
|
||||
return sprintf(
|
||||
' <span class="update-plugins %1$d"><span class="plugin-count">%2$s</span></span>',
|
||||
$count,
|
||||
esc_html( number_format_i18n( $count ) )
|
||||
);
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
|
||||
add_action(
|
||||
'admin_enqueue_scripts',
|
||||
'wpcf7_admin_enqueue_scripts',
|
||||
10, 1
|
||||
);
|
||||
|
||||
function wpcf7_admin_enqueue_scripts( $hook_suffix ) {
|
||||
if ( false === strpos( $hook_suffix, 'wpcf7' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
wp_enqueue_style( 'contact-form-7-admin',
|
||||
wpcf7_plugin_url( 'admin/includes/css/styles.css' ),
|
||||
array(), WPCF7_VERSION, 'all'
|
||||
);
|
||||
|
||||
if ( wpcf7_is_rtl() ) {
|
||||
wp_enqueue_style( 'contact-form-7-admin-rtl',
|
||||
wpcf7_plugin_url( 'admin/includes/css/styles-rtl.css' ),
|
||||
array(), WPCF7_VERSION, 'all'
|
||||
);
|
||||
}
|
||||
|
||||
$assets = include wpcf7_plugin_path( 'admin/includes/js/index.asset.php' );
|
||||
|
||||
$assets = wp_parse_args( $assets, array(
|
||||
'dependencies' => array(),
|
||||
'version' => WPCF7_VERSION,
|
||||
) );
|
||||
|
||||
wp_enqueue_script( 'wpcf7-admin',
|
||||
wpcf7_plugin_url( 'admin/includes/js/index.js' ),
|
||||
$assets['dependencies'],
|
||||
$assets['version'],
|
||||
array( 'in_footer' => true )
|
||||
);
|
||||
|
||||
wp_set_script_translations( 'wpcf7-admin', 'contact-form-7' );
|
||||
|
||||
$wpcf7_obj = array(
|
||||
'apiSettings' => array(
|
||||
'root' => sanitize_url( rest_url( 'contact-form-7/v1' ) ),
|
||||
'namespace' => 'contact-form-7/v1',
|
||||
),
|
||||
);
|
||||
|
||||
$post = wpcf7_get_current_contact_form();
|
||||
|
||||
if ( $post ) {
|
||||
$wpcf7_obj = array_merge( $wpcf7_obj, array(
|
||||
'nonce' => array(
|
||||
'save' => wp_create_nonce(
|
||||
sprintf(
|
||||
'wpcf7-save-contact-form_%s',
|
||||
$post->initial() ? -1 : $post->id()
|
||||
)
|
||||
),
|
||||
'copy' => wp_create_nonce(
|
||||
sprintf(
|
||||
'wpcf7-copy-contact-form_%s',
|
||||
$post->initial() ? -1 : $post->id()
|
||||
)
|
||||
),
|
||||
'delete' => wp_create_nonce(
|
||||
sprintf(
|
||||
'wpcf7-delete-contact-form_%s',
|
||||
$post->initial() ? -1 : $post->id()
|
||||
)
|
||||
),
|
||||
),
|
||||
'configValidator' => array(
|
||||
'errors' => array(),
|
||||
'docUrl' => WPCF7_ConfigValidator::get_doc_link(),
|
||||
),
|
||||
) );
|
||||
|
||||
if (
|
||||
current_user_can( 'wpcf7_edit_contact_form', $post->id() ) and
|
||||
wpcf7_validate_configuration()
|
||||
) {
|
||||
$config_validator = new WPCF7_ConfigValidator( $post );
|
||||
$config_validator->restore();
|
||||
|
||||
$wpcf7_obj['configValidator'] = array_merge(
|
||||
$wpcf7_obj['configValidator'],
|
||||
array(
|
||||
'errors' => $config_validator->collect_error_messages(
|
||||
array( 'decodes_html_entities' => true )
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
wp_add_inline_script( 'wpcf7-admin',
|
||||
sprintf(
|
||||
'var wpcf7 = %s;',
|
||||
wp_json_encode( $wpcf7_obj, JSON_PRETTY_PRINT )
|
||||
),
|
||||
'before'
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
add_filter(
|
||||
'set_screen_option_wpcf7_contact_forms_per_page',
|
||||
static function ( $result, $option, $value ) {
|
||||
$wpcf7_screens = array(
|
||||
'wpcf7_contact_forms_per_page',
|
||||
);
|
||||
|
||||
if ( in_array( $option, $wpcf7_screens, true ) ) {
|
||||
$result = $value;
|
||||
}
|
||||
|
||||
return $result;
|
||||
},
|
||||
10, 3
|
||||
);
|
||||
|
||||
|
||||
function wpcf7_load_contact_form_admin() {
|
||||
global $plugin_page;
|
||||
|
||||
$action = wpcf7_current_action();
|
||||
|
||||
do_action( 'wpcf7_admin_load',
|
||||
wpcf7_superglobal_get( 'page' ),
|
||||
$action
|
||||
);
|
||||
|
||||
if ( 'save' === $action ) {
|
||||
$id = wpcf7_superglobal_post( 'post_ID', '-1' );
|
||||
|
||||
check_admin_referer( 'wpcf7-save-contact-form_' . $id );
|
||||
|
||||
if ( ! current_user_can( 'wpcf7_edit_contact_form', $id ) ) {
|
||||
wp_die(
|
||||
esc_html( __( 'You are not allowed to edit this item.', 'contact-form-7' ) )
|
||||
);
|
||||
}
|
||||
|
||||
$contact_form = wpcf7_save_contact_form(
|
||||
array_merge(
|
||||
wp_unslash( $_REQUEST ),
|
||||
array(
|
||||
'id' => $id,
|
||||
'title' => wpcf7_superglobal_post( 'post_title', null ),
|
||||
'locale' => wpcf7_superglobal_post( 'wpcf7-locale', null ),
|
||||
'form' => wpcf7_superglobal_post( 'wpcf7-form', '' ),
|
||||
'mail' => wpcf7_superglobal_post( 'wpcf7-mail', array() ),
|
||||
'mail_2' => wpcf7_superglobal_post( 'wpcf7-mail-2', array() ),
|
||||
'messages' => wpcf7_superglobal_post( 'wpcf7-messages', array() ),
|
||||
'additional_settings' => wpcf7_superglobal_post( 'wpcf7-additional-settings', '' ),
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
if ( $contact_form and wpcf7_validate_configuration() ) {
|
||||
$config_validator = new WPCF7_ConfigValidator( $contact_form );
|
||||
$config_validator->validate();
|
||||
$config_validator->save();
|
||||
}
|
||||
|
||||
$query = array(
|
||||
'post' => $contact_form ? $contact_form->id() : 0,
|
||||
'active-tab' => wpcf7_canonicalize_name(
|
||||
wpcf7_superglobal_post( 'active-tab' )
|
||||
),
|
||||
);
|
||||
|
||||
if ( ! $contact_form ) {
|
||||
$query['message'] = 'failed';
|
||||
} elseif ( -1 === (int) $id ) {
|
||||
$query['message'] = 'created';
|
||||
} else {
|
||||
$query['message'] = 'saved';
|
||||
}
|
||||
|
||||
$redirect_to = add_query_arg( $query, menu_page_url( 'wpcf7', false ) );
|
||||
wp_safe_redirect( $redirect_to );
|
||||
exit();
|
||||
}
|
||||
|
||||
if ( 'copy' === $action ) {
|
||||
$id = absint( $_POST['post_ID'] ?? $_REQUEST['post'] ?? '' );
|
||||
|
||||
check_admin_referer( 'wpcf7-copy-contact-form_' . $id );
|
||||
|
||||
if ( ! current_user_can( 'wpcf7_edit_contact_form', $id ) ) {
|
||||
wp_die(
|
||||
esc_html( __( 'You are not allowed to edit this item.', 'contact-form-7' ) )
|
||||
);
|
||||
}
|
||||
|
||||
$query = array();
|
||||
|
||||
if ( $contact_form = wpcf7_contact_form( $id ) ) {
|
||||
$new_contact_form = $contact_form->copy();
|
||||
$new_contact_form->save();
|
||||
|
||||
$query['post'] = $new_contact_form->id();
|
||||
$query['message'] = 'created';
|
||||
}
|
||||
|
||||
$redirect_to = add_query_arg( $query, menu_page_url( 'wpcf7', false ) );
|
||||
|
||||
wp_safe_redirect( $redirect_to );
|
||||
exit();
|
||||
}
|
||||
|
||||
if ( 'delete' === $action ) {
|
||||
$nonce_action = 'bulk-posts';
|
||||
|
||||
if (
|
||||
$post_id = wpcf7_superglobal_post( 'post_ID' ) or
|
||||
! is_array( $post_id = wpcf7_superglobal_request( 'post', array() ) )
|
||||
) {
|
||||
$nonce_action = sprintf( 'wpcf7-delete-contact-form_%s', $post_id );
|
||||
}
|
||||
|
||||
check_admin_referer( $nonce_action );
|
||||
|
||||
$posts = array_filter( (array) $post_id );
|
||||
|
||||
$deleted = 0;
|
||||
|
||||
foreach ( $posts as $post ) {
|
||||
$post = WPCF7_ContactForm::get_instance( $post );
|
||||
|
||||
if ( empty( $post ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( ! current_user_can( 'wpcf7_delete_contact_form', $post->id() ) ) {
|
||||
wp_die(
|
||||
esc_html( __( 'You are not allowed to delete this item.', 'contact-form-7' ) )
|
||||
);
|
||||
}
|
||||
|
||||
if ( ! $post->delete() ) {
|
||||
wp_die(
|
||||
esc_html( __( 'Error in deleting.', 'contact-form-7' ) )
|
||||
);
|
||||
}
|
||||
|
||||
$deleted += 1;
|
||||
}
|
||||
|
||||
$query = array();
|
||||
|
||||
if ( ! empty( $deleted ) ) {
|
||||
$query['message'] = 'deleted';
|
||||
}
|
||||
|
||||
$redirect_to = add_query_arg( $query, menu_page_url( 'wpcf7', false ) );
|
||||
|
||||
wp_safe_redirect( $redirect_to );
|
||||
exit();
|
||||
}
|
||||
|
||||
$post = null;
|
||||
|
||||
if ( 'wpcf7-new' === $plugin_page ) {
|
||||
$post = WPCF7_ContactForm::get_template( array(
|
||||
'locale' => wpcf7_superglobal_get( 'locale', null ),
|
||||
) );
|
||||
} elseif ( $post_id = wpcf7_superglobal_get( 'post' ) ) {
|
||||
$post = WPCF7_ContactForm::get_instance( $post_id );
|
||||
}
|
||||
|
||||
$current_screen = get_current_screen();
|
||||
|
||||
$help_tabs = new WPCF7_Help_Tabs( $current_screen );
|
||||
|
||||
if ( $post and current_user_can( 'wpcf7_edit_contact_form', $post->id() ) ) {
|
||||
$help_tabs->set_help_tabs( 'edit' );
|
||||
} else {
|
||||
$help_tabs->set_help_tabs( 'list' );
|
||||
|
||||
if ( ! class_exists( 'WPCF7_Contact_Form_List_Table' ) ) {
|
||||
require_once WPCF7_PLUGIN_DIR . '/admin/includes/class-contact-forms-list-table.php';
|
||||
}
|
||||
|
||||
add_filter(
|
||||
'manage_' . $current_screen->id . '_columns',
|
||||
array( 'WPCF7_Contact_Form_List_Table', 'define_columns' ),
|
||||
10, 0
|
||||
);
|
||||
|
||||
add_screen_option( 'per_page', array(
|
||||
'default' => 20,
|
||||
'option' => 'wpcf7_contact_forms_per_page',
|
||||
) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function wpcf7_admin_management_page() {
|
||||
if ( $post = wpcf7_get_current_contact_form() ) {
|
||||
$post_id = $post->initial() ? -1 : $post->id();
|
||||
|
||||
require_once WPCF7_PLUGIN_DIR . '/admin/includes/editor.php';
|
||||
require_once WPCF7_PLUGIN_DIR . '/admin/edit-contact-form.php';
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
'validate' === wpcf7_current_action() and
|
||||
wpcf7_validate_configuration() and
|
||||
current_user_can( 'wpcf7_edit_contact_forms' )
|
||||
) {
|
||||
wpcf7_admin_bulk_validate_page();
|
||||
return;
|
||||
}
|
||||
|
||||
$list_table = new WPCF7_Contact_Form_List_Table();
|
||||
$list_table->prepare_items();
|
||||
|
||||
$formatter = new WPCF7_HTMLFormatter( array(
|
||||
'allowed_html' => array_merge( wpcf7_kses_allowed_html(), array(
|
||||
'form' => array(
|
||||
'method' => true,
|
||||
),
|
||||
) ),
|
||||
) );
|
||||
|
||||
$formatter->append_start_tag( 'div', array(
|
||||
'class' => 'wrap',
|
||||
'id' => 'wpcf7-contact-form-list-table',
|
||||
) );
|
||||
|
||||
$formatter->append_start_tag( 'h1', array(
|
||||
'class' => 'wp-heading-inline',
|
||||
) );
|
||||
|
||||
$formatter->append_preformatted(
|
||||
esc_html( __( 'Contact Forms', 'contact-form-7' ) )
|
||||
);
|
||||
|
||||
$formatter->end_tag( 'h1' );
|
||||
|
||||
if ( current_user_can( 'wpcf7_edit_contact_forms' ) ) {
|
||||
$formatter->append_preformatted(
|
||||
wpcf7_link(
|
||||
menu_page_url( 'wpcf7-new', false ),
|
||||
__( 'Add Contact Form', 'contact-form-7' ),
|
||||
array( 'class' => 'page-title-action' )
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if ( $search_keyword = wpcf7_superglobal_request( 's' ) ) {
|
||||
$formatter->append_start_tag( 'span', array(
|
||||
'class' => 'subtitle',
|
||||
) );
|
||||
|
||||
$formatter->append_preformatted(
|
||||
sprintf(
|
||||
/* translators: %s: Search query. */
|
||||
__( 'Search results for: <strong>%s</strong>', 'contact-form-7' ),
|
||||
esc_html( $search_keyword )
|
||||
)
|
||||
);
|
||||
|
||||
$formatter->end_tag( 'span' );
|
||||
}
|
||||
|
||||
$formatter->append_start_tag( 'hr', array(
|
||||
'class' => 'wp-header-end',
|
||||
) );
|
||||
|
||||
$formatter->call_user_func( static function () {
|
||||
do_action( 'wpcf7_admin_warnings',
|
||||
'wpcf7', wpcf7_current_action(), null
|
||||
);
|
||||
|
||||
wpcf7_welcome_panel();
|
||||
|
||||
do_action( 'wpcf7_admin_notices',
|
||||
'wpcf7', wpcf7_current_action(), null
|
||||
);
|
||||
} );
|
||||
|
||||
$formatter->append_start_tag( 'form', array(
|
||||
'method' => 'get',
|
||||
) );
|
||||
|
||||
$formatter->append_start_tag( 'input', array(
|
||||
'type' => 'hidden',
|
||||
'name' => 'page',
|
||||
'value' => wpcf7_superglobal_request( 'page' ),
|
||||
) );
|
||||
|
||||
$formatter->call_user_func( static function () use ( $list_table ) {
|
||||
$list_table->search_box(
|
||||
__( 'Search Contact Forms', 'contact-form-7' ),
|
||||
'wpcf7-contact'
|
||||
);
|
||||
|
||||
$list_table->display();
|
||||
} );
|
||||
|
||||
$formatter->print();
|
||||
}
|
||||
|
||||
|
||||
function wpcf7_admin_add_new_page() {
|
||||
$post = wpcf7_get_current_contact_form();
|
||||
|
||||
if ( ! $post ) {
|
||||
$post = WPCF7_ContactForm::get_template();
|
||||
}
|
||||
|
||||
$post_id = -1;
|
||||
|
||||
require_once WPCF7_PLUGIN_DIR . '/admin/includes/editor.php';
|
||||
require_once WPCF7_PLUGIN_DIR . '/admin/edit-contact-form.php';
|
||||
}
|
||||
|
||||
|
||||
function wpcf7_load_integration_page() {
|
||||
do_action( 'wpcf7_admin_load',
|
||||
wpcf7_superglobal_get( 'page' ),
|
||||
wpcf7_current_action()
|
||||
);
|
||||
|
||||
$integration = WPCF7_Integration::get_instance();
|
||||
|
||||
if (
|
||||
$service_name = wpcf7_superglobal_request( 'service' ) and
|
||||
$integration->service_exists( $service_name )
|
||||
) {
|
||||
$service = $integration->get_service( $service_name );
|
||||
$service->load( wpcf7_current_action() );
|
||||
}
|
||||
|
||||
$help_tabs = new WPCF7_Help_Tabs( get_current_screen() );
|
||||
$help_tabs->set_help_tabs( 'integration' );
|
||||
}
|
||||
|
||||
|
||||
function wpcf7_admin_integration_page() {
|
||||
$integration = WPCF7_Integration::get_instance();
|
||||
|
||||
$service_name = wpcf7_superglobal_request( 'service' );
|
||||
$service = null;
|
||||
|
||||
if ( $service_name and $integration->service_exists( $service_name ) ) {
|
||||
$service = $integration->get_service( $service_name );
|
||||
}
|
||||
|
||||
$formatter = new WPCF7_HTMLFormatter( array(
|
||||
'allowed_html' => array_merge( wpcf7_kses_allowed_html(), array(
|
||||
'form' => array(
|
||||
'action' => true,
|
||||
'method' => true,
|
||||
),
|
||||
) ),
|
||||
) );
|
||||
|
||||
$formatter->append_start_tag( 'div', array(
|
||||
'class' => 'wrap',
|
||||
'id' => 'wpcf7-integration',
|
||||
) );
|
||||
|
||||
$formatter->append_start_tag( 'h1' );
|
||||
|
||||
$formatter->append_preformatted(
|
||||
esc_html( __( 'Integration with External API', 'contact-form-7' ) )
|
||||
);
|
||||
|
||||
$formatter->end_tag( 'h1' );
|
||||
|
||||
$formatter->append_start_tag( 'p' );
|
||||
|
||||
$formatter->append_preformatted(
|
||||
sprintf(
|
||||
/* translators: %s: URL to support page about integration with external APIs */
|
||||
__( 'You can expand the possibilities of your contact forms by integrating them with external services. For details, see <a href="%s">Integration with external APIs</a>.', 'contact-form-7' ),
|
||||
__( 'https://contactform7.com/integration-with-external-apis/', 'contact-form-7' )
|
||||
)
|
||||
);
|
||||
|
||||
$formatter->end_tag( 'p' );
|
||||
|
||||
$formatter->call_user_func(
|
||||
static function () use ( $integration, $service, $service_name ) {
|
||||
do_action( 'wpcf7_admin_warnings',
|
||||
'wpcf7-integration', wpcf7_current_action(), $service
|
||||
);
|
||||
|
||||
do_action( 'wpcf7_admin_notices',
|
||||
'wpcf7-integration', wpcf7_current_action(), $service
|
||||
);
|
||||
|
||||
if ( $service ) {
|
||||
$message = wpcf7_superglobal_request( 'message' );
|
||||
$service->admin_notice( $message );
|
||||
|
||||
$integration->list_services( array(
|
||||
'include' => $service_name,
|
||||
) );
|
||||
} else {
|
||||
$integration->list_services();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
$formatter->print();
|
||||
}
|
||||
|
||||
|
||||
add_action( 'wpcf7_admin_notices', 'wpcf7_admin_updated_message', 10, 3 );
|
||||
|
||||
function wpcf7_admin_updated_message( $page, $action, $object ) {
|
||||
if ( ! in_array( $page, array( 'wpcf7', 'wpcf7-new' ), true ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$message_type = wpcf7_superglobal_request( 'message' );
|
||||
|
||||
if ( ! $message_type ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$notice_type = 'success';
|
||||
|
||||
if ( 'created' === $message_type ) {
|
||||
$message = __( 'Contact form created.', 'contact-form-7' );
|
||||
} elseif ( 'saved' === $message_type ) {
|
||||
$message = __( 'Contact form saved.', 'contact-form-7' );
|
||||
} elseif ( 'deleted' === $message_type ) {
|
||||
$message = __( 'Contact form deleted.', 'contact-form-7' );
|
||||
} elseif ( 'failed' === $message_type ) {
|
||||
$notice_type = 'error';
|
||||
$message = __( 'There was an error saving the contact form.', 'contact-form-7' );
|
||||
} elseif ( 'validated' === $message_type ) {
|
||||
$bulk_validate = WPCF7::get_option( 'bulk_validate', array() );
|
||||
$count_invalid = absint( $bulk_validate['count_invalid'] ?? 0 );
|
||||
|
||||
if ( $count_invalid ) {
|
||||
$notice_type = 'warning';
|
||||
|
||||
$message = sprintf(
|
||||
/* translators: %s: number of contact forms */
|
||||
_n(
|
||||
'Configuration validation completed. %s invalid contact form was found.',
|
||||
'Configuration validation completed. %s invalid contact forms were found.',
|
||||
$count_invalid, 'contact-form-7'
|
||||
),
|
||||
number_format_i18n( $count_invalid )
|
||||
);
|
||||
} else {
|
||||
$message = __( 'Configuration validation completed. No invalid contact form was found.', 'contact-form-7' );
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! empty( $message ) ) {
|
||||
wp_admin_notice(
|
||||
$message,
|
||||
array( 'type' => $notice_type )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
add_filter( 'plugin_action_links', 'wpcf7_plugin_action_links', 10, 2 );
|
||||
|
||||
function wpcf7_plugin_action_links( $links, $file ) {
|
||||
if ( WPCF7_PLUGIN_BASENAME !== $file ) {
|
||||
return $links;
|
||||
}
|
||||
|
||||
if ( ! current_user_can( 'wpcf7_read_contact_forms' ) ) {
|
||||
return $links;
|
||||
}
|
||||
|
||||
$settings_link = wpcf7_link(
|
||||
menu_page_url( 'wpcf7', false ),
|
||||
__( 'Settings', 'contact-form-7' )
|
||||
);
|
||||
|
||||
array_unshift( $links, $settings_link );
|
||||
|
||||
return $links;
|
||||
}
|
||||
|
||||
|
||||
add_action( 'wpcf7_admin_warnings', 'wpcf7_old_wp_version_error', 10, 3 );
|
||||
|
||||
function wpcf7_old_wp_version_error( $page, $action, $object ) {
|
||||
$wp_version = get_bloginfo( 'version' );
|
||||
|
||||
if ( version_compare( $wp_version, WPCF7_REQUIRED_WP_VERSION, '<' ) ) {
|
||||
wp_admin_notice(
|
||||
sprintf(
|
||||
/* translators: 1: version of Contact Form 7, 2: version of WordPress, 3: URL */
|
||||
__( '<strong>Contact Form 7 %1$s requires WordPress %2$s or higher.</strong> Please <a href="%3$s">update WordPress</a> first.', 'contact-form-7' ),
|
||||
WPCF7_VERSION,
|
||||
WPCF7_REQUIRED_WP_VERSION,
|
||||
admin_url( 'update-core.php' )
|
||||
),
|
||||
array( 'type' => 'warning' )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
add_action( 'wpcf7_admin_warnings', 'wpcf7_not_allowed_to_edit', 10, 3 );
|
||||
|
||||
function wpcf7_not_allowed_to_edit( $page, $action, $object ) {
|
||||
if ( $object instanceof WPCF7_ContactForm ) {
|
||||
$contact_form = $object;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! current_user_can( 'wpcf7_edit_contact_form', $contact_form->id() ) ) {
|
||||
wp_admin_notice(
|
||||
__( 'You are not allowed to edit this contact form.', 'contact-form-7' ),
|
||||
array( 'type' => 'warning' )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
add_action( 'wpcf7_admin_warnings', 'wpcf7_ctct_deprecated_warning', 10, 3 );
|
||||
|
||||
function wpcf7_ctct_deprecated_warning( $page, $action, $object ) {
|
||||
$service = WPCF7_ConstantContact::get_instance();
|
||||
|
||||
if ( $service->is_active() ) {
|
||||
wp_admin_notice(
|
||||
__( 'Contact Form 7 has completed the <a href="https://contactform7.com/2025/01/08/complete-removal-of-constant-contact-integration/">removal of the Constant Contact integration</a>. We recommend <a href="https://contactform7.com/sendinblue-integration/">Brevo</a> as an alternative.', 'contact-form-7' ),
|
||||
array( 'type' => 'warning' )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
add_action( 'wpcf7_admin_warnings', 'wpcf7_captcha_future_warning', 10, 3 );
|
||||
|
||||
function wpcf7_captcha_future_warning( $page, $action, $object ) {
|
||||
$service = WPCF7_RECAPTCHA::get_instance();
|
||||
|
||||
if ( $service->is_active() ) {
|
||||
wp_admin_notice(
|
||||
__( '<strong>Attention reCAPTCHA users:</strong> Google attempts to make all reCAPTCHA users migrate to reCAPTCHA Enterprise, meaning Google charges you for API calls exceeding the free tier. Contact Form 7 supports <a href="https://contactform7.com/turnstile-integration/">Cloudflare Turnstile</a>, and we recommend it unless you have reasons to use reCAPTCHA.', 'contact-form-7' ),
|
||||
array( 'type' => 'warning' )
|
||||
);
|
||||
}
|
||||
}
|
||||
484
wp-content/plugins/contact-form-7/admin/edit-contact-form.php
Normal file
@ -0,0 +1,484 @@
|
||||
<?php
|
||||
|
||||
// don't load directly
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
$save_button = sprintf(
|
||||
'<input %s />',
|
||||
wpcf7_format_atts( array(
|
||||
'type' => 'submit',
|
||||
'class' => 'button-primary',
|
||||
'name' => 'wpcf7-save',
|
||||
'value' => __( 'Save', 'contact-form-7' ),
|
||||
) )
|
||||
);
|
||||
|
||||
$formatter = new WPCF7_HTMLFormatter( array(
|
||||
'allowed_html' => array_merge( wpcf7_kses_allowed_html(), array(
|
||||
'form' => array(
|
||||
'method' => true,
|
||||
'action' => true,
|
||||
'id' => true,
|
||||
'class' => true,
|
||||
'disabled' => true,
|
||||
),
|
||||
) ),
|
||||
) );
|
||||
|
||||
$formatter->append_start_tag( 'div', array(
|
||||
'class' => 'wrap',
|
||||
'id' => 'wpcf7-contact-form-editor',
|
||||
) );
|
||||
|
||||
$formatter->append_start_tag( 'h1', array(
|
||||
'class' => 'wp-heading-inline',
|
||||
) );
|
||||
|
||||
$formatter->append_preformatted(
|
||||
esc_html( $post->initial()
|
||||
? __( 'Add Contact Form', 'contact-form-7' )
|
||||
: __( 'Edit Contact Form', 'contact-form-7' )
|
||||
)
|
||||
);
|
||||
|
||||
$formatter->end_tag( 'h1' );
|
||||
|
||||
if ( ! $post->initial() and current_user_can( 'wpcf7_edit_contact_forms' ) ) {
|
||||
$formatter->append_whitespace();
|
||||
|
||||
$formatter->append_preformatted(
|
||||
wpcf7_link(
|
||||
menu_page_url( 'wpcf7-new', false ),
|
||||
__( 'Add Contact Form', 'contact-form-7' ),
|
||||
array( 'class' => 'page-title-action' )
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$formatter->append_start_tag( 'hr', array(
|
||||
'class' => 'wp-header-end',
|
||||
) );
|
||||
|
||||
$formatter->call_user_func( static function () use ( $post ) {
|
||||
do_action( 'wpcf7_admin_warnings',
|
||||
$post->initial() ? 'wpcf7-new' : 'wpcf7',
|
||||
wpcf7_current_action(),
|
||||
$post
|
||||
);
|
||||
|
||||
do_action( 'wpcf7_admin_notices',
|
||||
$post->initial() ? 'wpcf7-new' : 'wpcf7',
|
||||
wpcf7_current_action(),
|
||||
$post
|
||||
);
|
||||
} );
|
||||
|
||||
if ( $post ) {
|
||||
$formatter->append_start_tag( 'form', array(
|
||||
'method' => 'post',
|
||||
'action' => esc_url( add_query_arg(
|
||||
array( 'post' => $post_id ),
|
||||
menu_page_url( 'wpcf7', false )
|
||||
) ),
|
||||
'id' => 'wpcf7-admin-form-element',
|
||||
'disabled' => ! current_user_can( 'wpcf7_edit_contact_form', $post_id ),
|
||||
) );
|
||||
|
||||
if ( current_user_can( 'wpcf7_edit_contact_form', $post_id ) ) {
|
||||
$formatter->call_user_func( static function () use ( $post_id ) {
|
||||
wp_nonce_field( 'wpcf7-save-contact-form_' . $post_id );
|
||||
} );
|
||||
}
|
||||
|
||||
$formatter->append_start_tag( 'input', array(
|
||||
'type' => 'hidden',
|
||||
'id' => 'post_ID',
|
||||
'name' => 'post_ID',
|
||||
'value' => (int) $post_id,
|
||||
) );
|
||||
|
||||
$formatter->append_start_tag( 'input', array(
|
||||
'type' => 'hidden',
|
||||
'id' => 'wpcf7-locale',
|
||||
'name' => 'wpcf7-locale',
|
||||
'value' => $post->locale(),
|
||||
) );
|
||||
|
||||
$formatter->append_start_tag( 'input', array(
|
||||
'type' => 'hidden',
|
||||
'id' => 'hiddenaction',
|
||||
'name' => 'action',
|
||||
'value' => 'save',
|
||||
) );
|
||||
|
||||
$formatter->append_start_tag( 'input', array(
|
||||
'type' => 'hidden',
|
||||
'id' => 'active-tab',
|
||||
'name' => 'active-tab',
|
||||
'value' => wpcf7_superglobal_get( 'active-tab' ),
|
||||
) );
|
||||
|
||||
$formatter->append_start_tag( 'div', array(
|
||||
'id' => 'poststuff',
|
||||
) );
|
||||
|
||||
$formatter->append_start_tag( 'div', array(
|
||||
'id' => 'post-body',
|
||||
'class' => 'metabox-holder columns-2 wp-clearfix',
|
||||
) );
|
||||
|
||||
$formatter->append_start_tag( 'div', array(
|
||||
'id' => 'post-body-content',
|
||||
) );
|
||||
|
||||
$formatter->append_start_tag( 'div', array(
|
||||
'id' => 'titlediv',
|
||||
) );
|
||||
|
||||
$formatter->append_start_tag( 'div', array(
|
||||
'id' => 'titlewrap',
|
||||
) );
|
||||
|
||||
$formatter->append_start_tag( 'input', array(
|
||||
'type' => 'text',
|
||||
'name' => 'post_title',
|
||||
'value' => $post->initial() ? '' : $post->title(),
|
||||
'id' => 'title',
|
||||
'spellcheck' => 'true',
|
||||
'autocomplete' => 'off',
|
||||
'disabled' => ! current_user_can( 'wpcf7_edit_contact_form', $post_id ),
|
||||
'placeholder' => __( 'Enter title here', 'contact-form-7' ),
|
||||
'aria-label' => __( 'Enter title here', 'contact-form-7' ),
|
||||
) );
|
||||
|
||||
$formatter->end_tag( 'div' ); // #titlewrap
|
||||
|
||||
$formatter->append_start_tag( 'div', array(
|
||||
'class' => 'inside',
|
||||
) );
|
||||
|
||||
if ( ! $post->initial() ) {
|
||||
if ( $shortcode = $post->shortcode() ) {
|
||||
$formatter->append_start_tag( 'p', array(
|
||||
'class' => 'description',
|
||||
) );
|
||||
|
||||
$formatter->append_start_tag( 'label', array(
|
||||
'for' => 'wpcf7-shortcode',
|
||||
) );
|
||||
|
||||
$formatter->append_preformatted(
|
||||
esc_html( __( 'Copy this shortcode and paste it into your post, page, or text widget content:', 'contact-form-7' ) )
|
||||
);
|
||||
|
||||
$formatter->end_tag( 'label' );
|
||||
|
||||
$formatter->append_whitespace();
|
||||
|
||||
$formatter->append_start_tag( 'span', array(
|
||||
'class' => 'shortcode wp-ui-highlight',
|
||||
) );
|
||||
|
||||
$formatter->append_start_tag( 'input', array(
|
||||
'type' => 'text',
|
||||
'id' => 'wpcf7-shortcode',
|
||||
'readonly' => true,
|
||||
'class' => 'large-text code selectable',
|
||||
'value' => $shortcode,
|
||||
) );
|
||||
|
||||
$formatter->end_tag( 'p' );
|
||||
}
|
||||
|
||||
if ( $shortcode = $post->shortcode( array( 'use_old_format' => true ) ) ) {
|
||||
$formatter->append_start_tag( 'p', array(
|
||||
'class' => 'description',
|
||||
) );
|
||||
|
||||
$formatter->append_start_tag( 'label', array(
|
||||
'for' => 'wpcf7-shortcode-old',
|
||||
) );
|
||||
|
||||
$formatter->append_preformatted(
|
||||
esc_html( __( 'You can also use this old-style shortcode:', 'contact-form-7' ) )
|
||||
);
|
||||
|
||||
$formatter->end_tag( 'label' );
|
||||
|
||||
$formatter->append_whitespace();
|
||||
|
||||
$formatter->append_start_tag( 'span', array(
|
||||
'class' => 'shortcode old',
|
||||
) );
|
||||
|
||||
$formatter->append_start_tag( 'input', array(
|
||||
'type' => 'text',
|
||||
'id' => 'wpcf7-shortcode-old',
|
||||
'readonly' => true,
|
||||
'class' => 'large-text code selectable',
|
||||
'value' => $shortcode,
|
||||
) );
|
||||
|
||||
$formatter->end_tag( 'p' );
|
||||
}
|
||||
}
|
||||
|
||||
$formatter->end_tag( 'div' ); // .inside
|
||||
$formatter->end_tag( 'div' ); // #titlediv
|
||||
$formatter->end_tag( 'div' ); // #post-body-content
|
||||
|
||||
$formatter->append_start_tag( 'div', array(
|
||||
'id' => 'postbox-container-1',
|
||||
'class' => 'postbox-container',
|
||||
) );
|
||||
|
||||
if ( current_user_can( 'wpcf7_edit_contact_form', $post_id ) ) {
|
||||
$formatter->append_start_tag( 'section', array(
|
||||
'id' => 'submitdiv',
|
||||
'class' => 'postbox',
|
||||
) );
|
||||
|
||||
$formatter->append_start_tag( 'h2' );
|
||||
|
||||
$formatter->append_preformatted(
|
||||
esc_html( __( 'Status', 'contact-form-7' ) )
|
||||
);
|
||||
|
||||
$formatter->end_tag( 'h2' );
|
||||
|
||||
$formatter->append_start_tag( 'div', array(
|
||||
'class' => 'inside',
|
||||
) );
|
||||
|
||||
$formatter->append_start_tag( 'div', array(
|
||||
'class' => 'submitbox',
|
||||
'id' => 'submitpost',
|
||||
) );
|
||||
|
||||
$formatter->append_start_tag( 'div', array(
|
||||
'id' => 'minor-publishing-actions',
|
||||
) );
|
||||
|
||||
$formatter->append_start_tag( 'div', array(
|
||||
'class' => 'hidden',
|
||||
) );
|
||||
|
||||
$formatter->append_start_tag( 'input', array(
|
||||
'type' => 'submit',
|
||||
'class' => 'button-primary',
|
||||
'name' => 'wpcf7-save',
|
||||
'value' => __( 'Save', 'contact-form-7' ),
|
||||
) );
|
||||
|
||||
$formatter->end_tag( 'div' ); // .hidden
|
||||
|
||||
if ( ! $post->initial() ) {
|
||||
$formatter->append_start_tag( 'input', array(
|
||||
'type' => 'submit',
|
||||
'name' => 'wpcf7-copy',
|
||||
'class' => 'copy button',
|
||||
'value' => __( 'Duplicate', 'contact-form-7' ),
|
||||
) );
|
||||
}
|
||||
|
||||
$formatter->end_tag( 'div' ); // #minor-publishing-actions
|
||||
|
||||
$formatter->append_start_tag( 'div', array(
|
||||
'id' => 'misc-publishing-actions',
|
||||
) );
|
||||
|
||||
$formatter->call_user_func( static function () use ( $post_id ) {
|
||||
do_action( 'wpcf7_admin_misc_pub_section', $post_id );
|
||||
} );
|
||||
|
||||
$formatter->end_tag( 'div' ); // #misc-publishing-actions
|
||||
|
||||
$formatter->append_start_tag( 'div', array(
|
||||
'id' => 'major-publishing-actions',
|
||||
) );
|
||||
|
||||
if ( ! $post->initial() ) {
|
||||
$formatter->append_start_tag( 'div', array(
|
||||
'id' => 'delete-action',
|
||||
) );
|
||||
|
||||
$formatter->append_start_tag( 'input', array(
|
||||
'type' => 'submit',
|
||||
'name' => 'wpcf7-delete',
|
||||
'class' => 'delete submitdelete',
|
||||
'value' => __( 'Delete', 'contact-form-7' ),
|
||||
) );
|
||||
|
||||
$formatter->end_tag( 'div' ); // #delete-action
|
||||
}
|
||||
|
||||
$formatter->append_start_tag( 'div', array(
|
||||
'id' => 'publishing-action',
|
||||
) );
|
||||
|
||||
$formatter->append_preformatted( '<span class="spinner"></span>' );
|
||||
$formatter->append_preformatted( $save_button );
|
||||
|
||||
$formatter->end_tag( 'div' ); // #publishing-action
|
||||
|
||||
$formatter->append_preformatted( '<div class="clear"></div>' );
|
||||
|
||||
$formatter->end_tag( 'div' ); // #major-publishing-actions
|
||||
$formatter->end_tag( 'div' ); // #submitpost
|
||||
$formatter->end_tag( 'div' ); // .inside
|
||||
$formatter->end_tag( 'section' ); // #submitdiv
|
||||
}
|
||||
|
||||
$formatter->append_start_tag( 'section', array(
|
||||
'id' => 'informationdiv',
|
||||
'class' => 'postbox',
|
||||
) );
|
||||
|
||||
$formatter->append_start_tag( 'h2' );
|
||||
|
||||
$formatter->append_preformatted(
|
||||
esc_html( __( 'Do you need help?', 'contact-form-7' ) )
|
||||
);
|
||||
|
||||
$formatter->end_tag( 'h2' );
|
||||
|
||||
$formatter->append_start_tag( 'div', array(
|
||||
'class' => 'inside',
|
||||
) );
|
||||
|
||||
$formatter->append_start_tag( 'p' );
|
||||
|
||||
$formatter->append_preformatted(
|
||||
esc_html( __( 'Here are some available options to help solve your problems.', 'contact-form-7' ) )
|
||||
);
|
||||
|
||||
$formatter->end_tag( 'p' );
|
||||
|
||||
$formatter->append_start_tag( 'ol' );
|
||||
|
||||
$formatter->append_start_tag( 'li' );
|
||||
|
||||
$formatter->append_preformatted(
|
||||
sprintf(
|
||||
/* translators: 1: URL to FAQ, 2: URL to docs */
|
||||
'<a href="%1$s">FAQ</a> and <a href="%2$s">docs</a>',
|
||||
__( 'https://contactform7.com/faq/', 'contact-form-7' ),
|
||||
__( 'https://contactform7.com/docs/', 'contact-form-7' )
|
||||
)
|
||||
);
|
||||
|
||||
$formatter->append_start_tag( 'li' );
|
||||
|
||||
$formatter->append_preformatted(
|
||||
wpcf7_link(
|
||||
__( 'https://wordpress.org/support/plugin/contact-form-7/', 'contact-form-7' ),
|
||||
__( 'Support forums', 'contact-form-7' )
|
||||
)
|
||||
);
|
||||
|
||||
$formatter->append_start_tag( 'li' );
|
||||
|
||||
$formatter->append_preformatted(
|
||||
wpcf7_link(
|
||||
__( 'https://contactform7.com/custom-development/', 'contact-form-7' ),
|
||||
__( 'Professional services', 'contact-form-7' )
|
||||
)
|
||||
);
|
||||
|
||||
$formatter->end_tag( 'ol' );
|
||||
$formatter->end_tag( 'div' ); // .inside
|
||||
$formatter->end_tag( 'section' ); // #informationdiv
|
||||
$formatter->end_tag( 'div' ); // #postbox-container-1
|
||||
|
||||
$formatter->append_start_tag( 'div', array(
|
||||
'id' => 'postbox-container-2',
|
||||
'class' => 'postbox-container',
|
||||
) );
|
||||
|
||||
$formatter->append_start_tag( 'div', array(
|
||||
'id' => 'contact-form-editor',
|
||||
) );
|
||||
|
||||
$formatter->call_user_func( static function () use ( $post, $post_id ) {
|
||||
$editor = new WPCF7_Editor( $post );
|
||||
$panels = array();
|
||||
|
||||
if ( current_user_can( 'wpcf7_edit_contact_form', $post_id ) ) {
|
||||
$panels = array(
|
||||
'form-panel' => array(
|
||||
'title' => __( 'Form', 'contact-form-7' ),
|
||||
'callback' => 'wpcf7_editor_panel_form',
|
||||
),
|
||||
'mail-panel' => array(
|
||||
'title' => __( 'Mail', 'contact-form-7' ),
|
||||
'callback' => 'wpcf7_editor_panel_mail',
|
||||
),
|
||||
'messages-panel' => array(
|
||||
'title' => __( 'Messages', 'contact-form-7' ),
|
||||
'callback' => 'wpcf7_editor_panel_messages',
|
||||
),
|
||||
);
|
||||
|
||||
$additional_settings = $post->prop( 'additional_settings' );
|
||||
|
||||
if ( ! is_scalar( $additional_settings ) ) {
|
||||
$additional_settings = '';
|
||||
}
|
||||
|
||||
$additional_settings = trim( $additional_settings );
|
||||
$additional_settings = explode( "\n", $additional_settings );
|
||||
$additional_settings = array_filter( $additional_settings );
|
||||
$additional_settings = count( $additional_settings );
|
||||
|
||||
$panels['additional-settings-panel'] = array(
|
||||
'title' => $additional_settings
|
||||
? sprintf(
|
||||
/* translators: %d: number of additional settings */
|
||||
__( 'Additional Settings (%d)', 'contact-form-7' ),
|
||||
$additional_settings
|
||||
)
|
||||
: __( 'Additional Settings', 'contact-form-7' ),
|
||||
'callback' => 'wpcf7_editor_panel_additional_settings',
|
||||
);
|
||||
}
|
||||
|
||||
$panels = apply_filters( 'wpcf7_editor_panels', $panels );
|
||||
|
||||
foreach ( $panels as $id => $panel ) {
|
||||
$editor->add_panel( $id, $panel['title'], $panel['callback'] );
|
||||
}
|
||||
|
||||
$editor->display();
|
||||
} );
|
||||
|
||||
$formatter->end_tag( 'div' ); // #contact-form-editor
|
||||
|
||||
if ( current_user_can( 'wpcf7_edit_contact_form', $post_id ) ) {
|
||||
$formatter->append_start_tag( 'p', array(
|
||||
'class' => 'submit',
|
||||
) );
|
||||
|
||||
$formatter->append_preformatted( $save_button );
|
||||
|
||||
$formatter->end_tag( 'p' );
|
||||
}
|
||||
|
||||
$formatter->end_tag( 'div' ); // #postbox-container-2
|
||||
$formatter->end_tag( 'div' ); // #post-body
|
||||
|
||||
$formatter->append_preformatted( '<br class="clear" />' );
|
||||
|
||||
$formatter->end_tag( 'div' ); // #poststuff
|
||||
$formatter->end_tag( 'form' );
|
||||
}
|
||||
|
||||
$formatter->end_tag( 'div' ); // .wrap
|
||||
|
||||
$formatter->print();
|
||||
|
||||
$tag_generator = WPCF7_TagGenerator::get_instance();
|
||||
$tag_generator->print_panels( $post );
|
||||
|
||||
do_action( 'wpcf7_admin_footer', $post );
|
||||
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
function wpcf7_current_action() {
|
||||
foreach ( array( 'action', 'action2' ) as $var ) {
|
||||
$action = wpcf7_superglobal_request( $var, null );
|
||||
|
||||
if ( isset( $action ) and -1 !== $action ) {
|
||||
return $action;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function wpcf7_admin_has_edit_cap() {
|
||||
return current_user_can( 'wpcf7_edit_contact_forms' );
|
||||
}
|
||||
|
||||
function wpcf7_add_tag_generator( $name, $title, $elm_id, $callback, $options = array() ) {
|
||||
$tag_generator = WPCF7_TagGenerator::get_instance();
|
||||
return $tag_generator->add( $name, $title, $callback, $options );
|
||||
}
|
||||
@ -0,0 +1,241 @@
|
||||
<?php
|
||||
|
||||
if ( ! class_exists( 'WP_List_Table' ) ) {
|
||||
require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php';
|
||||
}
|
||||
|
||||
class WPCF7_Contact_Form_List_Table extends WP_List_Table {
|
||||
|
||||
public static function define_columns() {
|
||||
$columns = array(
|
||||
'cb' => '<input type="checkbox" />',
|
||||
'title' => __( 'Title', 'contact-form-7' ),
|
||||
'shortcode' => __( 'Shortcode', 'contact-form-7' ),
|
||||
'author' => __( 'Author', 'contact-form-7' ),
|
||||
'date' => __( 'Date', 'contact-form-7' ),
|
||||
);
|
||||
|
||||
return $columns;
|
||||
}
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct( array(
|
||||
'singular' => 'post',
|
||||
'plural' => 'posts',
|
||||
'ajax' => false,
|
||||
) );
|
||||
}
|
||||
|
||||
public function prepare_items() {
|
||||
$current_screen = get_current_screen();
|
||||
$per_page = $this->get_items_per_page( 'wpcf7_contact_forms_per_page' );
|
||||
|
||||
$args = array(
|
||||
'posts_per_page' => $per_page,
|
||||
'orderby' => 'title',
|
||||
'order' => 'ASC',
|
||||
'offset' => ( $this->get_pagenum() - 1 ) * $per_page,
|
||||
);
|
||||
|
||||
if ( $search_keyword = wpcf7_superglobal_request( 's' ) ) {
|
||||
$args['s'] = $search_keyword;
|
||||
}
|
||||
|
||||
if ( $order_by = wpcf7_superglobal_request( 'orderby' ) ) {
|
||||
$args['orderby'] = $order_by;
|
||||
}
|
||||
|
||||
if (
|
||||
$order = wpcf7_superglobal_request( 'order' ) and
|
||||
'desc' === strtolower( $order )
|
||||
) {
|
||||
$args['order'] = 'DESC';
|
||||
}
|
||||
|
||||
$this->items = WPCF7_ContactForm::find( $args );
|
||||
|
||||
$total_items = WPCF7_ContactForm::count();
|
||||
$total_pages = ceil( $total_items / $per_page );
|
||||
|
||||
$this->set_pagination_args( array(
|
||||
'total_items' => $total_items,
|
||||
'total_pages' => $total_pages,
|
||||
'per_page' => $per_page,
|
||||
) );
|
||||
}
|
||||
|
||||
public function get_columns() {
|
||||
return get_column_headers( get_current_screen() );
|
||||
}
|
||||
|
||||
protected function get_sortable_columns() {
|
||||
$columns = array(
|
||||
'title' => array( 'title', true ),
|
||||
'author' => array( 'author', false ),
|
||||
'date' => array( 'date', false ),
|
||||
);
|
||||
|
||||
return $columns;
|
||||
}
|
||||
|
||||
protected function get_bulk_actions() {
|
||||
$actions = array(
|
||||
'delete' => __( 'Delete', 'contact-form-7' ),
|
||||
);
|
||||
|
||||
return $actions;
|
||||
}
|
||||
|
||||
protected function column_default( $item, $column_name ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
public function column_cb( $item ) {
|
||||
return sprintf(
|
||||
'<input type="checkbox" name="%1$s[]" value="%2$s" />',
|
||||
$this->_args['singular'],
|
||||
$item->id()
|
||||
);
|
||||
}
|
||||
|
||||
public function column_title( $item ) {
|
||||
$edit_link = add_query_arg(
|
||||
array(
|
||||
'post' => absint( $item->id() ),
|
||||
'action' => 'edit',
|
||||
),
|
||||
menu_page_url( 'wpcf7', false )
|
||||
);
|
||||
|
||||
$output = sprintf(
|
||||
'<a class="row-title" href="%1$s" aria-label="%2$s">%3$s</a>',
|
||||
esc_url( $edit_link ),
|
||||
esc_attr( sprintf(
|
||||
/* translators: %s: title of contact form */
|
||||
__( 'Edit “%s”', 'contact-form-7' ),
|
||||
$item->title()
|
||||
) ),
|
||||
esc_html( $item->title() )
|
||||
);
|
||||
|
||||
$output = sprintf( '<strong>%s</strong>', $output );
|
||||
|
||||
if ( wpcf7_validate_configuration()
|
||||
and current_user_can( 'wpcf7_edit_contact_form', $item->id() ) ) {
|
||||
$config_validator = new WPCF7_ConfigValidator( $item );
|
||||
$config_validator->restore();
|
||||
|
||||
if ( $count_errors = $config_validator->count_errors() ) {
|
||||
$error_notice = sprintf(
|
||||
/* translators: %s: number of errors detected */
|
||||
_n(
|
||||
'%s configuration error detected',
|
||||
'%s configuration errors detected',
|
||||
$count_errors, 'contact-form-7' ),
|
||||
number_format_i18n( $count_errors )
|
||||
);
|
||||
|
||||
$output .= sprintf(
|
||||
'<div class="config-error"><span class="icon-in-circle" aria-hidden="true">!</span> %s</div>',
|
||||
$error_notice
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
protected function handle_row_actions( $item, $column_name, $primary ) {
|
||||
if ( $column_name !== $primary ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$edit_link = add_query_arg(
|
||||
array(
|
||||
'post' => absint( $item->id() ),
|
||||
'action' => 'edit',
|
||||
),
|
||||
menu_page_url( 'wpcf7', false )
|
||||
);
|
||||
|
||||
$actions = array(
|
||||
'edit' => wpcf7_link( $edit_link, __( 'Edit', 'contact-form-7' ) ),
|
||||
);
|
||||
|
||||
if ( current_user_can( 'wpcf7_edit_contact_form', $item->id() ) ) {
|
||||
$copy_link = add_query_arg(
|
||||
array(
|
||||
'post' => absint( $item->id() ),
|
||||
'action' => 'copy',
|
||||
),
|
||||
menu_page_url( 'wpcf7', false )
|
||||
);
|
||||
|
||||
$copy_link = wp_nonce_url(
|
||||
$copy_link,
|
||||
'wpcf7-copy-contact-form_' . absint( $item->id() )
|
||||
);
|
||||
|
||||
$actions = array_merge( $actions, array(
|
||||
'copy' => wpcf7_link( $copy_link, __( 'Duplicate', 'contact-form-7' ) ),
|
||||
) );
|
||||
}
|
||||
|
||||
return $this->row_actions( $actions );
|
||||
}
|
||||
|
||||
public function column_author( $item ) {
|
||||
$post = get_post( $item->id() );
|
||||
|
||||
if ( ! $post ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$author = get_userdata( $post->post_author );
|
||||
|
||||
if ( false === $author ) {
|
||||
return;
|
||||
}
|
||||
|
||||
return esc_html( $author->display_name );
|
||||
}
|
||||
|
||||
public function column_shortcode( $item ) {
|
||||
$shortcodes = array( $item->shortcode() );
|
||||
|
||||
$output = '';
|
||||
|
||||
foreach ( $shortcodes as $shortcode ) {
|
||||
$output .= "\n" . sprintf(
|
||||
'<span class="shortcode"><input %s /></span>',
|
||||
wpcf7_format_atts( array(
|
||||
'type' => 'text',
|
||||
'readonly' => true,
|
||||
'value' => $shortcode,
|
||||
'class' => 'large-text code selectable',
|
||||
) )
|
||||
);
|
||||
}
|
||||
|
||||
return trim( $output );
|
||||
}
|
||||
|
||||
public function column_date( $item ) {
|
||||
$datetime = get_post_datetime( $item->id() );
|
||||
|
||||
if ( false === $datetime ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$t_time = sprintf(
|
||||
/* translators: 1: date, 2: time */
|
||||
__( '%1$s at %2$s', 'contact-form-7' ),
|
||||
/* translators: date format, see https://www.php.net/date */
|
||||
$datetime->format( __( 'Y/m/d', 'contact-form-7' ) ),
|
||||
/* translators: time format, see https://www.php.net/date */
|
||||
$datetime->format( __( 'g:i a', 'contact-form-7' ) )
|
||||
);
|
||||
|
||||
return $t_time;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,180 @@
|
||||
<?php
|
||||
|
||||
add_action( 'wpcf7_admin_menu', 'wpcf7_admin_init_bulk_cv', 10, 0 );
|
||||
|
||||
function wpcf7_admin_init_bulk_cv() {
|
||||
if (
|
||||
! wpcf7_validate_configuration() or
|
||||
! current_user_can( 'wpcf7_edit_contact_forms' )
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
$result = WPCF7::get_option( 'bulk_validate' );
|
||||
$last_important_update = WPCF7_ConfigValidator::last_important_update;
|
||||
|
||||
if (
|
||||
! empty( $result['version'] ) and
|
||||
version_compare( $last_important_update, $result['version'], '<=' )
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
add_filter( 'wpcf7_admin_menu_change_notice',
|
||||
'wpcf7_admin_menu_change_notice_bulk_cv',
|
||||
10, 1
|
||||
);
|
||||
|
||||
add_action( 'wpcf7_admin_warnings',
|
||||
'wpcf7_admin_warnings_bulk_cv',
|
||||
5, 3
|
||||
);
|
||||
}
|
||||
|
||||
function wpcf7_admin_menu_change_notice_bulk_cv( $counts ) {
|
||||
$counts['wpcf7'] += 1;
|
||||
return $counts;
|
||||
}
|
||||
|
||||
function wpcf7_admin_warnings_bulk_cv( $page, $action, $object ) {
|
||||
if ( 'wpcf7' === $page and 'validate' === $action ) {
|
||||
return;
|
||||
}
|
||||
|
||||
wp_admin_notice(
|
||||
sprintf(
|
||||
'%1$s » %2$s',
|
||||
__( 'Misconfiguration leads to mail delivery failure or other troubles. Validate your contact forms now.', 'contact-form-7' ),
|
||||
wpcf7_link(
|
||||
add_query_arg(
|
||||
array( 'action' => 'validate' ),
|
||||
menu_page_url( 'wpcf7', false )
|
||||
),
|
||||
__( 'Validate Contact Form 7 Configuration', 'contact-form-7' )
|
||||
)
|
||||
),
|
||||
array( 'type' => 'warning' )
|
||||
);
|
||||
}
|
||||
|
||||
add_action( 'wpcf7_admin_load', 'wpcf7_load_bulk_validate_page', 10, 2 );
|
||||
|
||||
function wpcf7_load_bulk_validate_page( $page, $action ) {
|
||||
if (
|
||||
'wpcf7' !== $page or
|
||||
'validate' !== $action or
|
||||
! wpcf7_validate_configuration() or
|
||||
'POST' !== wpcf7_superglobal_server( 'REQUEST_METHOD' )
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
check_admin_referer( 'wpcf7-bulk-validate' );
|
||||
|
||||
if ( ! current_user_can( 'wpcf7_edit_contact_forms' ) ) {
|
||||
wp_die( wp_kses_data( __( 'You are not allowed to validate configuration.', 'contact-form-7' ) ) );
|
||||
}
|
||||
|
||||
$contact_forms = WPCF7_ContactForm::find();
|
||||
|
||||
$result = array(
|
||||
'timestamp' => time(),
|
||||
'version' => WPCF7_VERSION,
|
||||
'count_valid' => 0,
|
||||
'count_invalid' => 0,
|
||||
);
|
||||
|
||||
foreach ( $contact_forms as $contact_form ) {
|
||||
$config_validator = new WPCF7_ConfigValidator( $contact_form );
|
||||
$config_validator->validate();
|
||||
$config_validator->save();
|
||||
|
||||
if ( $config_validator->is_valid() ) {
|
||||
$result['count_valid'] += 1;
|
||||
} else {
|
||||
$result['count_invalid'] += 1;
|
||||
}
|
||||
}
|
||||
|
||||
WPCF7::update_option( 'bulk_validate', $result );
|
||||
|
||||
$redirect_to = add_query_arg(
|
||||
array(
|
||||
'message' => 'validated',
|
||||
),
|
||||
menu_page_url( 'wpcf7', false )
|
||||
);
|
||||
|
||||
wp_safe_redirect( $redirect_to );
|
||||
exit();
|
||||
}
|
||||
|
||||
function wpcf7_admin_bulk_validate_page() {
|
||||
$contact_forms = WPCF7_ContactForm::find();
|
||||
$count = WPCF7_ContactForm::count();
|
||||
|
||||
$submit_text = sprintf(
|
||||
/* translators: %s: number of contact forms */
|
||||
_n(
|
||||
'Validate %s contact form now',
|
||||
'Validate %s contact forms now',
|
||||
$count, 'contact-form-7'
|
||||
),
|
||||
number_format_i18n( $count )
|
||||
);
|
||||
|
||||
$formatter = new WPCF7_HTMLFormatter( array(
|
||||
'allowed_html' => array_merge( wpcf7_kses_allowed_html(), array(
|
||||
'form' => array(
|
||||
'action' => true,
|
||||
'method' => true,
|
||||
),
|
||||
) ),
|
||||
) );
|
||||
|
||||
$formatter->append_start_tag( 'div', array(
|
||||
'class' => 'wrap',
|
||||
) );
|
||||
|
||||
$formatter->append_start_tag( 'h1' );
|
||||
|
||||
$formatter->append_preformatted(
|
||||
esc_html( __( 'Validate Configuration', 'contact-form-7' ) )
|
||||
);
|
||||
|
||||
$formatter->end_tag( 'h1' );
|
||||
|
||||
$formatter->append_start_tag( 'form', array(
|
||||
'method' => 'post',
|
||||
'action' => '',
|
||||
) );
|
||||
|
||||
$formatter->append_start_tag( 'p' );
|
||||
|
||||
$formatter->call_user_func( static function () {
|
||||
wp_nonce_field( 'wpcf7-bulk-validate' );
|
||||
} );
|
||||
|
||||
$formatter->append_start_tag( 'input', array(
|
||||
'type' => 'hidden',
|
||||
'name' => 'action',
|
||||
'value' => 'validate',
|
||||
) );
|
||||
|
||||
$formatter->append_start_tag( 'input', array(
|
||||
'type' => 'submit',
|
||||
'class' => 'button',
|
||||
'value' => $submit_text,
|
||||
) );
|
||||
|
||||
$formatter->end_tag( 'form' );
|
||||
|
||||
$formatter->append_preformatted(
|
||||
wpcf7_link(
|
||||
__( 'https://contactform7.com/configuration-validator-faq/', 'contact-form-7' ),
|
||||
__( 'FAQ about Configuration Validator', 'contact-form-7' )
|
||||
)
|
||||
);
|
||||
|
||||
$formatter->print();
|
||||
}
|
||||
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Form Tab
|
||||
*/
|
||||
.tag-generator-panel {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.tag-generator-dialog > .close-button {
|
||||
right: auto;
|
||||
left: 8px;
|
||||
}
|
||||
|
||||
form.tag-generator-panel[data-version="1"] {
|
||||
.control-box > fieldset > legend {
|
||||
border: 1px solid #dfdfdf;
|
||||
border-right: 4px solid #00a0d2;
|
||||
}
|
||||
|
||||
.insert-box input.tag {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.insert-box .submitbox input[type="button"] {
|
||||
float: left;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Mail Tab
|
||||
*/
|
||||
.contact-form-editor-box-mail span.mailtag {
|
||||
margin: 0 4px 0 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Welcome Panel
|
||||
*/
|
||||
.wpcf7-welcome-panel .welcome-panel-close {
|
||||
left: 10px;
|
||||
right: auto;
|
||||
padding: 10px 21px 10px 15px;
|
||||
}
|
||||
|
||||
.wpcf7-welcome-panel .welcome-panel-close::before {
|
||||
right: 0;
|
||||
left: auto;
|
||||
}
|
||||
|
||||
.wpcf7-welcome-panel .welcome-panel-content {
|
||||
margin-right: 13px;
|
||||
}
|
||||
|
||||
.wpcf7-welcome-panel .welcome-panel-column {
|
||||
float: right;
|
||||
padding: 0 0 0 2%;
|
||||
}
|
||||
|
||||
/*
|
||||
* Integration
|
||||
*/
|
||||
.card {
|
||||
border-left: 1px solid #e5e5e5;
|
||||
border-right: 4px solid #e5e5e5;
|
||||
}
|
||||
|
||||
.card img.icon {
|
||||
float: right;
|
||||
margin: 8px -8px 8px 8px;
|
||||
}
|
||||
|
||||
.card h2.title {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.card .infobox {
|
||||
float: left;
|
||||
}
|
||||
614
wp-content/plugins/contact-form-7/admin/includes/css/styles.css
Normal file
@ -0,0 +1,614 @@
|
||||
#titlediv .inside p.description {
|
||||
margin: 8px 2px 0;
|
||||
}
|
||||
|
||||
#titlediv .inside p.description label {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
span.shortcode {
|
||||
display: block;
|
||||
margin: 2px 0;
|
||||
}
|
||||
|
||||
span.shortcode.old {
|
||||
background: #777;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
span.shortcode input {
|
||||
font-size: 12px;
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
padding: 4px 8px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#wpcf7-contact-form-list-table span.shortcode input,
|
||||
#wpcf7-contact-form-editor span.shortcode input {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
#wpcf7-contact-form-list-table span.shortcode input {
|
||||
color: #444;
|
||||
}
|
||||
|
||||
#wpcf7-contact-form-editor span.shortcode input {
|
||||
color: #fff;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#submitpost input.copy {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
#submitpost input.delete {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
background: inherit;
|
||||
color: #a00;
|
||||
}
|
||||
|
||||
#submitpost input.delete:hover {
|
||||
color: #dc3232; /* Red */
|
||||
}
|
||||
|
||||
#submitpost input.delete:focus {
|
||||
outline: thin dotted;
|
||||
}
|
||||
|
||||
.postbox-container .postbox h3 {
|
||||
border-bottom: 1px solid transparent;
|
||||
}
|
||||
|
||||
div.config-error, span.config-error, ul.config-error {
|
||||
color: #444;
|
||||
font-style: normal;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
ul.config-error {
|
||||
margin: 2px 0;
|
||||
}
|
||||
|
||||
ul.config-error li {
|
||||
list-style: none;
|
||||
padding: 2px 2px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#misc-publishing-actions .config-error {
|
||||
line-height: 2;
|
||||
}
|
||||
|
||||
[data-config-field][aria-invalid="true"] {
|
||||
border-color: #dc3232;
|
||||
}
|
||||
|
||||
#contact-form-editor-tabs .icon-in-circle,
|
||||
#contact-form-editor .config-error .icon-in-circle,
|
||||
.wp-list-table .config-error .icon-in-circle,
|
||||
.icon-in-circle {
|
||||
display: inline-block;
|
||||
vertical-align: baseline;
|
||||
margin: 1px 6px 0;
|
||||
padding: 0 5px;
|
||||
min-width: 7px;
|
||||
height: 17px;
|
||||
border-radius: 11px;
|
||||
background-color: #ca4a1f;
|
||||
color: #fff;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
line-height: 17px;
|
||||
text-align: center;
|
||||
z-index: 26;
|
||||
}
|
||||
|
||||
/*
|
||||
* Tabs
|
||||
*/
|
||||
#contact-form-editor-tabs {
|
||||
border-bottom: 1px solid #aaa;
|
||||
padding: 9px 10px 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#contact-form-editor-tabs button {
|
||||
display: inline-block;
|
||||
border: 1px solid #ccc;
|
||||
border-bottom: 1px solid #aaa;
|
||||
padding: 6px 10px;
|
||||
margin: 0 4px -1px;
|
||||
color: #333;
|
||||
background-color: #e4e4e4;
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
#contact-form-editor-tabs button[aria-selected="true"] {
|
||||
border-top: 1px solid #aaa;
|
||||
border-right: 1px solid #aaa;
|
||||
border-left: 1px solid #aaa;
|
||||
border-bottom: 1px solid #f5f5f5;
|
||||
color: #000;
|
||||
background-color: #f5f5f5;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#contact-form-editor-tabs button:hover {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
#contact-form-editor .contact-form-editor-panel > div.config-error {
|
||||
margin-bottom: 1.4em;
|
||||
}
|
||||
|
||||
#contact-form-editor-tabs button[aria-selected="true"] .icon-in-circle {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#contact-form-editor .contact-form-editor-panel h2 {
|
||||
font-size: 18px;
|
||||
font-weight: 400;
|
||||
line-height: 24px;
|
||||
margin: 8px 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#contact-form-editor .contact-form-editor-panel {
|
||||
background-color: #f5f5f5;
|
||||
border: 1px solid #aaa;
|
||||
border-top: none;
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
#contact-form-editor .form-table th {
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
#contact-form-editor .contact-form-editor-panel fieldset legend {
|
||||
line-height: 1.5;
|
||||
margin: .6em 0 .4em;
|
||||
}
|
||||
|
||||
/*
|
||||
* Form Tab
|
||||
*/
|
||||
#tag-generator-list button {
|
||||
font-size: 12px;
|
||||
height: 26px;
|
||||
line-height: 24px;
|
||||
margin: 2px;
|
||||
padding: 0 8px 1px;
|
||||
}
|
||||
|
||||
.tag-generator-dialog {
|
||||
padding: 12px;
|
||||
border: 1px solid #c3c4c7;
|
||||
box-shadow: 0 1px 1px rgba( 0, 0, 0, 0.04 );
|
||||
height: 720px;
|
||||
width: 720px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.tag-generator-dialog::backdrop {
|
||||
background: rgb( 0 0 0 / 50% );
|
||||
}
|
||||
|
||||
.tag-generator-dialog > .close-button {
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
right: 8px;
|
||||
}
|
||||
|
||||
form.tag-generator-panel {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 720px;
|
||||
width: 720px;
|
||||
max-height: 100%;
|
||||
max-width: 100%;
|
||||
margin-block-end: 0;
|
||||
}
|
||||
|
||||
form.tag-generator-panel[data-version="2"] {
|
||||
&:invalid .mail-tag-tip {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.description-box {
|
||||
box-sizing: border-box;
|
||||
flex: none;
|
||||
margin-inline: -12px;
|
||||
padding-inline: 12px;
|
||||
border-bottom: 1px solid #dfdfdf;
|
||||
}
|
||||
|
||||
.control-box {
|
||||
box-sizing: border-box;
|
||||
flex: auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px 0;
|
||||
min-height: 120px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.control-box > fieldset {
|
||||
margin-block: 8px;
|
||||
margin-inline-start: 10em;
|
||||
line-height: 2.25;
|
||||
}
|
||||
|
||||
.control-box > fieldset > legend {
|
||||
font-weight: bolder;
|
||||
margin-block: 8px;
|
||||
margin-inline-start: -10em;
|
||||
line-height: 1.25;
|
||||
}
|
||||
|
||||
.control-box input[type="text"] {
|
||||
width: 20rem;
|
||||
max-width: 88%;
|
||||
}
|
||||
|
||||
.control-box input[type="number"] {
|
||||
width: 8rem;
|
||||
max-width: 44%;
|
||||
}
|
||||
|
||||
.control-box textarea {
|
||||
height: 12ex;
|
||||
width: 20rem;
|
||||
max-width: 88%;
|
||||
}
|
||||
|
||||
.control-box select {
|
||||
width: 20rem;
|
||||
max-width: 88%;
|
||||
}
|
||||
|
||||
.control-box input:invalid,
|
||||
.control-box textarea:invalid {
|
||||
background-color: #ffe9de;
|
||||
}
|
||||
|
||||
.insert-box {
|
||||
box-sizing: border-box;
|
||||
flex: none;
|
||||
margin-block-end: -12px;
|
||||
margin-inline: -12px;
|
||||
padding-block: 24px 12px;
|
||||
padding-inline: 12px;
|
||||
background-color: #fcfcfc;
|
||||
border-top: 1px solid #dfdfdf;
|
||||
}
|
||||
|
||||
.insert-box .flex-container {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.insert-box .flex-container > [data-tag-part="tag"] {
|
||||
flex: auto;
|
||||
margin-inline-end: 8px;
|
||||
}
|
||||
|
||||
.insert-box .mail-tag-tip::before {
|
||||
font: 1.2rem dashicons;
|
||||
content: "\f348" / '';
|
||||
color: #646970;
|
||||
padding-inline-end: 4px;
|
||||
vertical-align: top;
|
||||
}
|
||||
}
|
||||
|
||||
form.tag-generator-panel[data-version="1"] {
|
||||
.control-box {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
overflow: auto;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.control-box > fieldset > legend {
|
||||
border: 1px solid #dfdfdf;
|
||||
border-left: 4px solid #00a0d2;
|
||||
background: #f7fcfe;
|
||||
padding: 4px 12px;
|
||||
margin: 4px 0;
|
||||
line-height: 1.4em;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
table.form-table th {
|
||||
width: 120px;
|
||||
padding: 4px 10px 4px 0;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
table.form-table td {
|
||||
padding: 4px 10px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.control-box input.oneline {
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
.control-box input.large-text {
|
||||
width: 400px;
|
||||
}
|
||||
|
||||
.control-box textarea.values {
|
||||
width: 200px;
|
||||
height: 6em;
|
||||
}
|
||||
|
||||
.control-box input[type="number"],
|
||||
.control-box input[type="date"] {
|
||||
width: 88px;
|
||||
}
|
||||
|
||||
.control-box table caption {
|
||||
text-align: left;
|
||||
font-size: 110%;
|
||||
font-weight: bold;
|
||||
color: #777;
|
||||
margin: 10px 0 5px;
|
||||
}
|
||||
|
||||
.control-box table.form-table td label {
|
||||
line-height: 1.1em;
|
||||
}
|
||||
|
||||
.control-box table.form-table td label .description {
|
||||
line-height: 1.4em;
|
||||
}
|
||||
|
||||
.insert-box {
|
||||
margin: 0 -15px -15px;
|
||||
padding: 8px 16px;
|
||||
background-color: #fcfcfc;
|
||||
border-top: 1px solid #dfdfdf;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.insert-box input.tag {
|
||||
width: 510px;
|
||||
float: left;
|
||||
background-color: transparent;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.insert-box .submitbox {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.insert-box .submitbox input[type="button"] {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.insert-box .description label {
|
||||
cursor: text;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Mail Tab
|
||||
*/
|
||||
.contact-form-editor-box-mail span.mailtag {
|
||||
display: inline-block;
|
||||
margin: 0 0 0 4px;
|
||||
padding: 1px 2px;
|
||||
cursor: pointer;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.contact-form-editor-box-mail span.mailtag.used {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.contact-form-editor-box-mail span.mailtag.unused {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/*
|
||||
* Messages Tab
|
||||
*/
|
||||
#messages-panel p.description {
|
||||
margin: 5px 0 10px;
|
||||
}
|
||||
|
||||
/*
|
||||
* Tabs for integration modules
|
||||
*/
|
||||
#sendinblue-panel table tr.inactive ~ tr {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#sendinblue-panel .dashicons {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
#sendinblue-panel td p {
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
/*
|
||||
* List Table
|
||||
*/
|
||||
.fixed .column-title {
|
||||
width: 38%;
|
||||
}
|
||||
|
||||
.fixed .column-shortcode {
|
||||
width: 38%;
|
||||
}
|
||||
|
||||
/*
|
||||
* Welcome Panel
|
||||
*/
|
||||
.wpcf7-welcome-panel {
|
||||
position: relative;
|
||||
overflow: auto;
|
||||
margin: 16px 0;
|
||||
padding: 23px 10px 0;
|
||||
border: 1px solid #c3c4c7;
|
||||
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.04);
|
||||
background: #fff;
|
||||
font-size: 13px;
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
.wpcf7-welcome-panel h3 {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
line-height: 2.1em;
|
||||
margin: 1em 0 1.2em;
|
||||
}
|
||||
|
||||
.wpcf7-welcome-panel h3 .dashicons {
|
||||
position: relative;
|
||||
top: -2px;
|
||||
display: inline-block;
|
||||
width: 60px;
|
||||
color: #575757;
|
||||
font-size: 40px;
|
||||
}
|
||||
|
||||
.wpcf7-welcome-panel p {
|
||||
color: #646970;
|
||||
}
|
||||
|
||||
.wpcf7-welcome-panel p a {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.wpcf7-welcome-panel .welcome-panel-close {
|
||||
position: absolute;
|
||||
z-index: 2;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
padding: 10px 15px 10px 21px;
|
||||
font-size: 13px;
|
||||
line-height: 1.23076923; /* Chrome rounding, needs to be 16px equivalent */
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.wpcf7-welcome-panel .welcome-panel-close::before {
|
||||
background: 0 0;
|
||||
color: #787c82;
|
||||
content: "\f153" / '';
|
||||
display: block;
|
||||
font: normal 16px/20px dashicons;
|
||||
speak: never;
|
||||
height: 20px;
|
||||
text-align: center;
|
||||
width: 20px;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
left: 0;
|
||||
transition: all .1s ease-in-out;
|
||||
}
|
||||
|
||||
.wpcf7-welcome-panel .welcome-panel-content {
|
||||
display: block;
|
||||
margin-left: 13px;
|
||||
max-width: 1500px;
|
||||
min-height: auto;
|
||||
}
|
||||
|
||||
.wpcf7-welcome-panel .welcome-panel-column-container {
|
||||
clear: both;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.wpcf7-welcome-panel .welcome-panel-column {
|
||||
display: block;
|
||||
width: 48%;
|
||||
min-width: 200px;
|
||||
float: left;
|
||||
padding: 0 2% 0 0;
|
||||
margin: 0 0 1em 0;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 870px) {
|
||||
.wpcf7-welcome-panel .welcome-panel-column {
|
||||
display: block;
|
||||
float: none;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.wpcf7-welcome-panel .welcome-panel-column p {
|
||||
margin-top: 7px;
|
||||
color: #3c434a;
|
||||
}
|
||||
|
||||
/*
|
||||
* Integration
|
||||
*/
|
||||
.card {
|
||||
background: #fff none repeat scroll 0 0;
|
||||
border: 1px solid #e5e5e5;
|
||||
border-left: 4px solid #e5e5e5;
|
||||
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.04);
|
||||
margin-top: 20px;
|
||||
max-width: 520px;
|
||||
min-width: 255px;
|
||||
padding: 0.7em 2em 1em;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.card.active {
|
||||
border-color: #00a0d2;
|
||||
}
|
||||
|
||||
#constant_contact.card.active {
|
||||
border-color: #dc3232;
|
||||
}
|
||||
|
||||
.card img.icon {
|
||||
float: left;
|
||||
margin: 8px 8px 8px -8px;
|
||||
}
|
||||
|
||||
.card h2.title {
|
||||
float: left;
|
||||
max-width: 240px;
|
||||
font-size: 1.3em;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.card .infobox {
|
||||
float: right;
|
||||
font-size: 13px;
|
||||
color: #666;
|
||||
margin: 1em;
|
||||
line-height: 1.5;
|
||||
max-width: 240px;
|
||||
}
|
||||
|
||||
.card .inside .form-table th {
|
||||
padding: 15px 10px 15px 0;
|
||||
width: 160px;
|
||||
}
|
||||
|
||||
.card .inside .form-table td {
|
||||
padding: 10px 10px;
|
||||
}
|
||||
|
||||
.card .checkboxes li {
|
||||
margin: 0;
|
||||
}
|
||||
556
wp-content/plugins/contact-form-7/admin/includes/editor.php
Normal file
@ -0,0 +1,556 @@
|
||||
<?php
|
||||
|
||||
class WPCF7_Editor {
|
||||
|
||||
private $contact_form;
|
||||
private $panels = array();
|
||||
|
||||
public function __construct( WPCF7_ContactForm $contact_form ) {
|
||||
$this->contact_form = $contact_form;
|
||||
}
|
||||
|
||||
public function add_panel( $panel_id, $title, $callback ) {
|
||||
if ( wpcf7_is_name( $panel_id ) ) {
|
||||
$this->panels[$panel_id] = array(
|
||||
'title' => $title,
|
||||
'callback' => $callback,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public function display() {
|
||||
if ( empty( $this->panels ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$active_panel_id = wpcf7_superglobal_get( 'active-tab' );
|
||||
|
||||
if ( ! array_key_exists( $active_panel_id, $this->panels ) ) {
|
||||
$active_panel_id = array_key_first( $this->panels );
|
||||
}
|
||||
|
||||
$formatter = new WPCF7_HTMLFormatter();
|
||||
|
||||
$formatter->append_start_tag( 'nav', array(
|
||||
'id' => 'contact-form-editor-tabs',
|
||||
'role' => 'tablist',
|
||||
'aria-label' => __( 'Contact form editor tabs', 'contact-form-7' ),
|
||||
'data-active-tab' => absint( array_search(
|
||||
$active_panel_id, array_keys( $this->panels ), true
|
||||
) ),
|
||||
) );
|
||||
|
||||
foreach ( $this->panels as $panel_id => $panel ) {
|
||||
$active = $panel_id === $active_panel_id;
|
||||
|
||||
$formatter->append_start_tag( 'button', array(
|
||||
'type' => 'button',
|
||||
'role' => 'tab',
|
||||
'aria-selected' => $active ? 'true' : 'false',
|
||||
'aria-controls' => $panel_id,
|
||||
'id' => sprintf( '%s-tab', $panel_id ),
|
||||
'tabindex' => $active ? '0' : '-1',
|
||||
) );
|
||||
|
||||
$formatter->append_preformatted( esc_html( $panel['title'] ) );
|
||||
}
|
||||
|
||||
$formatter->end_tag( 'nav' );
|
||||
|
||||
foreach ( $this->panels as $panel_id => $panel ) {
|
||||
$active = $panel_id === $active_panel_id;
|
||||
|
||||
$formatter->append_start_tag( 'section', array(
|
||||
'role' => 'tabpanel',
|
||||
'aria-labelledby' => sprintf( '%s-tab', $panel_id ),
|
||||
'id' => $panel_id,
|
||||
'class' => 'contact-form-editor-panel',
|
||||
'tabindex' => '0',
|
||||
'hidden' => ! $active,
|
||||
) );
|
||||
|
||||
if ( is_callable( $panel['callback'] ) ) {
|
||||
$formatter->call_user_func( $panel['callback'], $this->contact_form );
|
||||
}
|
||||
|
||||
$formatter->end_tag( 'section' );
|
||||
}
|
||||
|
||||
$formatter->print();
|
||||
}
|
||||
}
|
||||
|
||||
function wpcf7_editor_panel_form( $post ) {
|
||||
$description = sprintf(
|
||||
/* translators: %s: URL to support page about the form template */
|
||||
__( 'You can edit the form template here. For details, see <a href="%s">Editing form template</a>.', 'contact-form-7' ),
|
||||
__( 'https://contactform7.com/editing-form-template/', 'contact-form-7' )
|
||||
);
|
||||
|
||||
$formatter = new WPCF7_HTMLFormatter();
|
||||
|
||||
$formatter->append_start_tag( 'h2' );
|
||||
$formatter->append_preformatted( esc_html( __( 'Form', 'contact-form-7' ) ) );
|
||||
$formatter->end_tag( 'h2' );
|
||||
|
||||
$formatter->append_start_tag( 'fieldset' );
|
||||
|
||||
$formatter->append_start_tag( 'legend' );
|
||||
$formatter->append_preformatted( $description );
|
||||
$formatter->end_tag( 'legend' );
|
||||
|
||||
$formatter->call_user_func( static function () {
|
||||
$tag_generator = WPCF7_TagGenerator::get_instance();
|
||||
$tag_generator->print_buttons();
|
||||
} );
|
||||
|
||||
$formatter->append_start_tag( 'textarea', array(
|
||||
'id' => 'wpcf7-form',
|
||||
'name' => 'wpcf7-form',
|
||||
'cols' => 100,
|
||||
'rows' => 24,
|
||||
'class' => 'large-text code',
|
||||
'data-config-field' => 'form.body',
|
||||
) );
|
||||
|
||||
$formatter->append_preformatted( esc_textarea( $post->prop( 'form' ) ) );
|
||||
|
||||
$formatter->end_tag( 'textarea' );
|
||||
|
||||
$formatter->print();
|
||||
}
|
||||
|
||||
function wpcf7_editor_panel_mail( $post ) {
|
||||
wpcf7_editor_box_mail( $post );
|
||||
|
||||
echo '<br class="clear" />';
|
||||
|
||||
wpcf7_editor_box_mail( $post, array(
|
||||
'id' => 'wpcf7-mail-2',
|
||||
'name' => 'mail_2',
|
||||
'title' => __( 'Mail (2)', 'contact-form-7' ),
|
||||
'use' => __( 'Use Mail (2)', 'contact-form-7' ),
|
||||
) );
|
||||
}
|
||||
|
||||
function wpcf7_editor_box_mail( $post, $options = '' ) {
|
||||
$options = wp_parse_args( $options, array(
|
||||
'id' => 'wpcf7-mail',
|
||||
'name' => 'mail',
|
||||
'title' => __( 'Mail', 'contact-form-7' ),
|
||||
'use' => null,
|
||||
) );
|
||||
|
||||
$id = esc_attr( $options['id'] );
|
||||
|
||||
$mail = wp_parse_args( $post->prop( $options['name'] ), array(
|
||||
'active' => false,
|
||||
'recipient' => '',
|
||||
'sender' => '',
|
||||
'subject' => '',
|
||||
'body' => '',
|
||||
'additional_headers' => '',
|
||||
'attachments' => '',
|
||||
'use_html' => false,
|
||||
'exclude_blank' => false,
|
||||
) );
|
||||
|
||||
$formatter = new WPCF7_HTMLFormatter();
|
||||
|
||||
$formatter->append_start_tag( 'div', array(
|
||||
'class' => 'contact-form-editor-box-mail',
|
||||
'id' => $id,
|
||||
) );
|
||||
|
||||
$formatter->append_start_tag( 'h2' );
|
||||
$formatter->append_preformatted( esc_html( $options['title'] ) );
|
||||
$formatter->end_tag( 'h2' );
|
||||
|
||||
if ( ! empty( $options['use'] ) ) {
|
||||
$formatter->append_start_tag( 'label', array(
|
||||
'for' => sprintf( '%s-active', $id ),
|
||||
) );
|
||||
|
||||
$formatter->append_start_tag( 'input', array(
|
||||
'type' => 'checkbox',
|
||||
'id' => sprintf( '%s-active', $id ),
|
||||
'name' => sprintf( '%s[active]', $id ),
|
||||
'data-config-field' => '',
|
||||
'data-toggle' => sprintf( '%s-fieldset', $id ),
|
||||
'value' => '1',
|
||||
'checked' => $mail['active'],
|
||||
) );
|
||||
|
||||
$formatter->append_whitespace();
|
||||
$formatter->append_preformatted( esc_html( $options['use'] ) );
|
||||
$formatter->end_tag( 'label' );
|
||||
|
||||
$formatter->append_start_tag( 'p', array(
|
||||
'class' => 'description',
|
||||
) );
|
||||
|
||||
$formatter->append_preformatted(
|
||||
esc_html( __( 'Mail (2) is an additional mail template often used as an autoresponder.', 'contact-form-7' ) )
|
||||
);
|
||||
|
||||
$formatter->end_tag( 'p' );
|
||||
}
|
||||
|
||||
$formatter->append_start_tag( 'fieldset', array(
|
||||
'id' => sprintf( '%s-fieldset', $id ),
|
||||
) );
|
||||
|
||||
$formatter->append_start_tag( 'legend' );
|
||||
|
||||
$description = sprintf(
|
||||
/* translators: %s: URL to support page about the email template */
|
||||
__( 'You can edit the email template here. For details, see <a href="%s">Setting up mail</a>.', 'contact-form-7' ),
|
||||
__( 'https://contactform7.com/setting-up-mail/', 'contact-form-7' )
|
||||
);
|
||||
|
||||
$formatter->append_preformatted( $description );
|
||||
|
||||
$formatter->append_start_tag( 'br' );
|
||||
|
||||
$formatter->append_preformatted(
|
||||
esc_html( __( 'In the following fields, you can use these mail-tags:', 'contact-form-7' ) )
|
||||
);
|
||||
|
||||
$formatter->append_start_tag( 'br' );
|
||||
|
||||
$formatter->call_user_func( static function () use ( $post, $options ) {
|
||||
$post->suggest_mail_tags( $options['name'] );
|
||||
} );
|
||||
|
||||
$formatter->end_tag( 'legend' );
|
||||
|
||||
$formatter->append_start_tag( 'table', array(
|
||||
'class' => 'form-table',
|
||||
) );
|
||||
|
||||
$formatter->append_start_tag( 'tbody' );
|
||||
|
||||
$formatter->append_start_tag( 'tr' );
|
||||
|
||||
$formatter->append_start_tag( 'th', array(
|
||||
'scope' => 'row',
|
||||
) );
|
||||
|
||||
$formatter->append_start_tag( 'label', array(
|
||||
'for' => sprintf( '%s-recipient', $id ),
|
||||
) );
|
||||
|
||||
$formatter->append_preformatted(
|
||||
esc_html( __( 'To', 'contact-form-7' ) )
|
||||
);
|
||||
|
||||
$formatter->append_start_tag( 'td' );
|
||||
|
||||
$formatter->append_start_tag( 'input', array(
|
||||
'type' => 'text',
|
||||
'id' => sprintf( '%s-recipient', $id ),
|
||||
'name' => sprintf( '%s[recipient]', $id ),
|
||||
'class' => 'large-text code',
|
||||
'size' => 70,
|
||||
'value' => $mail['recipient'],
|
||||
'data-config-field' => sprintf( '%s.recipient', $options['name'] ),
|
||||
) );
|
||||
|
||||
$formatter->end_tag( 'tr' );
|
||||
|
||||
$formatter->append_start_tag( 'tr' );
|
||||
|
||||
$formatter->append_start_tag( 'th', array(
|
||||
'scope' => 'row',
|
||||
) );
|
||||
|
||||
$formatter->append_start_tag( 'label', array(
|
||||
'for' => sprintf( '%s-sender', $id ),
|
||||
) );
|
||||
|
||||
$formatter->append_preformatted(
|
||||
esc_html( __( 'From', 'contact-form-7' ) )
|
||||
);
|
||||
|
||||
$formatter->append_start_tag( 'td' );
|
||||
|
||||
$formatter->append_start_tag( 'input', array(
|
||||
'type' => 'text',
|
||||
'id' => sprintf( '%s-sender', $id ),
|
||||
'name' => sprintf( '%s[sender]', $id ),
|
||||
'class' => 'large-text code',
|
||||
'size' => 70,
|
||||
'value' => $mail['sender'],
|
||||
'data-config-field' => sprintf( '%s.sender', $options['name'] ),
|
||||
) );
|
||||
|
||||
$formatter->end_tag( 'tr' );
|
||||
|
||||
$formatter->append_start_tag( 'tr' );
|
||||
|
||||
$formatter->append_start_tag( 'th', array(
|
||||
'scope' => 'row',
|
||||
) );
|
||||
|
||||
$formatter->append_start_tag( 'label', array(
|
||||
'for' => sprintf( '%s-subject', $id ),
|
||||
) );
|
||||
|
||||
$formatter->append_preformatted(
|
||||
esc_html( __( 'Subject', 'contact-form-7' ) )
|
||||
);
|
||||
|
||||
$formatter->append_start_tag( 'td' );
|
||||
|
||||
$formatter->append_start_tag( 'input', array(
|
||||
'type' => 'text',
|
||||
'id' => sprintf( '%s-subject', $id ),
|
||||
'name' => sprintf( '%s[subject]', $id ),
|
||||
'class' => 'large-text code',
|
||||
'size' => 70,
|
||||
'value' => $mail['subject'],
|
||||
'data-config-field' => sprintf( '%s.subject', $options['name'] ),
|
||||
) );
|
||||
|
||||
$formatter->end_tag( 'tr' );
|
||||
|
||||
$formatter->append_start_tag( 'tr' );
|
||||
|
||||
$formatter->append_start_tag( 'th', array(
|
||||
'scope' => 'row',
|
||||
) );
|
||||
|
||||
$formatter->append_start_tag( 'label', array(
|
||||
'for' => sprintf( '%s-additional-headers', $id ),
|
||||
) );
|
||||
|
||||
$formatter->append_preformatted(
|
||||
esc_html( __( 'Additional headers', 'contact-form-7' ) )
|
||||
);
|
||||
|
||||
$formatter->append_start_tag( 'td' );
|
||||
|
||||
$formatter->append_start_tag( 'textarea', array(
|
||||
'id' => sprintf( '%s-additional-headers', $id ),
|
||||
'name' => sprintf( '%s[additional_headers]', $id ),
|
||||
'cols' => 100,
|
||||
'rows' => 4,
|
||||
'class' => 'large-text code',
|
||||
'data-config-field' => sprintf( '%s.additional_headers', $options['name'] ),
|
||||
) );
|
||||
|
||||
$formatter->append_preformatted(
|
||||
esc_textarea( $mail['additional_headers'] )
|
||||
);
|
||||
|
||||
$formatter->end_tag( 'tr' );
|
||||
|
||||
$formatter->append_start_tag( 'tr' );
|
||||
|
||||
$formatter->append_start_tag( 'th', array(
|
||||
'scope' => 'row',
|
||||
) );
|
||||
|
||||
$formatter->append_start_tag( 'label', array(
|
||||
'for' => sprintf( '%s-body', $id ),
|
||||
) );
|
||||
|
||||
$formatter->append_preformatted(
|
||||
esc_html( __( 'Message body', 'contact-form-7' ) )
|
||||
);
|
||||
|
||||
$formatter->append_start_tag( 'td' );
|
||||
|
||||
$formatter->append_start_tag( 'textarea', array(
|
||||
'id' => sprintf( '%s-body', $id ),
|
||||
'name' => sprintf( '%s[body]', $id ),
|
||||
'cols' => 100,
|
||||
'rows' => 18,
|
||||
'class' => 'large-text code',
|
||||
'data-config-field' => sprintf( '%s.body', $options['name'] ),
|
||||
) );
|
||||
|
||||
$formatter->append_preformatted(
|
||||
esc_textarea( $mail['body'] )
|
||||
);
|
||||
|
||||
$formatter->end_tag( 'textarea' );
|
||||
|
||||
$formatter->append_start_tag( 'p' );
|
||||
|
||||
$formatter->append_start_tag( 'label', array(
|
||||
'for' => sprintf( '%s-exclude-blank', $id ),
|
||||
) );
|
||||
|
||||
$formatter->append_start_tag( 'input', array(
|
||||
'type' => 'checkbox',
|
||||
'id' => sprintf( '%s-exclude-blank', $id ),
|
||||
'name' => sprintf( '%s[exclude_blank]', $id ),
|
||||
'value' => '1',
|
||||
'checked' => $mail['exclude_blank'],
|
||||
) );
|
||||
|
||||
$formatter->append_whitespace();
|
||||
|
||||
$formatter->append_preformatted(
|
||||
esc_html( __( 'Exclude a line from output if all of its mail-tags are blank', 'contact-form-7' ) )
|
||||
);
|
||||
|
||||
$formatter->append_start_tag( 'p' );
|
||||
|
||||
$formatter->append_start_tag( 'label', array(
|
||||
'for' => sprintf( '%s-use-html', $id ),
|
||||
) );
|
||||
|
||||
$formatter->append_start_tag( 'input', array(
|
||||
'type' => 'checkbox',
|
||||
'id' => sprintf( '%s-use-html', $id ),
|
||||
'name' => sprintf( '%s[use_html]', $id ),
|
||||
'value' => '1',
|
||||
'checked' => $mail['use_html'],
|
||||
) );
|
||||
|
||||
$formatter->append_whitespace();
|
||||
|
||||
$formatter->append_preformatted(
|
||||
esc_html( __( 'Use HTML content type', 'contact-form-7' ) )
|
||||
);
|
||||
|
||||
$formatter->end_tag( 'tr' );
|
||||
|
||||
$formatter->append_start_tag( 'tr' );
|
||||
|
||||
$formatter->append_start_tag( 'th', array(
|
||||
'scope' => 'row',
|
||||
) );
|
||||
|
||||
$formatter->append_start_tag( 'label', array(
|
||||
'for' => sprintf( '%s-attachments', $id ),
|
||||
) );
|
||||
|
||||
$formatter->append_preformatted(
|
||||
esc_html( __( 'File attachments', 'contact-form-7' ) )
|
||||
);
|
||||
|
||||
$formatter->append_start_tag( 'td' );
|
||||
|
||||
$formatter->append_start_tag( 'textarea', array(
|
||||
'id' => sprintf( '%s-attachments', $id ),
|
||||
'name' => sprintf( '%s[attachments]', $id ),
|
||||
'cols' => 100,
|
||||
'rows' => 4,
|
||||
'class' => 'large-text code',
|
||||
'data-config-field' => sprintf( '%s.attachments', $options['name'] ),
|
||||
) );
|
||||
|
||||
$formatter->append_preformatted(
|
||||
esc_textarea( $mail['attachments'] )
|
||||
);
|
||||
|
||||
$formatter->end_tag( 'textarea' );
|
||||
$formatter->end_tag( 'tr' );
|
||||
|
||||
$formatter->print();
|
||||
}
|
||||
|
||||
function wpcf7_editor_panel_messages( $post ) {
|
||||
$description = sprintf(
|
||||
/* translators: %s: URL to support page about the messages editor */
|
||||
__( 'You can edit messages used in various situations here. For details, see <a href="%s">Editing messages</a>.', 'contact-form-7' ),
|
||||
__( 'https://contactform7.com/editing-messages/', 'contact-form-7' )
|
||||
);
|
||||
|
||||
$messages = wpcf7_messages();
|
||||
|
||||
if (
|
||||
isset( $messages['captcha_not_match'] ) and
|
||||
! wpcf7_use_really_simple_captcha()
|
||||
) {
|
||||
unset( $messages['captcha_not_match'] );
|
||||
}
|
||||
|
||||
$formatter = new WPCF7_HTMLFormatter();
|
||||
|
||||
$formatter->append_start_tag( 'h2' );
|
||||
|
||||
$formatter->append_preformatted(
|
||||
esc_html( __( 'Messages', 'contact-form-7' ) )
|
||||
);
|
||||
|
||||
$formatter->end_tag( 'h2' );
|
||||
|
||||
$formatter->append_start_tag( 'fieldset' );
|
||||
|
||||
$formatter->append_start_tag( 'legend' );
|
||||
$formatter->append_preformatted( $description );
|
||||
$formatter->end_tag( 'legend' );
|
||||
|
||||
foreach ( $messages as $key => $arr ) {
|
||||
$field_id = sprintf( 'wpcf7-message-%s', strtr( $key, '_', '-' ) );
|
||||
$field_name = sprintf( 'wpcf7-messages[%s]', $key );
|
||||
|
||||
$formatter->append_start_tag( 'p', array(
|
||||
'class' => 'description',
|
||||
) );
|
||||
|
||||
$formatter->append_start_tag( 'label', array(
|
||||
'for' => $field_id,
|
||||
) );
|
||||
|
||||
$formatter->append_preformatted( esc_html( $arr['description'] ) );
|
||||
$formatter->append_start_tag( 'br' );
|
||||
|
||||
$formatter->append_start_tag( 'input', array(
|
||||
'type' => 'text',
|
||||
'id' => $field_id,
|
||||
'name' => $field_name,
|
||||
'class' => 'large-text',
|
||||
'size' => 70,
|
||||
'value' => $post->message( $key, false ),
|
||||
'data-config-field' => sprintf( 'messages.%s', $key ),
|
||||
) );
|
||||
}
|
||||
|
||||
$formatter->print();
|
||||
}
|
||||
|
||||
function wpcf7_editor_panel_additional_settings( $post ) {
|
||||
$description = sprintf(
|
||||
/* translators: %s: URL to support page about the additional settings editor */
|
||||
__( 'You can add customization code snippets here. For details, see <a href="%s">Additional settings</a>.', 'contact-form-7' ),
|
||||
__( 'https://contactform7.com/additional-settings/', 'contact-form-7' )
|
||||
);
|
||||
|
||||
$formatter = new WPCF7_HTMLFormatter();
|
||||
|
||||
$formatter->append_start_tag( 'h2' );
|
||||
|
||||
$formatter->append_preformatted(
|
||||
esc_html( __( 'Additional Settings', 'contact-form-7' ) )
|
||||
);
|
||||
|
||||
$formatter->end_tag( 'h2' );
|
||||
|
||||
$formatter->append_start_tag( 'fieldset' );
|
||||
|
||||
$formatter->append_start_tag( 'legend' );
|
||||
$formatter->append_preformatted( $description );
|
||||
$formatter->end_tag( 'legend' );
|
||||
|
||||
$formatter->append_start_tag( 'textarea', array(
|
||||
'id' => 'wpcf7-additional-settings',
|
||||
'name' => 'wpcf7-additional-settings',
|
||||
'cols' => 100,
|
||||
'rows' => 24,
|
||||
'class' => 'large-text',
|
||||
'data-config-field' => 'additional_settings.body',
|
||||
) );
|
||||
|
||||
$formatter->append_preformatted(
|
||||
esc_textarea( $post->prop( 'additional_settings' ) )
|
||||
);
|
||||
|
||||
$formatter->end_tag( 'textarea' );
|
||||
|
||||
$formatter->print();
|
||||
}
|
||||
104
wp-content/plugins/contact-form-7/admin/includes/help-tabs.php
Normal file
@ -0,0 +1,104 @@
|
||||
<?php
|
||||
|
||||
class WPCF7_Help_Tabs {
|
||||
|
||||
private $screen;
|
||||
|
||||
public function __construct( WP_Screen $screen ) {
|
||||
$this->screen = $screen;
|
||||
}
|
||||
|
||||
public function set_help_tabs( $screen_type ) {
|
||||
switch ( $screen_type ) {
|
||||
case 'list':
|
||||
$this->screen->add_help_tab( array(
|
||||
'id' => 'list_overview',
|
||||
'title' => __( 'Overview', 'contact-form-7' ),
|
||||
'content' => $this->content( 'list_overview' ),
|
||||
) );
|
||||
|
||||
$this->screen->add_help_tab( array(
|
||||
'id' => 'list_available_actions',
|
||||
'title' => __( 'Available Actions', 'contact-form-7' ),
|
||||
'content' => $this->content( 'list_available_actions' ),
|
||||
) );
|
||||
|
||||
$this->sidebar();
|
||||
|
||||
return;
|
||||
case 'edit':
|
||||
$this->screen->add_help_tab( array(
|
||||
'id' => 'edit_overview',
|
||||
'title' => __( 'Overview', 'contact-form-7' ),
|
||||
'content' => $this->content( 'edit_overview' ),
|
||||
) );
|
||||
|
||||
$this->screen->add_help_tab( array(
|
||||
'id' => 'edit_form_tags',
|
||||
'title' => __( 'Form-tags', 'contact-form-7' ),
|
||||
'content' => $this->content( 'edit_form_tags' ),
|
||||
) );
|
||||
|
||||
$this->screen->add_help_tab( array(
|
||||
'id' => 'edit_mail_tags',
|
||||
'title' => __( 'Mail-tags', 'contact-form-7' ),
|
||||
'content' => $this->content( 'edit_mail_tags' ),
|
||||
) );
|
||||
|
||||
$this->sidebar();
|
||||
|
||||
return;
|
||||
case 'integration':
|
||||
$this->screen->add_help_tab( array(
|
||||
'id' => 'integration_overview',
|
||||
'title' => __( 'Overview', 'contact-form-7' ),
|
||||
'content' => $this->content( 'integration_overview' ),
|
||||
) );
|
||||
|
||||
$this->sidebar();
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private function content( $name ) {
|
||||
$content = array();
|
||||
|
||||
$content['list_overview'] = '<p>' . __( 'On this screen, you can manage contact forms provided by Contact Form 7. You can manage an unlimited number of contact forms. Each contact form has a unique ID and Contact Form 7 shortcode ([contact-form-7 ...]). To insert a contact form into a post or a text widget, insert the shortcode into the target.', 'contact-form-7' ) . '</p>';
|
||||
|
||||
$content['list_available_actions'] = '<p>' . __( 'Hovering over a row in the contact forms list will display action links that allow you to manage your contact form. You can perform the following actions:', 'contact-form-7' ) . '</p>';
|
||||
$content['list_available_actions'] .= '<p>' . __( '<strong>Edit</strong> - Navigates to the editing screen for that contact form. You can also reach that screen by clicking on the contact form title.', 'contact-form-7' ) . '</p>';
|
||||
$content['list_available_actions'] .= '<p>' . __( '<strong>Duplicate</strong> - Clones that contact form. A cloned contact form inherits all content from the original, but has a different ID.', 'contact-form-7' ) . '</p>';
|
||||
|
||||
$content['edit_overview'] = '<p>' . __( 'On this screen, you can edit a contact form. A contact form is comprised of the following components:', 'contact-form-7' ) . '</p>';
|
||||
$content['edit_overview'] .= '<p>' . __( '<strong>Title</strong> is the title of a contact form. This title is only used for labeling a contact form, and can be edited.', 'contact-form-7' ) . '</p>';
|
||||
$content['edit_overview'] .= '<p>' . __( '<strong>Form</strong> is a content of HTML form. You can use arbitrary HTML, which is allowed inside a form element. You can also use Contact Form 7’s form-tags here.', 'contact-form-7' ) . '</p>';
|
||||
$content['edit_overview'] .= '<p>' . __( '<strong>Mail</strong> manages a mail template (headers and message body) that this contact form will send when users submit it. You can use Contact Form 7’s mail-tags here.', 'contact-form-7' ) . '</p>';
|
||||
$content['edit_overview'] .= '<p>' . __( '<strong>Mail (2)</strong> is an additional mail template that works similar to Mail. Mail (2) is different in that it is sent only when Mail has been sent successfully.', 'contact-form-7' ) . '</p>';
|
||||
$content['edit_overview'] .= '<p>' . __( 'In <strong>Messages</strong>, you can edit various types of messages used for this contact form. These messages are relatively short messages, like a validation error message you see when you leave a required field blank.', 'contact-form-7' ) . '</p>';
|
||||
$content['edit_overview'] .= '<p>' . __( '<strong>Additional Settings</strong> provides a place where you can customize the behavior of this contact form by adding code snippets.', 'contact-form-7' ) . '</p>';
|
||||
|
||||
$content['edit_form_tags'] = '<p>' . __( 'A form-tag is a short code enclosed in square brackets used in a form content. A form-tag generally represents an input field, and its components can be separated into four parts: type, name, options, and values. Contact Form 7 supports several types of form-tags including text fields, number fields, date fields, checkboxes, radio buttons, menus, file-uploading fields, CAPTCHAs, and quiz fields.', 'contact-form-7' ) . '</p>';
|
||||
$content['edit_form_tags'] .= '<p>' . __( 'While form-tags have a comparatively complex syntax, you do not need to know the syntax to add form-tags because you can use the straightforward tag generator (<strong>Generate Tag</strong> button on this screen).', 'contact-form-7' ) . '</p>';
|
||||
|
||||
$content['edit_mail_tags'] = '<p>' . __( 'A mail-tag is also a short code enclosed in square brackets that you can use in every Mail and Mail (2) field. A mail-tag represents a user input value through an input field of a corresponding form-tag.', 'contact-form-7' ) . '</p>';
|
||||
$content['edit_mail_tags'] .= '<p>' . __( 'There are also special mail-tags that have specific names, but do not have corresponding form-tags. They are used to represent meta information of form submissions like the submitter’s IP address or the URL of the page.', 'contact-form-7' ) . '</p>';
|
||||
|
||||
$content['integration_overview'] = '<p>' . __( 'On this screen, you can manage services that are available through Contact Form 7. Using API will allow you to collaborate with any services that are available.', 'contact-form-7' ) . '</p>';
|
||||
$content['integration_overview'] .= '<p>' . __( 'You may need to first sign up for an account with the service that you plan to use. When you do so, you would need to authorize Contact Form 7 to access the service with your account.', 'contact-form-7' ) . '</p>';
|
||||
$content['integration_overview'] .= '<p>' . __( 'Any information you provide will not be shared with service providers without your authorization.', 'contact-form-7' ) . '</p>';
|
||||
|
||||
if ( ! empty( $content[$name] ) ) {
|
||||
return $content[$name];
|
||||
}
|
||||
}
|
||||
|
||||
public function sidebar() {
|
||||
$content = '<p><strong>' . __( 'For more information:', 'contact-form-7' ) . '</strong></p>';
|
||||
$content .= '<p>' . wpcf7_link( __( 'https://contactform7.com/docs/', 'contact-form-7' ), __( 'Docs', 'contact-form-7' ) ) . '</p>';
|
||||
$content .= '<p>' . wpcf7_link( __( 'https://contactform7.com/faq/', 'contact-form-7' ), __( 'FAQ', 'contact-form-7' ) ) . '</p>';
|
||||
$content .= '<p>' . wpcf7_link( __( 'https://contactform7.com/support/', 'contact-form-7' ), __( 'Support', 'contact-form-7' ) ) . '</p>';
|
||||
|
||||
$this->screen->set_help_sidebar( $content );
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
return array(
|
||||
'dependencies' => array(
|
||||
'wp-api-fetch',
|
||||
'wp-i18n',
|
||||
),
|
||||
'version' => WPCF7_VERSION,
|
||||
);
|
||||
@ -0,0 +1,627 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* The base class for form-tag generators management.
|
||||
*/
|
||||
class WPCF7_TagGenerator {
|
||||
|
||||
private static $instance;
|
||||
|
||||
private $panels = array();
|
||||
|
||||
private function __construct() {}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the singleton instance of this class.
|
||||
*/
|
||||
public static function get_instance() {
|
||||
if ( empty( self::$instance ) ) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds a form-tag generator instance.
|
||||
*/
|
||||
public function add( $id, $title, $callback, $options = '' ) {
|
||||
$id = trim( $id );
|
||||
|
||||
if (
|
||||
'' === $id or
|
||||
! wpcf7_is_name( $id ) or
|
||||
! is_callable( $callback )
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$options = wp_parse_args( $options, array(
|
||||
'version' => '1',
|
||||
) );
|
||||
|
||||
$this->panels[$id] = array(
|
||||
'title' => $title,
|
||||
'content' => 'tag-generator-panel-' . $id,
|
||||
'options' => $options,
|
||||
'callback' => $callback,
|
||||
);
|
||||
|
||||
if ( version_compare( $options['version'], '2', '<' ) ) {
|
||||
$message = sprintf(
|
||||
/* translators: 1: version, 2: tag generator title */
|
||||
__( 'Use of tag generator instances older than version 2 is deprecated. Version %1$s instance (%2$s) detected.', 'contact-form-7' ),
|
||||
$options['version'],
|
||||
$title
|
||||
);
|
||||
|
||||
wp_trigger_error( __METHOD__, $message, E_USER_DEPRECATED );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Renders form-tag generator calling buttons.
|
||||
*/
|
||||
public function print_buttons() {
|
||||
$formatter = new WPCF7_HTMLFormatter();
|
||||
|
||||
$formatter->append_start_tag( 'span', array(
|
||||
'id' => 'tag-generator-list',
|
||||
'class' => 'hide-if-no-js',
|
||||
) );
|
||||
|
||||
foreach ( (array) $this->panels as $panel ) {
|
||||
$formatter->append_start_tag( 'button', array(
|
||||
'type' => 'button',
|
||||
'data-taggen' => 'open-dialog',
|
||||
'data-target' => $panel['content'],
|
||||
'title' => sprintf(
|
||||
/* translators: %s: title of form-tag */
|
||||
__( 'Form-tag Generator: %s', 'contact-form-7' ),
|
||||
$panel['title']
|
||||
),
|
||||
) );
|
||||
|
||||
$formatter->append_preformatted( esc_html( $panel['title'] ) );
|
||||
}
|
||||
|
||||
$formatter->print();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Renders form-tag generator dialog panels (hidden until called).
|
||||
*/
|
||||
public function print_panels( WPCF7_ContactForm $contact_form ) {
|
||||
$formatter = new WPCF7_HTMLFormatter( array(
|
||||
'allowed_html' => array_merge( wpcf7_kses_allowed_html(), array(
|
||||
'dialog' => array(
|
||||
'id' => true,
|
||||
'class' => true,
|
||||
),
|
||||
'form' => array(
|
||||
'method' => true,
|
||||
'class' => true,
|
||||
'data-*' => true,
|
||||
),
|
||||
) ),
|
||||
) );
|
||||
|
||||
foreach ( (array) $this->panels as $id => $panel ) {
|
||||
$callback = $panel['callback'];
|
||||
|
||||
$options = array_merge( $panel['options'], array(
|
||||
'id' => $id,
|
||||
'title' => $panel['title'],
|
||||
'content' => $panel['content'],
|
||||
) );
|
||||
|
||||
if ( is_callable( $callback ) ) {
|
||||
$formatter->append_start_tag( 'dialog', array(
|
||||
'id' => $options['content'],
|
||||
'class' => 'tag-generator-dialog',
|
||||
) );
|
||||
|
||||
$formatter->append_start_tag( 'button', array(
|
||||
'class' => 'close-button',
|
||||
'title' => __( 'Close this dialog box', 'contact-form-7' ),
|
||||
'data-taggen' => 'close-dialog',
|
||||
) );
|
||||
|
||||
$formatter->append_preformatted(
|
||||
esc_html( __( 'Close', 'contact-form-7' ) )
|
||||
);
|
||||
|
||||
$formatter->end_tag( 'button' );
|
||||
|
||||
$formatter->append_start_tag( 'form', array(
|
||||
'method' => 'dialog',
|
||||
'class' => 'tag-generator-panel',
|
||||
'data-id' => $options['id'],
|
||||
'data-version' => $options['version'],
|
||||
) );
|
||||
|
||||
$formatter->call_user_func( $callback, $contact_form, $options );
|
||||
|
||||
$formatter->close_all_tags();
|
||||
}
|
||||
}
|
||||
|
||||
$formatter->print();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Class helps to implement a form-tag generator content.
|
||||
*/
|
||||
class WPCF7_TagGeneratorGenerator {
|
||||
|
||||
private $key = '';
|
||||
|
||||
|
||||
/**
|
||||
* The constructor.
|
||||
*/
|
||||
public function __construct( $key ) {
|
||||
$this->key = $key;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a unique reference ID.
|
||||
*/
|
||||
public function ref( $suffix = '' ) {
|
||||
$ref = sprintf( '%s-%s', $this->key, $suffix );
|
||||
$ref = strtolower( $ref );
|
||||
$ref = preg_replace( '/[^0-9a-z-]/', '', $ref );
|
||||
$ref = preg_replace( '/[-]+/', '-', $ref );
|
||||
$ref = trim( $ref, '-' );
|
||||
return $ref;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Calls one of the template methods.
|
||||
*/
|
||||
public function print( $part, $options = '' ) {
|
||||
if ( is_callable( array( $this, $part ) ) ) {
|
||||
call_user_func( array( $this, $part ), $options );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Template method for field type field.
|
||||
*/
|
||||
private function field_type( $options = '' ) {
|
||||
$options = wp_parse_args( $options, array(
|
||||
'with_required' => false,
|
||||
'with_optional' => false,
|
||||
'select_options' => array(),
|
||||
) );
|
||||
|
||||
$formatter = new WPCF7_HTMLFormatter();
|
||||
|
||||
$formatter->append_start_tag( 'fieldset' );
|
||||
|
||||
$formatter->append_start_tag( 'legend', array(
|
||||
'id' => $this->ref( 'type-legend' ),
|
||||
) );
|
||||
|
||||
$formatter->append_preformatted(
|
||||
esc_html( __( 'Field type', 'contact-form-7' ) )
|
||||
);
|
||||
|
||||
$formatter->end_tag( 'legend' );
|
||||
|
||||
$formatter->append_start_tag( 'select', array(
|
||||
'data-tag-part' => 'basetype',
|
||||
'aria-labelledby' => $this->ref( 'type-legend' ),
|
||||
) );
|
||||
|
||||
foreach ( (array) $options['select_options'] as $basetype => $title ) {
|
||||
$formatter->append_start_tag( 'option', array(
|
||||
'value' => $basetype,
|
||||
) );
|
||||
|
||||
$formatter->append_preformatted( esc_html( $title ) );
|
||||
}
|
||||
|
||||
$formatter->end_tag( 'select' );
|
||||
|
||||
if ( $options['with_required'] ) {
|
||||
$formatter->append_start_tag( 'br' );
|
||||
$formatter->append_start_tag( 'label' );
|
||||
|
||||
$formatter->append_start_tag( 'input', array(
|
||||
'type' => 'checkbox',
|
||||
'data-tag-part' => 'type-suffix',
|
||||
'value' => '*',
|
||||
) );
|
||||
|
||||
$formatter->append_whitespace();
|
||||
|
||||
$formatter->append_preformatted(
|
||||
esc_html( __( 'This is a required field.', 'contact-form-7' ) )
|
||||
);
|
||||
}
|
||||
|
||||
if ( $options['with_optional'] ) {
|
||||
$formatter->append_start_tag( 'br' );
|
||||
$formatter->append_start_tag( 'label' );
|
||||
|
||||
$formatter->append_start_tag( 'input', array(
|
||||
'type' => 'checkbox',
|
||||
'data-tag-part' => 'option',
|
||||
'data-tag-option' => 'optional',
|
||||
'checked' => true,
|
||||
) );
|
||||
|
||||
$formatter->append_whitespace();
|
||||
|
||||
$formatter->append_preformatted(
|
||||
esc_html( __( 'This checkbox is optional.', 'contact-form-7' ) )
|
||||
);
|
||||
}
|
||||
|
||||
$formatter->print();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Template method for field name field.
|
||||
*/
|
||||
private function field_name( $options = '' ) {
|
||||
$options = wp_parse_args( $options, array(
|
||||
'ask_if' => '',
|
||||
) );
|
||||
|
||||
?>
|
||||
<fieldset>
|
||||
<legend id="<?php echo esc_attr( $this->ref( 'name-legend' ) ); ?>"><?php
|
||||
echo esc_html( __( 'Field name', 'contact-form-7' ) );
|
||||
?></legend>
|
||||
<input type="text" data-tag-part="name" pattern="[A-Za-z][A-Za-z0-9_\-]*" aria-labelledby="<?php echo esc_attr( $this->ref( 'name-legend' ) ); ?>" />
|
||||
|
||||
<?php
|
||||
$tag_option = $label = '';
|
||||
|
||||
if ( 'author_name' === $options['ask_if'] ) {
|
||||
$tag_option = 'autocomplete:name';
|
||||
|
||||
if ( wpcf7_akismet_is_available() ) {
|
||||
$tag_option .= ' akismet:author';
|
||||
}
|
||||
|
||||
$label = __( "This field expects the submitter name.", 'contact-form-7' );
|
||||
} elseif ( 'author_email' === $options['ask_if'] ) {
|
||||
$tag_option = 'autocomplete:email';
|
||||
|
||||
if ( wpcf7_akismet_is_available() ) {
|
||||
$tag_option .= ' akismet:author_email';
|
||||
}
|
||||
|
||||
$label = __( "This field expects the submitter email.", 'contact-form-7' );
|
||||
} elseif ( 'author_url' === $options['ask_if'] ) {
|
||||
$tag_option = 'autocomplete:url';
|
||||
|
||||
if ( wpcf7_akismet_is_available() ) {
|
||||
$tag_option .= ' akismet:author_url';
|
||||
}
|
||||
|
||||
$label = __( "This field expects the submitter URL.", 'contact-form-7' );
|
||||
} elseif ( 'author_tel' === $options['ask_if'] ) {
|
||||
$tag_option = 'autocomplete:tel';
|
||||
$label = __( "This field expects the submitter telephone number.", 'contact-form-7' );
|
||||
}
|
||||
|
||||
if ( $tag_option ) {
|
||||
?>
|
||||
<br />
|
||||
<label>
|
||||
<input type="checkbox" data-tag-part="option" data-tag-option="<?php echo esc_attr( $tag_option ); ?>" />
|
||||
<?php echo esc_html( $label ); ?>
|
||||
</label>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</fieldset>
|
||||
<?php
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Template method for ID attribute option field.
|
||||
*/
|
||||
private function id_attr( $options = '' ) {
|
||||
?>
|
||||
<fieldset>
|
||||
<legend id="<?php echo esc_attr( $this->ref( 'id-legend' ) ); ?>"><?php
|
||||
echo esc_html( __( 'ID attribute', 'contact-form-7' ) );
|
||||
?></legend>
|
||||
<input type="text" data-tag-part="option" data-tag-option="id:" pattern="[A-Za-z][A-Za-z0-9_\-]*" aria-labelledby="<?php echo esc_attr( $this->ref( 'id-legend' ) ); ?>" />
|
||||
</fieldset>
|
||||
<?php
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Template method for class attribute option field.
|
||||
*/
|
||||
private function class_attr( $options = '' ) {
|
||||
?>
|
||||
<fieldset>
|
||||
<legend id="<?php echo esc_attr( $this->ref( 'class-legend' ) ); ?>"><?php
|
||||
echo esc_html( __( 'Class attribute', 'contact-form-7' ) );
|
||||
?></legend>
|
||||
<input type="text" data-tag-part="option" data-tag-option="class:" pattern="[A-Za-z0-9_\-\s]*" aria-labelledby="<?php echo esc_attr( $this->ref( 'class-legend' ) ); ?>" />
|
||||
</fieldset>
|
||||
<?php
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Template method for min/max options.
|
||||
*/
|
||||
private function min_max( $options = '' ) {
|
||||
$options = wp_parse_args( $options, array(
|
||||
'type' => 'number',
|
||||
'title' => __( 'Length', 'contact-form-7' ),
|
||||
'min_option' => 'minlength:',
|
||||
'max_option' => 'maxlength:',
|
||||
'accept_minus' => false,
|
||||
) );
|
||||
|
||||
$formatter = new WPCF7_HTMLFormatter();
|
||||
|
||||
$formatter->append_start_tag( 'fieldset' );
|
||||
|
||||
$formatter->append_start_tag( 'legend' );
|
||||
$formatter->append_preformatted( esc_html( $options['title'] ) );
|
||||
$formatter->end_tag( 'legend' );
|
||||
|
||||
$formatter->append_start_tag( 'label' );
|
||||
|
||||
$formatter->append_preformatted(
|
||||
esc_html( __( 'Min', 'contact-form-7' ) )
|
||||
);
|
||||
|
||||
$formatter->append_whitespace();
|
||||
|
||||
$formatter->append_start_tag( 'input', array(
|
||||
'type' => $options['type'],
|
||||
'data-tag-part' => 'option',
|
||||
'data-tag-option' => $options['min_option'],
|
||||
'min' => $options['accept_minus'] ? null : 0,
|
||||
) );
|
||||
|
||||
$formatter->end_tag( 'label' );
|
||||
|
||||
$formatter->append_preformatted( ' ⇔ ' );
|
||||
|
||||
$formatter->append_start_tag( 'label' );
|
||||
|
||||
$formatter->append_preformatted(
|
||||
esc_html( __( 'Max', 'contact-form-7' ) )
|
||||
);
|
||||
|
||||
$formatter->append_whitespace();
|
||||
|
||||
$formatter->append_start_tag( 'input', array(
|
||||
'type' => $options['type'],
|
||||
'data-tag-part' => 'option',
|
||||
'data-tag-option' => $options['max_option'],
|
||||
'min' => $options['accept_minus'] ? null : 0,
|
||||
) );
|
||||
|
||||
$formatter->end_tag( 'label' );
|
||||
|
||||
$formatter->print();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Template method for default value field.
|
||||
*/
|
||||
private function default_value( $options = '' ) {
|
||||
$options = wp_parse_args( $options, array(
|
||||
'type' => 'text',
|
||||
'title' => __( 'Default value', 'contact-form-7' ),
|
||||
'with_placeholder' => false,
|
||||
'use_content' => false,
|
||||
) );
|
||||
|
||||
$formatter = new WPCF7_HTMLFormatter();
|
||||
|
||||
$formatter->append_start_tag( 'fieldset' );
|
||||
|
||||
$formatter->append_start_tag( 'legend', array(
|
||||
'id' => $this->ref( 'value-legend' ),
|
||||
) );
|
||||
|
||||
$formatter->append_preformatted( esc_html( $options['title'] ) );
|
||||
|
||||
$formatter->end_tag( 'legend' );
|
||||
|
||||
$formatter->append_start_tag( 'input', array(
|
||||
'type' => $options['type'],
|
||||
'data-tag-part' => $options['use_content'] ? 'content' : 'value',
|
||||
'aria-labelledby' => $this->ref( 'value-legend' ),
|
||||
) );
|
||||
|
||||
if ( $options['with_placeholder'] ) {
|
||||
$formatter->append_start_tag( 'br' );
|
||||
$formatter->append_start_tag( 'label' );
|
||||
|
||||
$formatter->append_start_tag( 'input', array(
|
||||
'type' => 'checkbox',
|
||||
'data-tag-part' => 'option',
|
||||
'data-tag-option' => 'placeholder',
|
||||
) );
|
||||
|
||||
$formatter->append_whitespace();
|
||||
|
||||
$formatter->append_preformatted(
|
||||
esc_html( __( 'Use this text as the placeholder.', 'contact-form-7' ) )
|
||||
);
|
||||
}
|
||||
|
||||
$formatter->print();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Template method for selectable values useful for checkboxes or a menu.
|
||||
*/
|
||||
private function selectable_values( $options = '' ) {
|
||||
$options = wp_parse_args( $options, array(
|
||||
'first_as_label' => false,
|
||||
'use_label_element' => false,
|
||||
) );
|
||||
|
||||
$formatter = new WPCF7_HTMLFormatter();
|
||||
|
||||
$formatter->append_start_tag( 'fieldset' );
|
||||
|
||||
$formatter->append_start_tag( 'legend', array(
|
||||
'id' => $this->ref( 'selectable-values-legend' ),
|
||||
) );
|
||||
|
||||
$formatter->append_preformatted(
|
||||
esc_html( __( 'Selectable values', 'contact-form-7' ) )
|
||||
);
|
||||
|
||||
$formatter->end_tag( 'legend' );
|
||||
|
||||
$formatter->append_start_tag( 'span', array(
|
||||
'id' => $this->ref( 'selectable-values-description' ),
|
||||
) );
|
||||
|
||||
$formatter->append_preformatted(
|
||||
esc_html( __( 'One item per line.', 'contact-form-7' ) )
|
||||
);
|
||||
|
||||
$formatter->end_tag( 'span' );
|
||||
|
||||
$formatter->append_start_tag( 'br' );
|
||||
|
||||
$formatter->append_start_tag( 'textarea', array(
|
||||
'required' => true,
|
||||
'data-tag-part' => 'value',
|
||||
'aria-labelledby' => $this->ref( 'selectable-values-legend' ),
|
||||
'aria-describedby' => $this->ref( 'selectable-values-description' ),
|
||||
) );
|
||||
|
||||
$formatter->append_preformatted(
|
||||
esc_html( __( "Option 1\nOption 2\nOption 3", 'contact-form-7' ) )
|
||||
);
|
||||
|
||||
$formatter->end_tag( 'textarea' );
|
||||
|
||||
if ( $options['first_as_label'] ) {
|
||||
$formatter->append_start_tag( 'br' );
|
||||
$formatter->append_start_tag( 'label' );
|
||||
|
||||
$formatter->append_start_tag( 'input', array(
|
||||
'type' => 'checkbox',
|
||||
'checked' => 'checked' === $options['first_as_label'],
|
||||
'data-tag-part' => 'option',
|
||||
'data-tag-option' => 'first_as_label',
|
||||
) );
|
||||
|
||||
$formatter->append_whitespace();
|
||||
|
||||
$formatter->append_preformatted(
|
||||
esc_html( __( 'Use the first item as a label.', 'contact-form-7' ) )
|
||||
);
|
||||
|
||||
$formatter->end_tag( 'label' );
|
||||
}
|
||||
|
||||
if ( $options['use_label_element'] ) {
|
||||
$formatter->append_start_tag( 'br' );
|
||||
$formatter->append_start_tag( 'label' );
|
||||
|
||||
$formatter->append_start_tag( 'input', array(
|
||||
'type' => 'checkbox',
|
||||
'checked' => 'checked' === $options['use_label_element'],
|
||||
'data-tag-part' => 'option',
|
||||
'data-tag-option' => 'use_label_element',
|
||||
) );
|
||||
|
||||
$formatter->append_whitespace();
|
||||
|
||||
$formatter->append_preformatted(
|
||||
esc_html( __( 'Wrap each item with a label element.', 'contact-form-7' ) )
|
||||
);
|
||||
|
||||
$formatter->end_tag( 'label' );
|
||||
}
|
||||
|
||||
$formatter->print();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Template method for insert-box content including the result form-tag.
|
||||
*/
|
||||
private function insert_box_content( $options = '' ) {
|
||||
$formatter = new WPCF7_HTMLFormatter();
|
||||
|
||||
$formatter->append_start_tag( 'div', array(
|
||||
'class' => 'flex-container',
|
||||
) );
|
||||
|
||||
$formatter->append_start_tag( 'input', array(
|
||||
'type' => 'text',
|
||||
'class' => 'code selectable',
|
||||
'readonly' => true,
|
||||
'data-tag-part' => 'tag',
|
||||
'aria-label' => __( 'The form-tag to be inserted into the form template', 'contact-form-7' ),
|
||||
) );
|
||||
|
||||
$formatter->append_whitespace();
|
||||
|
||||
$formatter->append_start_tag( 'button', array(
|
||||
'type' => 'button',
|
||||
'class' => 'button button-primary',
|
||||
'data-taggen' => 'insert-tag',
|
||||
) );
|
||||
|
||||
$formatter->append_preformatted(
|
||||
esc_html( __( 'Insert Tag', 'contact-form-7' ) )
|
||||
);
|
||||
|
||||
$formatter->end_tag( 'button' );
|
||||
|
||||
$formatter->print();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Template method for a tip message about mail-tag.
|
||||
*/
|
||||
private function mail_tag_tip( $options = '' ) {
|
||||
$formatter = new WPCF7_HTMLFormatter();
|
||||
|
||||
$formatter->append_start_tag( 'p', array(
|
||||
'class' => 'mail-tag-tip',
|
||||
) );
|
||||
|
||||
$formatter->append_preformatted( sprintf(
|
||||
/* translators: %s: mail-tag corresponding to the form-tag */
|
||||
esc_html( __( 'To use the user input in the email, insert the corresponding mail-tag %s into the email template.', 'contact-form-7' ) ),
|
||||
'<strong data-tag-part="mail-tag"></strong>'
|
||||
) );
|
||||
|
||||
$formatter->print();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,280 @@
|
||||
<?php
|
||||
|
||||
abstract class WPCF7_WelcomePanelColumn {
|
||||
|
||||
abstract protected function icon();
|
||||
abstract protected function title();
|
||||
abstract protected function content();
|
||||
|
||||
public function print_content() {
|
||||
$content = $this->content();
|
||||
|
||||
if ( is_array( $content ) ) {
|
||||
$content = implode( "\n\n", $content );
|
||||
}
|
||||
|
||||
$content = wp_kses_post( $content );
|
||||
$content = wptexturize( $content );
|
||||
$content = convert_chars( $content );
|
||||
$content = wpautop( $content );
|
||||
|
||||
$formatter = new WPCF7_HTMLFormatter();
|
||||
|
||||
$formatter->append_start_tag( 'div', array(
|
||||
'class' => 'welcome-panel-column',
|
||||
) );
|
||||
|
||||
$formatter->append_start_tag( 'h3' );
|
||||
|
||||
$formatter->append_start_tag( 'span', array(
|
||||
'class' => sprintf( 'dashicons dashicons-%s', $this->icon() ),
|
||||
'aria-hidden' => 'true',
|
||||
) );
|
||||
|
||||
$formatter->end_tag( 'span' );
|
||||
|
||||
$formatter->append_whitespace();
|
||||
|
||||
$formatter->append_preformatted( $this->title() );
|
||||
|
||||
$formatter->end_tag( 'h3' );
|
||||
|
||||
$formatter->append_preformatted( $content );
|
||||
|
||||
$formatter->print();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class WPCF7_WelcomePanelColumn_AntiSpam extends WPCF7_WelcomePanelColumn {
|
||||
|
||||
protected function icon() {
|
||||
return 'shield';
|
||||
}
|
||||
|
||||
protected function title() {
|
||||
return __( 'Getting spammed? You have protection.', 'contact-form-7' );
|
||||
}
|
||||
|
||||
protected function content() {
|
||||
return array(
|
||||
__( 'Spammers target everything; your contact forms are not an exception. Before you get spammed, protect your contact forms with the powerful anti-spam features Contact Form 7 provides.', 'contact-form-7' ),
|
||||
sprintf(
|
||||
/* translators: 1: URL to support page about Akismet, 2: Cloudflare Turnstile, 3: Disallowed list */
|
||||
__( 'Contact Form 7 supports spam-filtering with <a href="%1$s">Akismet</a>. <a href="%2$s">Cloudflare Turnstile</a> blocks annoying spambots. Plus, using <a href="%3$s">disallowed list</a>, you can block messages containing specified keywords or those sent from specified IP addresses.', 'contact-form-7' ),
|
||||
__( 'https://contactform7.com/spam-filtering-with-akismet/', 'contact-form-7' ),
|
||||
__( 'https://contactform7.com/turnstile-integration/', 'contact-form-7' ),
|
||||
__( 'https://contactform7.com/comment-blacklist/', 'contact-form-7' )
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class WPCF7_WelcomePanelColumn_Donation extends WPCF7_WelcomePanelColumn {
|
||||
|
||||
protected function icon() {
|
||||
return 'megaphone';
|
||||
}
|
||||
|
||||
protected function title() {
|
||||
return __( 'Contact Form 7 needs your support.', 'contact-form-7' );
|
||||
}
|
||||
|
||||
protected function content() {
|
||||
return array(
|
||||
__( 'It is hard to continue to maintain this plugin without support from users like you.', 'contact-form-7' ),
|
||||
sprintf(
|
||||
/* translators: %s: URL to support page about ways to contribute */
|
||||
__( 'There are several ways for you to <a href="%s">contribute to the project</a>: testing, coding, translating it into your local languages, helping other users, financial donations, etc, etc. We equally welcome you regardless of the way you contribute.', 'contact-form-7' ),
|
||||
__( 'https://contactform7.com/contributing/', 'contact-form-7' )
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class WPCF7_WelcomePanelColumn_Flamingo extends WPCF7_WelcomePanelColumn {
|
||||
|
||||
protected function icon() {
|
||||
return 'editor-help';
|
||||
}
|
||||
|
||||
protected function title() {
|
||||
return __( 'Before you cry over spilt mail…', 'contact-form-7' );
|
||||
}
|
||||
|
||||
protected function content() {
|
||||
return array(
|
||||
__( 'Contact Form 7 does not store submitted messages anywhere. Therefore, you may lose important messages forever if your mail server has issues or you make a mistake in mail configuration.', 'contact-form-7' ),
|
||||
sprintf(
|
||||
/* translators: %s: URL to support page about the Flamingo plugin */
|
||||
__( 'Install a message storage plugin before this happens to you. <a href="%s">Flamingo</a> saves all messages through contact forms into the database. Flamingo is a free WordPress plugin created by the same author as Contact Form 7.', 'contact-form-7' ),
|
||||
__( 'https://contactform7.com/save-submitted-messages-with-flamingo/', 'contact-form-7' )
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class WPCF7_WelcomePanelColumn_Integration extends WPCF7_WelcomePanelColumn {
|
||||
|
||||
protected function icon() {
|
||||
return 'superhero-alt';
|
||||
}
|
||||
|
||||
protected function title() {
|
||||
return __( 'You have strong allies to back you up.', 'contact-form-7' );
|
||||
}
|
||||
|
||||
protected function content() {
|
||||
return array(
|
||||
sprintf(
|
||||
/* translators: %s: URL to support page about the Brevo integration */
|
||||
__( 'Your contact forms will become more powerful and versatile by integrating them with external APIs. With CRM and email marketing services, you can build your own contact lists (<a href="%s">Brevo</a>).', 'contact-form-7' ),
|
||||
__( 'https://contactform7.com/sendinblue-integration/', 'contact-form-7' )
|
||||
),
|
||||
sprintf(
|
||||
/* translators: 1: URL to support page about Cloudflare Turnstile, 2: Stripe */
|
||||
__( 'With help from cloud-based machine learning, anti-spam services will protect your forms (<a href="%1$s">Cloudflare Turnstile</a>). Even payment services are natively supported (<a href="%2$s">Stripe</a>).', 'contact-form-7' ),
|
||||
__( 'https://contactform7.com/turnstile-integration/', 'contact-form-7' ),
|
||||
__( 'https://contactform7.com/stripe-integration/', 'contact-form-7' )
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function wpcf7_welcome_panel() {
|
||||
$columns = array();
|
||||
|
||||
$flamingo_is_active = defined( 'FLAMINGO_VERSION' );
|
||||
|
||||
$sendinblue_is_active = false;
|
||||
|
||||
if (
|
||||
class_exists( 'WPCF7_Sendinblue' ) and
|
||||
$sendinblue = WPCF7_Sendinblue::get_instance()
|
||||
) {
|
||||
$sendinblue_is_active = $sendinblue->is_active();
|
||||
}
|
||||
|
||||
if ( $flamingo_is_active and $sendinblue_is_active ) {
|
||||
$columns[] = new WPCF7_WelcomePanelColumn_AntiSpam();
|
||||
$columns[] = new WPCF7_WelcomePanelColumn_Donation();
|
||||
} elseif ( $flamingo_is_active ) {
|
||||
$columns[] = new WPCF7_WelcomePanelColumn_Integration();
|
||||
$columns[] = new WPCF7_WelcomePanelColumn_AntiSpam();
|
||||
} elseif ( $sendinblue_is_active ) {
|
||||
$columns[] = new WPCF7_WelcomePanelColumn_Flamingo();
|
||||
$columns[] = new WPCF7_WelcomePanelColumn_AntiSpam();
|
||||
} else {
|
||||
$columns[] = new WPCF7_WelcomePanelColumn_Flamingo();
|
||||
$columns[] = new WPCF7_WelcomePanelColumn_Integration();
|
||||
}
|
||||
|
||||
$classes = 'wpcf7-welcome-panel';
|
||||
|
||||
$vers = (array) get_user_meta( get_current_user_id(),
|
||||
'wpcf7_hide_welcome_panel_on', true
|
||||
);
|
||||
|
||||
if ( wpcf7_version_grep( wpcf7_version( 'only_major=1' ), $vers ) ) {
|
||||
$classes .= ' hidden';
|
||||
}
|
||||
|
||||
?>
|
||||
<div id="wpcf7-welcome-panel" class="<?php echo esc_attr( $classes ); ?>">
|
||||
<?php wp_nonce_field( 'wpcf7-welcome-panel-nonce', 'welcomepanelnonce', false ); ?>
|
||||
<a class="welcome-panel-close" href="<?php echo esc_url( menu_page_url( 'wpcf7', false ) ); ?>"><?php echo esc_html( __( 'Dismiss', 'contact-form-7' ) ); ?></a>
|
||||
|
||||
<div class="welcome-panel-content">
|
||||
<div class="welcome-panel-column-container">
|
||||
<?php
|
||||
|
||||
foreach ( $columns as $column ) {
|
||||
$column->print_content();
|
||||
}
|
||||
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
|
||||
add_action(
|
||||
'wp_ajax_wpcf7-update-welcome-panel',
|
||||
'wpcf7_admin_ajax_welcome_panel',
|
||||
10, 0
|
||||
);
|
||||
|
||||
function wpcf7_admin_ajax_welcome_panel() {
|
||||
check_ajax_referer( 'wpcf7-welcome-panel-nonce', 'welcomepanelnonce' );
|
||||
|
||||
$vers = get_user_meta( get_current_user_id(),
|
||||
'wpcf7_hide_welcome_panel_on', true
|
||||
);
|
||||
|
||||
if ( empty( $vers ) or ! is_array( $vers ) ) {
|
||||
$vers = array();
|
||||
}
|
||||
|
||||
if ( empty( $_POST['visible'] ) ) {
|
||||
$vers[] = wpcf7_version( 'only_major=1' );
|
||||
} else {
|
||||
$vers = array_diff( $vers, array( wpcf7_version( 'only_major=1' ) ) );
|
||||
}
|
||||
|
||||
$vers = array_unique( $vers );
|
||||
|
||||
update_user_meta( get_current_user_id(),
|
||||
'wpcf7_hide_welcome_panel_on', $vers
|
||||
);
|
||||
|
||||
wp_die( 1 );
|
||||
}
|
||||
|
||||
|
||||
add_filter(
|
||||
'screen_settings',
|
||||
'wpcf7_welcome_panel_screen_settings',
|
||||
10, 2
|
||||
);
|
||||
|
||||
function wpcf7_welcome_panel_screen_settings( $screen_settings, $screen ) {
|
||||
|
||||
if ( 'toplevel_page_wpcf7' !== $screen->id ) {
|
||||
return $screen_settings;
|
||||
}
|
||||
|
||||
$vers = (array) get_user_meta( get_current_user_id(),
|
||||
'wpcf7_hide_welcome_panel_on', true
|
||||
);
|
||||
|
||||
$checkbox_id = 'wpcf7-welcome-panel-show';
|
||||
$checked = ! in_array( wpcf7_version( 'only_major=1' ), $vers, true );
|
||||
|
||||
$checkbox = sprintf(
|
||||
'<input %s />',
|
||||
wpcf7_format_atts( array(
|
||||
'id' => $checkbox_id,
|
||||
'type' => 'checkbox',
|
||||
'checked' => $checked,
|
||||
) )
|
||||
);
|
||||
|
||||
$screen_settings .= sprintf( '
|
||||
<fieldset class="wpcf7-welcome-panel-options">
|
||||
<legend>%1$s</legend>
|
||||
<label for="%2$s">%3$s %4$s</label>
|
||||
</fieldset>',
|
||||
esc_html( __( 'Welcome panel', 'contact-form-7' ) ),
|
||||
esc_attr( $checkbox_id ),
|
||||
$checkbox,
|
||||
esc_html( __( 'Show welcome panel', 'contact-form-7' ) )
|
||||
);
|
||||
|
||||
return $screen_settings;
|
||||
}
|
||||
BIN
wp-content/plugins/contact-form-7/assets/icon.png
Normal file
|
After Width: | Height: | Size: 29 KiB |
1
wp-content/plugins/contact-form-7/assets/icon.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 242.5 239.46"><defs><style>.cls-1,.cls-6{fill:none;}.cls-2{clip-path:url(#clip-path);}.cls-3{fill:#33c6f4;}.cls-4{fill:#1b447e;}.cls-5{fill:#fff;}.cls-6{stroke:#221e1f;stroke-miterlimit:10;stroke-width:7.16px;}</style><clipPath id="clip-path" transform="translate(1.72)"><circle class="cls-1" cx="119.73" cy="119.73" r="116.15"/></clipPath></defs><g id="Layer_2" data-name="Layer 2"><g id="Layer_1" data-name="Layer 1"><g class="cls-2"><circle class="cls-3" cx="121.45" cy="119.73" r="116.15"/><path class="cls-4" d="M239.32,167.79c-53.41-24-108.37-91.46-113-94.55s-10.84.77-10.84.77c-3.87-6.19-10.06.77-10.06.77C76.77,123.55.14,170.11.14,170.11S36.94,237.79,122,237.79C208.48,237.79,239.32,167.79,239.32,167.79Z" transform="translate(1.72)"/><path class="cls-5" d="M67.48,116.58s15.48-7,12.38,4.65-15.48,28.64-11.61,29.41S83,140.58,86.06,142.12s5.42.78,3.87,6.2-3.1,9.29,0,9.29,5.42-7,9.29-13.94,10.06-3.87,12.38-1.55,9.29,15.49,14.71,13.94,8.51-8.52,6.19-24,1.55-20.12,1.55-20.12,4.64-2.32,13.16,8.51,24,27.09,26.31,26.32-10.83-17.8-7.74-19.35,15.48,2.32,21.68,7.74c0,0,2.12,8.87,2.12.36L126.31,73.24,115.47,74l-10.06.77S80.64,111.94,67.48,116.58Z" transform="translate(1.72)"/><path class="cls-6" d="M239.32,170.11c-53.41-24-108.37-93.78-113-96.87s-10.84.77-10.84.77c-3.87-6.19-10.06.77-10.06.77C76.77,123.55.14,170.11.14,170.11" transform="translate(1.72)"/></g><circle class="cls-6" cx="121.45" cy="119.73" r="116.15"/></g></g></svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
add_action(
|
||||
'init',
|
||||
'wpcf7_init_block_editor_assets',
|
||||
10, 0
|
||||
);
|
||||
|
||||
function wpcf7_init_block_editor_assets() {
|
||||
register_block_type(
|
||||
wpcf7_plugin_path( 'includes/block-editor' )
|
||||
);
|
||||
}
|
||||
@ -0,0 +1,38 @@
|
||||
{
|
||||
"$schema": "https://schemas.wp.org/trunk/block.json",
|
||||
"apiVersion": 3,
|
||||
"name": "contact-form-7/contact-form-selector",
|
||||
"title": "Contact Form 7",
|
||||
"category": "widgets",
|
||||
"description": "Insert a contact form you have created with Contact Form 7.",
|
||||
"keywords": [ "form" ],
|
||||
"textdomain": "contact-form-7",
|
||||
"attributes": {
|
||||
"id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"hash": {
|
||||
"type": "string"
|
||||
},
|
||||
"title": {
|
||||
"type": "string"
|
||||
},
|
||||
"htmlId": {
|
||||
"type": "string"
|
||||
},
|
||||
"htmlName": {
|
||||
"type": "string"
|
||||
},
|
||||
"htmlTitle": {
|
||||
"type": "string"
|
||||
},
|
||||
"htmlClass": {
|
||||
"type": "string"
|
||||
},
|
||||
"output": {
|
||||
"enum": [ "form", "raw_form" ],
|
||||
"default": "form"
|
||||
}
|
||||
},
|
||||
"editorScript": [ "file:./index.js", "contact-form-7-block-editor" ]
|
||||
}
|
||||
@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
return array(
|
||||
'dependencies' => array(
|
||||
'react-jsx-runtime',
|
||||
'wp-api-fetch',
|
||||
'wp-block-editor',
|
||||
'wp-blocks',
|
||||
'wp-components',
|
||||
'wp-element',
|
||||
'wp-i18n',
|
||||
'wp-url',
|
||||
),
|
||||
'version' => WPCF7_VERSION,
|
||||
);
|
||||
26
wp-content/plugins/contact-form-7/includes/capabilities.php
Normal file
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
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;
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
add_action(
|
||||
'wpcf7_update_option',
|
||||
'wpcf7_config_validator_update_option',
|
||||
10, 3
|
||||
);
|
||||
|
||||
/**
|
||||
* Runs bulk validation after the reCAPTCHA integration option is updated.
|
||||
*/
|
||||
function wpcf7_config_validator_update_option( $name, $value, $old_option ) {
|
||||
if ( 'recaptcha' === $name ) {
|
||||
$contact_forms = WPCF7_ContactForm::find();
|
||||
|
||||
$options = array(
|
||||
'include' => 'unsafe_email_without_protection',
|
||||
);
|
||||
|
||||
foreach ( $contact_forms as $contact_form ) {
|
||||
$config_validator = new WPCF7_ConfigValidator( $contact_form, $options );
|
||||
$config_validator->restore();
|
||||
$config_validator->validate();
|
||||
$config_validator->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
trait WPCF7_ConfigValidator_AdditionalSettings {
|
||||
|
||||
/**
|
||||
* Runs error detection for the additional settings section.
|
||||
*/
|
||||
public function validate_additional_settings() {
|
||||
$section = 'additional_settings.body';
|
||||
|
||||
if ( $this->supports( 'deprecated_settings' ) ) {
|
||||
$deprecated_settings_used =
|
||||
$this->contact_form->additional_setting( 'on_sent_ok' ) ||
|
||||
$this->contact_form->additional_setting( 'on_submit' );
|
||||
|
||||
if ( $deprecated_settings_used ) {
|
||||
$this->add_error( $section, 'deprecated_settings',
|
||||
array(
|
||||
'message' => __( 'Deprecated settings are used.', 'contact-form-7' ),
|
||||
)
|
||||
);
|
||||
} else {
|
||||
$this->remove_error( $section, 'deprecated_settings' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,278 @@
|
||||
<?php
|
||||
|
||||
trait WPCF7_ConfigValidator_Form {
|
||||
|
||||
/**
|
||||
* Runs error detection for the form section.
|
||||
*/
|
||||
public function validate_form() {
|
||||
$section = 'form.body';
|
||||
$form = $this->contact_form->prop( 'form' );
|
||||
|
||||
if ( $this->supports( 'multiple_controls_in_label' ) ) {
|
||||
if ( $this->detect_multiple_controls_in_label( $section, $form ) ) {
|
||||
$this->add_error( $section, 'multiple_controls_in_label',
|
||||
array(
|
||||
'message' => __( 'Multiple form controls are in a single label element.', 'contact-form-7' ),
|
||||
)
|
||||
);
|
||||
} else {
|
||||
$this->remove_error( $section, 'multiple_controls_in_label' );
|
||||
}
|
||||
}
|
||||
|
||||
if ( $this->supports( 'unavailable_names' ) ) {
|
||||
$ng_names = $this->detect_unavailable_names( $section, $form );
|
||||
|
||||
if ( $ng_names ) {
|
||||
$this->add_error( $section, 'unavailable_names',
|
||||
array(
|
||||
'message' =>
|
||||
/* translators: %names%: a list of form control names */
|
||||
__( 'Unavailable names (%names%) are used for form controls.', 'contact-form-7' ),
|
||||
'params' => array( 'names' => implode( ', ', $ng_names ) ),
|
||||
)
|
||||
);
|
||||
} else {
|
||||
$this->remove_error( $section, 'unavailable_names' );
|
||||
}
|
||||
}
|
||||
|
||||
if ( $this->supports( 'unavailable_html_elements' ) ) {
|
||||
if ( $this->detect_unavailable_html_elements( $section, $form ) ) {
|
||||
$this->add_error( $section, 'unavailable_html_elements',
|
||||
array(
|
||||
'message' => __( 'Unavailable HTML elements are used in the form template.', 'contact-form-7' ),
|
||||
)
|
||||
);
|
||||
} else {
|
||||
$this->remove_error( $section, 'unavailable_html_elements' );
|
||||
}
|
||||
}
|
||||
|
||||
if ( $this->supports( 'dots_in_names' ) ) {
|
||||
if ( $this->detect_dots_in_names( $section, $form ) ) {
|
||||
$this->add_error( $section, 'dots_in_names',
|
||||
array(
|
||||
'message' => __( 'Dots are used in form-tag names.', 'contact-form-7' ),
|
||||
)
|
||||
);
|
||||
} else {
|
||||
$this->remove_error( $section, 'dots_in_names' );
|
||||
}
|
||||
}
|
||||
|
||||
if ( $this->supports( 'colons_in_names' ) ) {
|
||||
if ( $this->detect_colons_in_names( $section, $form ) ) {
|
||||
$this->add_error( $section, 'colons_in_names',
|
||||
array(
|
||||
'message' => __( 'Colons are used in form-tag names.', 'contact-form-7' ),
|
||||
)
|
||||
);
|
||||
} else {
|
||||
$this->remove_error( $section, 'colons_in_names' );
|
||||
}
|
||||
}
|
||||
|
||||
if ( $this->supports( 'upload_filesize_overlimit' ) ) {
|
||||
if ( $this->detect_upload_filesize_overlimit( $section, $form ) ) {
|
||||
$this->add_error( $section, 'upload_filesize_overlimit',
|
||||
array(
|
||||
'message' => __( 'Uploadable file size exceeds PHP’s maximum acceptable size.', 'contact-form-7' ),
|
||||
)
|
||||
);
|
||||
} else {
|
||||
$this->remove_error( $section, 'upload_filesize_overlimit' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Detects errors of multiple form controls in a single label.
|
||||
*
|
||||
* @link https://contactform7.com/configuration-errors/multiple-controls-in-label/
|
||||
*/
|
||||
public function detect_multiple_controls_in_label( $section, $content ) {
|
||||
$pattern = '%<label(?:[ \t\n]+.*?)?>(.+?)</label>%s';
|
||||
|
||||
if ( preg_match_all( $pattern, $content, $matches ) ) {
|
||||
$form_tags_manager = WPCF7_FormTagsManager::get_instance();
|
||||
|
||||
foreach ( $matches[1] as $insidelabel ) {
|
||||
$tags = $form_tags_manager->scan( $insidelabel );
|
||||
$fields_count = 0;
|
||||
|
||||
foreach ( $tags as $tag ) {
|
||||
$is_multiple_controls_container = wpcf7_form_tag_supports(
|
||||
$tag->type, 'multiple-controls-container'
|
||||
);
|
||||
|
||||
$is_zero_controls_container = wpcf7_form_tag_supports(
|
||||
$tag->type, 'zero-controls-container'
|
||||
);
|
||||
|
||||
if ( $is_multiple_controls_container ) {
|
||||
$fields_count += count( $tag->values );
|
||||
|
||||
if ( $tag->has_option( 'free_text' ) ) {
|
||||
$fields_count += 1;
|
||||
}
|
||||
} elseif ( $is_zero_controls_container ) {
|
||||
$fields_count += 0;
|
||||
} elseif ( ! empty( $tag->name ) ) {
|
||||
$fields_count += 1;
|
||||
}
|
||||
|
||||
if ( 1 < $fields_count ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Detects errors of unavailable form-tag names.
|
||||
*
|
||||
* @link https://contactform7.com/configuration-errors/unavailable-names/
|
||||
*/
|
||||
public function detect_unavailable_names( $section, $content ) {
|
||||
$public_query_vars = array( 'm', 'p', 'posts', 'w', 'cat',
|
||||
'withcomments', 'withoutcomments', 's', 'search', 'exact', 'sentence',
|
||||
'calendar', 'page', 'paged', 'more', 'tb', 'pb', 'author', 'order',
|
||||
'orderby', 'year', 'monthnum', 'day', 'hour', 'minute', 'second',
|
||||
'name', 'category_name', 'tag', 'feed', 'author_name', 'static',
|
||||
'pagename', 'page_id', 'error', 'attachment', 'attachment_id',
|
||||
'subpost', 'subpost_id', 'preview', 'robots', 'taxonomy', 'term',
|
||||
'cpage', 'post_type', 'embed',
|
||||
);
|
||||
|
||||
$form_tags_manager = WPCF7_FormTagsManager::get_instance();
|
||||
|
||||
$ng_named_tags = $form_tags_manager->filter( $content, array(
|
||||
'name' => $public_query_vars,
|
||||
) );
|
||||
|
||||
$ng_names = array();
|
||||
|
||||
foreach ( $ng_named_tags as $tag ) {
|
||||
$ng_names[] = sprintf( '"%s"', $tag->name );
|
||||
}
|
||||
|
||||
if ( $ng_names ) {
|
||||
return array_unique( $ng_names );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Detects errors of unavailable HTML elements.
|
||||
*
|
||||
* @link https://contactform7.com/configuration-errors/unavailable-html-elements/
|
||||
*/
|
||||
public function detect_unavailable_html_elements( $section, $content ) {
|
||||
$pattern = '%(?:<form[\s\t>]|</form>)%i';
|
||||
|
||||
if ( preg_match( $pattern, $content ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Detects errors of dots in form-tag names.
|
||||
*
|
||||
* @link https://contactform7.com/configuration-errors/dots-in-names/
|
||||
*/
|
||||
public function detect_dots_in_names( $section, $content ) {
|
||||
$form_tags_manager = WPCF7_FormTagsManager::get_instance();
|
||||
|
||||
$tags = $form_tags_manager->filter( $content, array(
|
||||
'feature' => 'name-attr',
|
||||
) );
|
||||
|
||||
foreach ( $tags as $tag ) {
|
||||
if ( str_contains( $tag->raw_name, '.' ) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Detects errors of colons in form-tag names.
|
||||
*
|
||||
* @link https://contactform7.com/configuration-errors/colons-in-names/
|
||||
*/
|
||||
public function detect_colons_in_names( $section, $content ) {
|
||||
$form_tags_manager = WPCF7_FormTagsManager::get_instance();
|
||||
|
||||
$tags = $form_tags_manager->filter( $content, array(
|
||||
'feature' => 'name-attr',
|
||||
) );
|
||||
|
||||
foreach ( $tags as $tag ) {
|
||||
if ( str_contains( $tag->raw_name, ':' ) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Detects errors of uploadable file size overlimit.
|
||||
*
|
||||
* @link https://contactform7.com/configuration-errors/upload-filesize-overlimit
|
||||
*/
|
||||
public function detect_upload_filesize_overlimit( $section, $content ) {
|
||||
$upload_max_filesize = ini_get( 'upload_max_filesize' );
|
||||
|
||||
if ( ! $upload_max_filesize ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$upload_max_filesize = strtolower( $upload_max_filesize );
|
||||
$upload_max_filesize = trim( $upload_max_filesize );
|
||||
|
||||
if ( ! preg_match( '/^(\d+)([kmg]?)$/', $upload_max_filesize, $matches ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( 'k' === $matches[2] ) {
|
||||
$upload_max_filesize = (int) $matches[1] * KB_IN_BYTES;
|
||||
} elseif ( 'm' === $matches[2] ) {
|
||||
$upload_max_filesize = (int) $matches[1] * MB_IN_BYTES;
|
||||
} elseif ( 'g' === $matches[2] ) {
|
||||
$upload_max_filesize = (int) $matches[1] * GB_IN_BYTES;
|
||||
} else {
|
||||
$upload_max_filesize = (int) $matches[1];
|
||||
}
|
||||
|
||||
$form_tags_manager = WPCF7_FormTagsManager::get_instance();
|
||||
|
||||
$tags = $form_tags_manager->filter( $content, array(
|
||||
'basetype' => 'file',
|
||||
) );
|
||||
|
||||
foreach ( $tags as $tag ) {
|
||||
if ( $upload_max_filesize < $tag->get_limit_option() ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,583 @@
|
||||
<?php
|
||||
|
||||
trait WPCF7_ConfigValidator_Mail {
|
||||
|
||||
/**
|
||||
* Replaces all mail-tags in the given content.
|
||||
*/
|
||||
public function replace_mail_tags( $content, $options = '' ) {
|
||||
$options = wp_parse_args( $options, array(
|
||||
'html' => false,
|
||||
'callback' =>
|
||||
array( $this, 'replace_mail_tags_with_minimum_input_callback' ),
|
||||
) );
|
||||
|
||||
$content = new WPCF7_MailTaggedText( $content, $options );
|
||||
|
||||
return $content->replace_tags();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Callback function for WPCF7_MailTaggedText. Replaces mail-tags with
|
||||
* the most conservative inputs.
|
||||
*/
|
||||
public function replace_mail_tags_with_minimum_input_callback( $matches ) {
|
||||
// allow [[foo]] syntax for escaping a tag
|
||||
if ( '[' === $matches[1] and ']' === $matches[4] ) {
|
||||
return substr( $matches[0], 1, -1 );
|
||||
}
|
||||
|
||||
$tag = $matches[0];
|
||||
$tagname = $matches[2];
|
||||
$values = $matches[3];
|
||||
|
||||
$mail_tag = new WPCF7_MailTag( $tag, $tagname, $values );
|
||||
$field_name = $mail_tag->field_name();
|
||||
|
||||
$example_email = 'example@example.com';
|
||||
$example_text = 'example';
|
||||
$example_blank = '';
|
||||
|
||||
// for back-compat
|
||||
$field_name = preg_replace( '/^wpcf7\./', '_', $field_name );
|
||||
|
||||
if ( '_site_admin_email' === $field_name ) {
|
||||
return get_bloginfo( 'admin_email', 'raw' );
|
||||
|
||||
} elseif ( '_user_agent' === $field_name ) {
|
||||
return $example_text;
|
||||
|
||||
} elseif ( '_user_email' === $field_name ) {
|
||||
return $this->contact_form->is_true( 'subscribers_only' )
|
||||
? $example_email
|
||||
: $example_blank;
|
||||
|
||||
} elseif ( str_starts_with( $field_name, '_user_' ) ) {
|
||||
return $this->contact_form->is_true( 'subscribers_only' )
|
||||
? $example_text
|
||||
: $example_blank;
|
||||
|
||||
} elseif ( str_starts_with( $field_name, '_' ) ) {
|
||||
return str_ends_with( $field_name, '_email' )
|
||||
? $example_email
|
||||
: $example_text;
|
||||
|
||||
}
|
||||
|
||||
static $opcalcset = array();
|
||||
|
||||
if ( ! isset( $opcalcset[$this->contact_form->id()] ) ) {
|
||||
$opcalcset[$this->contact_form->id()] =
|
||||
new WPCF7_MailTag_OutputCalculator( $this->contact_form );
|
||||
}
|
||||
|
||||
$opcalc = $opcalcset[$this->contact_form->id()];
|
||||
$op = $opcalc->calc_output( $mail_tag );
|
||||
|
||||
if ( WPCF7_MailTag_OutputCalculator::email === $op ) {
|
||||
return $example_email;
|
||||
} elseif ( ! ( WPCF7_MailTag_OutputCalculator::blank & $op ) ) {
|
||||
return $example_text;
|
||||
} else {
|
||||
return $example_blank;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Runs error detection for the mail sections.
|
||||
*/
|
||||
public function validate_mail( $template = 'mail' ) {
|
||||
if (
|
||||
$this->contact_form->is_true( 'demo_mode' ) or
|
||||
$this->contact_form->is_true( 'skip_mail' )
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
$components = (array) $this->contact_form->prop( $template );
|
||||
|
||||
if ( ! $components ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( 'mail' !== $template and empty( $components['active'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$components = wp_parse_args( $components, array(
|
||||
'subject' => '',
|
||||
'sender' => '',
|
||||
'recipient' => '',
|
||||
'additional_headers' => '',
|
||||
'body' => '',
|
||||
'attachments' => '',
|
||||
) );
|
||||
|
||||
$this->validate_mail_subject(
|
||||
$template,
|
||||
$components['subject']
|
||||
);
|
||||
|
||||
$this->validate_mail_sender(
|
||||
$template,
|
||||
$components['sender']
|
||||
);
|
||||
|
||||
$this->validate_mail_recipient(
|
||||
$template,
|
||||
$components['recipient']
|
||||
);
|
||||
|
||||
$this->validate_mail_additional_headers(
|
||||
$template,
|
||||
$components['additional_headers']
|
||||
);
|
||||
|
||||
$this->validate_mail_body(
|
||||
$template,
|
||||
$components['body']
|
||||
);
|
||||
|
||||
$this->validate_mail_attachments(
|
||||
$template,
|
||||
$components['attachments']
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Runs error detection for the mail subject section.
|
||||
*/
|
||||
public function validate_mail_subject( $template, $content ) {
|
||||
$section = sprintf( '%s.subject', $template );
|
||||
|
||||
if ( $this->supports( 'maybe_empty' ) ) {
|
||||
if ( $this->detect_maybe_empty( $section, $content ) ) {
|
||||
$this->add_error( $section, 'maybe_empty',
|
||||
array(
|
||||
'message' => __( 'There is a possible empty field.', 'contact-form-7' ),
|
||||
)
|
||||
);
|
||||
} else {
|
||||
$this->remove_error( $section, 'maybe_empty' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Runs error detection for the mail sender section.
|
||||
*/
|
||||
public function validate_mail_sender( $template, $content ) {
|
||||
$section = sprintf( '%s.sender', $template );
|
||||
|
||||
if ( $this->supports( 'invalid_mailbox_syntax' ) ) {
|
||||
if ( $this->detect_invalid_mailbox_syntax( $section, $content ) ) {
|
||||
$this->add_error( $section, 'invalid_mailbox_syntax',
|
||||
array(
|
||||
'message' => __( 'Invalid mailbox syntax is used.', 'contact-form-7' ),
|
||||
)
|
||||
);
|
||||
} else {
|
||||
$this->remove_error( $section, 'invalid_mailbox_syntax' );
|
||||
}
|
||||
}
|
||||
|
||||
if ( $this->supports( 'email_not_in_site_domain' ) ) {
|
||||
$this->remove_error( $section, 'email_not_in_site_domain' );
|
||||
|
||||
if ( ! $this->has_error( $section, 'invalid_mailbox_syntax' ) ) {
|
||||
$sender = $this->replace_mail_tags( $content );
|
||||
$sender = wpcf7_strip_newline( $sender );
|
||||
|
||||
if ( ! wpcf7_is_email_in_site_domain( $sender ) ) {
|
||||
$this->add_error( $section, 'email_not_in_site_domain',
|
||||
array(
|
||||
'message' => __( 'Sender email address does not belong to the site domain.', 'contact-form-7' ),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Runs error detection for the mail recipient section.
|
||||
*/
|
||||
public function validate_mail_recipient( $template, $content ) {
|
||||
$section = sprintf( '%s.recipient', $template );
|
||||
|
||||
if ( $this->supports( 'invalid_mailbox_syntax' ) ) {
|
||||
if ( $this->detect_invalid_mailbox_syntax( $section, $content ) ) {
|
||||
$this->add_error( $section, 'invalid_mailbox_syntax',
|
||||
array(
|
||||
'message' => __( 'Invalid mailbox syntax is used.', 'contact-form-7' ),
|
||||
)
|
||||
);
|
||||
} else {
|
||||
$this->remove_error( $section, 'invalid_mailbox_syntax' );
|
||||
}
|
||||
}
|
||||
|
||||
if ( $this->supports( 'unsafe_email_without_protection' ) ) {
|
||||
$this->remove_error( $section, 'unsafe_email_without_protection' );
|
||||
|
||||
if ( ! $this->has_error( $section, 'invalid_mailbox_syntax' ) ) {
|
||||
if (
|
||||
$this->detect_unsafe_email_without_protection( $section, $content )
|
||||
) {
|
||||
$this->add_error( $section, 'unsafe_email_without_protection',
|
||||
array(
|
||||
'message' => __( 'Unsafe email config is used without sufficient protection.', 'contact-form-7' ),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Runs error detection for the mail additional headers section.
|
||||
*/
|
||||
public function validate_mail_additional_headers( $template, $content ) {
|
||||
$section = sprintf( '%s.additional_headers', $template );
|
||||
|
||||
$invalid_mail_headers = array();
|
||||
$invalid_mailbox_fields = array();
|
||||
$unsafe_email_fields = array();
|
||||
|
||||
foreach ( explode( "\n", $content ) as $header ) {
|
||||
$header = trim( $header );
|
||||
|
||||
if ( '' === $header ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$is_valid_header = preg_match(
|
||||
'/^([0-9A-Za-z-]+):(.*)$/',
|
||||
$header,
|
||||
$matches
|
||||
);
|
||||
|
||||
if ( ! $is_valid_header ) {
|
||||
$invalid_mail_headers[] = $header;
|
||||
continue;
|
||||
}
|
||||
|
||||
$header_name = $matches[1];
|
||||
$header_value = trim( $matches[2] );
|
||||
|
||||
if (
|
||||
in_array(
|
||||
strtolower( $header_name ), array( 'reply-to', 'cc', 'bcc' ), true
|
||||
) and
|
||||
'' !== $header_value and
|
||||
$this->detect_invalid_mailbox_syntax( $section, $header_value )
|
||||
) {
|
||||
$invalid_mailbox_fields[] = $header_name;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (
|
||||
in_array( strtolower( $header_name ), array( 'cc', 'bcc' ), true ) and
|
||||
$this->detect_unsafe_email_without_protection( $section, $header_value )
|
||||
) {
|
||||
$unsafe_email_fields[] = $header_name;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $this->supports( 'invalid_mail_header' ) ) {
|
||||
if ( ! empty( $invalid_mail_headers ) ) {
|
||||
$this->add_error( $section, 'invalid_mail_header',
|
||||
array(
|
||||
'message' => __( 'There are invalid mail header fields.', 'contact-form-7' ),
|
||||
)
|
||||
);
|
||||
} else {
|
||||
$this->remove_error( $section, 'invalid_mail_header' );
|
||||
}
|
||||
}
|
||||
|
||||
if ( $this->supports( 'invalid_mailbox_syntax' ) ) {
|
||||
if ( ! empty( $invalid_mailbox_fields ) ) {
|
||||
foreach ( $invalid_mailbox_fields as $header_name ) {
|
||||
$this->add_error( $section, 'invalid_mailbox_syntax',
|
||||
array(
|
||||
'message' => __( 'Invalid mailbox syntax is used in the %name% field.', 'contact-form-7' ),
|
||||
'params' => array( 'name' => $header_name ),
|
||||
)
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$this->remove_error( $section, 'invalid_mailbox_syntax' );
|
||||
}
|
||||
}
|
||||
|
||||
if ( $this->supports( 'unsafe_email_without_protection' ) ) {
|
||||
if ( ! empty( $unsafe_email_fields ) ) {
|
||||
$this->add_error( $section, 'unsafe_email_without_protection',
|
||||
array(
|
||||
'message' => __( 'Unsafe email config is used without sufficient protection.', 'contact-form-7' ),
|
||||
)
|
||||
);
|
||||
} else {
|
||||
$this->remove_error( $section, 'unsafe_email_without_protection' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Runs error detection for the mail body section.
|
||||
*/
|
||||
public function validate_mail_body( $template, $content ) {
|
||||
$section = sprintf( '%s.body', $template );
|
||||
|
||||
if ( $this->supports( 'maybe_empty' ) ) {
|
||||
if ( $this->detect_maybe_empty( $section, $content ) ) {
|
||||
$this->add_error( $section, 'maybe_empty',
|
||||
array(
|
||||
'message' => __( 'There is a possible empty field.', 'contact-form-7' ),
|
||||
)
|
||||
);
|
||||
} else {
|
||||
$this->remove_error( $section, 'maybe_empty' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Runs error detection for the mail attachments section.
|
||||
*/
|
||||
public function validate_mail_attachments( $template, $content ) {
|
||||
$section = sprintf( '%s.attachments', $template );
|
||||
|
||||
$total_size = 0;
|
||||
$files_not_found = array();
|
||||
$files_out_of_content = array();
|
||||
|
||||
if ( '' !== $content ) {
|
||||
$attachables = array();
|
||||
|
||||
$tags = $this->contact_form->scan_form_tags(
|
||||
array( 'type' => array( 'file', 'file*' ) )
|
||||
);
|
||||
|
||||
foreach ( $tags as $tag ) {
|
||||
$name = $tag->name;
|
||||
|
||||
if ( ! str_contains( $content, "[{$name}]" ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$limit = (int) $tag->get_limit_option();
|
||||
|
||||
if ( empty( $attachables[$name] ) or $attachables[$name] < $limit ) {
|
||||
$attachables[$name] = $limit;
|
||||
}
|
||||
}
|
||||
|
||||
$total_size = array_sum( $attachables );
|
||||
|
||||
foreach ( explode( "\n", $content ) as $line ) {
|
||||
$line = trim( $line );
|
||||
|
||||
if ( '' === $line or str_starts_with( $line, '[' ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( $this->detect_file_not_found( $section, $line ) ) {
|
||||
$files_not_found[] = $line;
|
||||
} elseif ( $this->detect_file_not_in_content_dir( $section, $line ) ) {
|
||||
$files_out_of_content[] = $line;
|
||||
} else {
|
||||
$total_size += (int) @filesize( path_join( WP_CONTENT_DIR, $line ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( $this->supports( 'file_not_found' ) ) {
|
||||
if ( ! empty( $files_not_found ) ) {
|
||||
foreach ( $files_not_found as $line ) {
|
||||
$this->add_error( $section, 'file_not_found',
|
||||
array(
|
||||
'message' => __( 'Attachment file does not exist at %path%.', 'contact-form-7' ),
|
||||
'params' => array( 'path' => $line ),
|
||||
)
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$this->remove_error( $section, 'file_not_found' );
|
||||
}
|
||||
}
|
||||
|
||||
if ( $this->supports( 'file_not_in_content_dir' ) ) {
|
||||
if ( ! empty( $files_out_of_content ) ) {
|
||||
$this->add_error( $section, 'file_not_in_content_dir',
|
||||
array(
|
||||
'message' => __( 'It is not allowed to use files outside the wp-content directory.', 'contact-form-7' ),
|
||||
)
|
||||
);
|
||||
} else {
|
||||
$this->remove_error( $section, 'file_not_in_content_dir' );
|
||||
}
|
||||
}
|
||||
|
||||
if ( $this->supports( 'attachments_overweight' ) ) {
|
||||
$max = 25 * MB_IN_BYTES; // 25 MB
|
||||
|
||||
if ( $max < $total_size ) {
|
||||
$this->add_error( $section, 'attachments_overweight',
|
||||
array(
|
||||
'message' => __( 'The total size of attachment files is too large.', 'contact-form-7' ),
|
||||
)
|
||||
);
|
||||
} else {
|
||||
$this->remove_error( $section, 'attachments_overweight' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Detects errors of invalid mailbox syntax.
|
||||
*
|
||||
* @link https://contactform7.com/configuration-errors/invalid-mailbox-syntax/
|
||||
*/
|
||||
public function detect_invalid_mailbox_syntax( $section, $content ) {
|
||||
$content = $this->replace_mail_tags( $content );
|
||||
$content = wpcf7_strip_newline( $content );
|
||||
|
||||
if ( ! wpcf7_is_mailbox_list( $content ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Detects errors of empty message fields.
|
||||
*
|
||||
* @link https://contactform7.com/configuration-errors/maybe-empty/
|
||||
*/
|
||||
public function detect_maybe_empty( $section, $content ) {
|
||||
$content = $this->replace_mail_tags( $content );
|
||||
$content = wpcf7_strip_newline( $content );
|
||||
|
||||
if ( '' === $content ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Detects errors of nonexistent attachment files.
|
||||
*
|
||||
* @link https://contactform7.com/configuration-errors/file-not-found/
|
||||
*/
|
||||
public function detect_file_not_found( $section, $content ) {
|
||||
$path = path_join( WP_CONTENT_DIR, $content );
|
||||
|
||||
if ( ! is_readable( $path ) or ! is_file( $path ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Detects errors of attachment files out of the content directory.
|
||||
*
|
||||
* @link https://contactform7.com/configuration-errors/file-not-in-content-dir/
|
||||
*/
|
||||
public function detect_file_not_in_content_dir( $section, $content ) {
|
||||
$path = path_join( WP_CONTENT_DIR, $content );
|
||||
|
||||
if ( ! wpcf7_is_file_path_in_content_dir( $path ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Detects errors of that unsafe email config is used without
|
||||
* sufficient protection.
|
||||
*
|
||||
* @link https://contactform7.com/configuration-errors/unsafe-email-without-protection/
|
||||
*/
|
||||
public function detect_unsafe_email_without_protection( $section, $content ) {
|
||||
if ( $this->contact_form->is_true( 'subscribers_only' ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static $is_captcha_active = null;
|
||||
|
||||
if ( null === $is_captcha_active ) {
|
||||
$is_captcha_active = call_user_func( static function () {
|
||||
$recaptcha = WPCF7_RECAPTCHA::get_instance();
|
||||
$turnstile = WPCF7_Turnstile::get_instance();
|
||||
return $recaptcha->is_active() || $turnstile->is_active();
|
||||
} );
|
||||
}
|
||||
|
||||
if ( $is_captcha_active ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$example_email = 'user-specified@example.com';
|
||||
|
||||
// Replace mail-tags connected to an email type form-tag first.
|
||||
$content = $this->replace_mail_tags( $content, array(
|
||||
'callback' => function ( $matches ) use ( $example_email ) {
|
||||
// allow [[foo]] syntax for escaping a tag
|
||||
if ( '[' === $matches[1] and ']' === $matches[4] ) {
|
||||
return substr( $matches[0], 1, -1 );
|
||||
}
|
||||
|
||||
$tag = $matches[0];
|
||||
$tagname = $matches[2];
|
||||
$values = $matches[3];
|
||||
|
||||
$mail_tag = new WPCF7_MailTag( $tag, $tagname, $values );
|
||||
$field_name = $mail_tag->field_name();
|
||||
|
||||
$form_tags = $this->contact_form->scan_form_tags(
|
||||
array( 'name' => $field_name )
|
||||
);
|
||||
|
||||
if ( $form_tags ) {
|
||||
$form_tag = new WPCF7_FormTag( $form_tags[0] );
|
||||
|
||||
if ( 'email' === $form_tag->basetype ) {
|
||||
return $example_email;
|
||||
}
|
||||
}
|
||||
|
||||
return $tag;
|
||||
},
|
||||
) );
|
||||
|
||||
// Replace remaining mail-tags.
|
||||
$content = $this->replace_mail_tags( $content );
|
||||
|
||||
$content = wpcf7_strip_newline( $content );
|
||||
|
||||
if ( str_contains( $content, $example_email ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
trait WPCF7_ConfigValidator_Messages {
|
||||
|
||||
/**
|
||||
* Runs error detection for the messages section.
|
||||
*/
|
||||
public function validate_messages() {
|
||||
$messages = (array) $this->contact_form->prop( 'messages' );
|
||||
|
||||
if ( ! $messages ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
isset( $messages['captcha_not_match'] ) and
|
||||
! wpcf7_use_really_simple_captcha()
|
||||
) {
|
||||
unset( $messages['captcha_not_match'] );
|
||||
}
|
||||
|
||||
foreach ( $messages as $key => $message ) {
|
||||
$section = sprintf( 'messages.%s', $key );
|
||||
|
||||
if ( $this->supports( 'html_in_message' ) ) {
|
||||
if ( $this->detect_html_in_message( $section, $message ) ) {
|
||||
$this->add_error( $section, 'html_in_message',
|
||||
array(
|
||||
'message' => __( 'HTML tags are used in a message.', 'contact-form-7' ),
|
||||
)
|
||||
);
|
||||
} else {
|
||||
$this->remove_error( $section, 'html_in_message' );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Detects errors of HTML uses in a message.
|
||||
*
|
||||
* @link https://contactform7.com/configuration-errors/html-in-message/
|
||||
*/
|
||||
public function detect_html_in_message( $section, $content ) {
|
||||
$stripped = wp_strip_all_tags( $content );
|
||||
|
||||
if ( $stripped !== $content ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,386 @@
|
||||
<?php
|
||||
|
||||
require_once path_join( __DIR__, 'form.php' );
|
||||
require_once path_join( __DIR__, 'mail.php' );
|
||||
require_once path_join( __DIR__, 'messages.php' );
|
||||
require_once path_join( __DIR__, 'additional-settings.php' );
|
||||
require_once path_join( __DIR__, 'actions.php' );
|
||||
|
||||
|
||||
/**
|
||||
* Configuration validator.
|
||||
*
|
||||
* @link https://contactform7.com/configuration-errors/
|
||||
*/
|
||||
class WPCF7_ConfigValidator {
|
||||
|
||||
/**
|
||||
* The plugin version in which important updates happened last time.
|
||||
*/
|
||||
const last_important_update = '5.8.1';
|
||||
|
||||
const error_codes = array(
|
||||
'maybe_empty',
|
||||
'invalid_mailbox_syntax',
|
||||
'email_not_in_site_domain',
|
||||
'html_in_message',
|
||||
'multiple_controls_in_label',
|
||||
'file_not_found',
|
||||
'unavailable_names',
|
||||
'invalid_mail_header',
|
||||
'deprecated_settings',
|
||||
'file_not_in_content_dir',
|
||||
'unavailable_html_elements',
|
||||
'attachments_overweight',
|
||||
'dots_in_names',
|
||||
'colons_in_names',
|
||||
'upload_filesize_overlimit',
|
||||
'unsafe_email_without_protection',
|
||||
);
|
||||
|
||||
use WPCF7_ConfigValidator_Form;
|
||||
use WPCF7_ConfigValidator_Mail;
|
||||
use WPCF7_ConfigValidator_Messages;
|
||||
use WPCF7_ConfigValidator_AdditionalSettings;
|
||||
|
||||
private $contact_form;
|
||||
private $errors = array();
|
||||
private $include;
|
||||
private $exclude;
|
||||
|
||||
|
||||
/**
|
||||
* Returns a URL linking to the documentation page for the error type.
|
||||
*/
|
||||
public static function get_doc_link( $child_page = '' ) {
|
||||
$url = __( 'https://contactform7.com/configuration-errors/',
|
||||
'contact-form-7'
|
||||
);
|
||||
|
||||
if ( '' !== $child_page ) {
|
||||
$child_page = strtr( $child_page, '_', '-' );
|
||||
|
||||
$url = sprintf( '%s/%s', untrailingslashit( $url ), $child_page );
|
||||
}
|
||||
|
||||
return esc_url( $url );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct( WPCF7_ContactForm $contact_form, $options = '' ) {
|
||||
$options = wp_parse_args( $options, array(
|
||||
'include' => null,
|
||||
'exclude' => null,
|
||||
) );
|
||||
|
||||
$this->contact_form = $contact_form;
|
||||
|
||||
if ( isset( $options['include'] ) ) {
|
||||
$this->include = (array) $options['include'];
|
||||
}
|
||||
|
||||
if ( isset( $options['exclude'] ) ) {
|
||||
$this->exclude = (array) $options['exclude'];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the contact form object that is tied to this validator.
|
||||
*/
|
||||
public function contact_form() {
|
||||
return $this->contact_form;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if no error has been detected.
|
||||
*/
|
||||
public function is_valid() {
|
||||
return ! $this->count_errors();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the given error code is supported by this instance.
|
||||
*/
|
||||
public function supports( $error_code ) {
|
||||
if ( isset( $this->include ) ) {
|
||||
$supported_codes = array_intersect( self::error_codes, $this->include );
|
||||
} else {
|
||||
$supported_codes = self::error_codes;
|
||||
}
|
||||
|
||||
if ( isset( $this->exclude ) ) {
|
||||
$supported_codes = array_diff( $supported_codes, $this->exclude );
|
||||
}
|
||||
|
||||
return in_array( $error_code, $supported_codes, true );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Counts detected errors.
|
||||
*/
|
||||
public function count_errors( $options = '' ) {
|
||||
$options = wp_parse_args( $options, array(
|
||||
'section' => '',
|
||||
'code' => '',
|
||||
) );
|
||||
|
||||
$count = 0;
|
||||
|
||||
foreach ( $this->errors as $key => $errors ) {
|
||||
if ( preg_match( '/^mail_[0-9]+\.(.*)$/', $key, $matches ) ) {
|
||||
$key = sprintf( 'mail.%s', $matches[1] );
|
||||
}
|
||||
|
||||
if (
|
||||
$options['section'] and
|
||||
$key !== $options['section'] and
|
||||
preg_replace( '/\..*$/', '', $key, 1 ) !== $options['section']
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ( $errors as $error ) {
|
||||
if ( empty( $error ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( $options['code'] and $error['code'] !== $options['code'] ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
return $count;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Collects messages for detected errors.
|
||||
*/
|
||||
public function collect_error_messages( $options = '' ) {
|
||||
$options = wp_parse_args( $options, array(
|
||||
'decodes_html_entities' => false,
|
||||
) );
|
||||
|
||||
$error_messages = array();
|
||||
|
||||
foreach ( $this->errors as $section => $errors ) {
|
||||
$error_messages[$section] = array();
|
||||
|
||||
foreach ( $errors as $error ) {
|
||||
if ( empty( $error['args']['message'] ) ) {
|
||||
$message = $this->get_default_message( $error['code'] );
|
||||
} elseif ( empty( $error['args']['params'] ) ) {
|
||||
$message = $error['args']['message'];
|
||||
} else {
|
||||
$message = $this->build_message(
|
||||
$error['args']['message'],
|
||||
$error['args']['params']
|
||||
);
|
||||
}
|
||||
|
||||
if ( $options['decodes_html_entities'] ) {
|
||||
$message = html_entity_decode( $message, ENT_HTML5 );
|
||||
}
|
||||
|
||||
$link = '';
|
||||
|
||||
if ( ! empty( $error['args']['link'] ) ) {
|
||||
$link = $error['args']['link'];
|
||||
}
|
||||
|
||||
$error_messages[$section][] = array(
|
||||
'message' => $message,
|
||||
'link' => esc_url( $link ),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $error_messages;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Builds an error message by replacing placeholders.
|
||||
*/
|
||||
public function build_message( $message, $params = '' ) {
|
||||
$params = wp_parse_args( $params, array() );
|
||||
|
||||
foreach ( $params as $key => $val ) {
|
||||
if ( ! preg_match( '/^[0-9A-Za-z_]+$/', $key ) ) { // invalid key
|
||||
continue;
|
||||
}
|
||||
|
||||
$placeholder = '%' . $key . '%';
|
||||
|
||||
if ( false !== stripos( $message, $placeholder ) ) {
|
||||
$message = str_ireplace( $placeholder, $val, $message );
|
||||
}
|
||||
}
|
||||
|
||||
return $message;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a default message that is used when the message for the error
|
||||
* is not specified.
|
||||
*/
|
||||
public function get_default_message( $code = '' ) {
|
||||
return __( 'Configuration error is detected.', 'contact-form-7' );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the specified section has the specified error.
|
||||
*
|
||||
* @param string $section The section where the error detected.
|
||||
* @param string $code The unique code of the error.
|
||||
*/
|
||||
public function has_error( $section, $code ) {
|
||||
if ( empty( $this->errors[$section] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ( (array) $this->errors[$section] as $error ) {
|
||||
if ( isset( $error['code'] ) and $error['code'] === $code ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds a validation error.
|
||||
*
|
||||
* @param string $section The section where the error detected.
|
||||
* @param string $code The unique code of the error.
|
||||
* @param string|array $args Optional options for the error.
|
||||
*/
|
||||
public function add_error( $section, $code, $args = '' ) {
|
||||
$args = wp_parse_args( $args, array(
|
||||
'message' => '',
|
||||
'params' => array(),
|
||||
) );
|
||||
|
||||
$available_error_codes = (array) apply_filters(
|
||||
'wpcf7_config_validator_available_error_codes',
|
||||
self::error_codes,
|
||||
$this->contact_form
|
||||
);
|
||||
|
||||
if ( ! in_array( $code, $available_error_codes, true ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! isset( $args['link'] ) ) {
|
||||
$args['link'] = self::get_doc_link( $code );
|
||||
}
|
||||
|
||||
if ( ! isset( $this->errors[$section] ) ) {
|
||||
$this->errors[$section] = array();
|
||||
}
|
||||
|
||||
$this->errors[$section][] = array(
|
||||
'code' => $code,
|
||||
'args' => $args,
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Removes an error.
|
||||
*
|
||||
* @param string $section The section where the error detected.
|
||||
* @param string $code The unique code of the error.
|
||||
*/
|
||||
public function remove_error( $section, $code ) {
|
||||
if ( empty( $this->errors[$section] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ( (array) $this->errors[$section] as $key => $error ) {
|
||||
if ( isset( $error['code'] ) and $error['code'] === $code ) {
|
||||
unset( $this->errors[$section][$key] );
|
||||
}
|
||||
}
|
||||
|
||||
if ( empty( $this->errors[$section] ) ) {
|
||||
unset( $this->errors[$section] );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The main validation runner.
|
||||
*
|
||||
* @return bool True if there is no error detected.
|
||||
*/
|
||||
public function validate() {
|
||||
$this->validate_form();
|
||||
$this->validate_mail( 'mail' );
|
||||
$this->validate_mail( 'mail_2' );
|
||||
$this->validate_messages();
|
||||
$this->validate_additional_settings();
|
||||
|
||||
do_action( 'wpcf7_config_validator_validate', $this );
|
||||
|
||||
return $this->is_valid();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Saves detected errors as a post meta data.
|
||||
*/
|
||||
public function save() {
|
||||
if ( $this->contact_form->initial() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
delete_post_meta( $this->contact_form->id(), '_config_validation' );
|
||||
|
||||
if ( $this->errors ) {
|
||||
update_post_meta(
|
||||
$this->contact_form->id(), '_config_validation', $this->errors
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Restore errors from the database.
|
||||
*/
|
||||
public function restore() {
|
||||
$config_errors = get_post_meta(
|
||||
$this->contact_form->id(), '_config_validation', true
|
||||
);
|
||||
|
||||
foreach ( (array) $config_errors as $section => $errors ) {
|
||||
if ( empty( $errors ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ( (array) $errors as $error ) {
|
||||
if ( ! empty( $error['code'] ) ) {
|
||||
$code = $error['code'];
|
||||
$args = isset( $error['args'] ) ? $error['args'] : '';
|
||||
$this->add_error( $section, $code, $args );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,476 @@
|
||||
<?php
|
||||
/**
|
||||
* 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 ) {
|
||||
$contact_forms = WPCF7_ContactForm::find( array(
|
||||
'meta_query' => array(
|
||||
array(
|
||||
'key' => '_old_cf7_unit_id',
|
||||
'type' => 'DECIMAL',
|
||||
'value' => $old_id,
|
||||
),
|
||||
),
|
||||
'posts_per_page' => 1,
|
||||
) );
|
||||
|
||||
if ( $contact_forms ) {
|
||||
return wpcf7_contact_form( $contact_forms[0] );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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 ) {
|
||||
if ( ! preg_match( '/^[0-9a-f]{7,}$/', $hash ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$contact_forms = WPCF7_ContactForm::find( array(
|
||||
'meta_query' => array(
|
||||
array(
|
||||
'key' => '_hash',
|
||||
'compare' => 'REGEXP',
|
||||
'value' => '^' . $hash,
|
||||
),
|
||||
),
|
||||
'posts_per_page' => 1,
|
||||
) );
|
||||
|
||||
if ( $contact_forms ) {
|
||||
return wpcf7_contact_form( $contact_forms[0] );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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( $contact_forms[0] );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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 wpcf7_superglobal_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(
|
||||
'<p class="wpcf7-contact-form-not-found"><strong>%1$s</strong> %2$s</p>',
|
||||
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( $data = '', $context = 'save' ) {
|
||||
$data = wp_parse_args( $data, array(
|
||||
'id' => -1,
|
||||
'title' => null,
|
||||
'locale' => null,
|
||||
'form' => null,
|
||||
'mail' => null,
|
||||
'mail_2' => null,
|
||||
'messages' => null,
|
||||
'additional_settings' => null,
|
||||
) );
|
||||
|
||||
$data['id'] = (int) $data['id'];
|
||||
|
||||
if ( -1 === $data['id'] ) {
|
||||
$contact_form = WPCF7_ContactForm::get_template();
|
||||
} else {
|
||||
$contact_form = wpcf7_contact_form( $data['id'] );
|
||||
}
|
||||
|
||||
if ( empty( $contact_form ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( null !== $data['title'] ) {
|
||||
$contact_form->set_title( $data['title'] );
|
||||
}
|
||||
|
||||
if ( null !== $data['locale'] ) {
|
||||
$contact_form->set_locale( $data['locale'] );
|
||||
}
|
||||
|
||||
$properties = array();
|
||||
|
||||
if ( null !== $data['form'] ) {
|
||||
$properties['form'] = wpcf7_sanitize_form( $data['form'] );
|
||||
}
|
||||
|
||||
if ( null !== $data['mail'] ) {
|
||||
$properties['mail'] = wpcf7_sanitize_mail( $data['mail'] );
|
||||
$properties['mail']['active'] = true;
|
||||
}
|
||||
|
||||
if ( null !== $data['mail_2'] ) {
|
||||
$properties['mail_2'] = wpcf7_sanitize_mail( $data['mail_2'] );
|
||||
}
|
||||
|
||||
if ( null !== $data['messages'] ) {
|
||||
$properties['messages'] = wpcf7_sanitize_messages( $data['messages'] );
|
||||
}
|
||||
|
||||
if ( null !== $data['additional_settings'] ) {
|
||||
$properties['additional_settings'] = wpcf7_sanitize_additional_settings(
|
||||
$data['additional_settings']
|
||||
);
|
||||
}
|
||||
|
||||
$contact_form->set_properties( $properties );
|
||||
|
||||
do_action( 'wpcf7_save_contact_form', $contact_form, $data, $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 hash( 'sha256', implode( '|', array(
|
||||
get_current_user_id(),
|
||||
$post_id,
|
||||
time(),
|
||||
home_url(),
|
||||
) ) );
|
||||
}
|
||||
@ -0,0 +1,204 @@
|
||||
<?php
|
||||
|
||||
class WPCF7_ContactFormTemplate {
|
||||
|
||||
public static function get_default( $prop = 'form' ) {
|
||||
if ( 'form' === $prop ) {
|
||||
$template = self::form();
|
||||
} elseif ( 'mail' === $prop ) {
|
||||
$template = self::mail();
|
||||
} elseif ( 'mail_2' === $prop ) {
|
||||
$template = self::mail_2();
|
||||
} elseif ( 'messages' === $prop ) {
|
||||
$template = self::messages();
|
||||
} else {
|
||||
$template = null;
|
||||
}
|
||||
|
||||
return apply_filters( 'wpcf7_default_template', $template, $prop );
|
||||
}
|
||||
|
||||
public static function form() {
|
||||
$template = sprintf(
|
||||
'
|
||||
<label> %2$s
|
||||
[text* your-name autocomplete:name] </label>
|
||||
|
||||
<label> %3$s
|
||||
[email* your-email autocomplete:email] </label>
|
||||
|
||||
<label> %4$s
|
||||
[text* your-subject] </label>
|
||||
|
||||
<label> %5$s %1$s
|
||||
[textarea your-message] </label>
|
||||
|
||||
[submit "%6$s"]',
|
||||
__( '(optional)', 'contact-form-7' ),
|
||||
__( 'Your name', 'contact-form-7' ),
|
||||
__( 'Your email', 'contact-form-7' ),
|
||||
__( 'Subject', 'contact-form-7' ),
|
||||
__( 'Your message', 'contact-form-7' ),
|
||||
__( 'Submit', 'contact-form-7' )
|
||||
);
|
||||
|
||||
return trim( $template );
|
||||
}
|
||||
|
||||
public static function mail() {
|
||||
$template = array(
|
||||
'subject' => sprintf(
|
||||
/* translators: 1: blog name, 2: [your-subject] */
|
||||
_x( '%1$s "%2$s"', 'mail subject', 'contact-form-7' ),
|
||||
'[_site_title]',
|
||||
'[your-subject]'
|
||||
),
|
||||
'sender' => sprintf(
|
||||
'%s <%s>',
|
||||
'[_site_title]',
|
||||
self::from_email()
|
||||
),
|
||||
'body' =>
|
||||
sprintf(
|
||||
/* translators: %s: [your-name] [your-email] */
|
||||
__( 'From: %s', 'contact-form-7' ),
|
||||
'[your-name] [your-email]'
|
||||
) . "\n"
|
||||
. sprintf(
|
||||
/* translators: %s: [your-subject] */
|
||||
__( 'Subject: %s', 'contact-form-7' ),
|
||||
'[your-subject]'
|
||||
) . "\n\n"
|
||||
. __( 'Message Body:', 'contact-form-7' )
|
||||
. "\n" . '[your-message]' . "\n\n"
|
||||
. '-- ' . "\n"
|
||||
. sprintf(
|
||||
/* translators: 1: blog name, 2: blog URL */
|
||||
__( 'This is a notification that a contact form was submitted on your website (%1$s %2$s).', 'contact-form-7' ),
|
||||
'[_site_title]',
|
||||
'[_site_url]'
|
||||
),
|
||||
'recipient' => '[_site_admin_email]',
|
||||
'additional_headers' => 'Reply-To: [your-email]',
|
||||
'attachments' => '',
|
||||
'use_html' => 0,
|
||||
'exclude_blank' => 0,
|
||||
);
|
||||
|
||||
return $template;
|
||||
}
|
||||
|
||||
public static function mail_2() {
|
||||
$template = array(
|
||||
'active' => false,
|
||||
'subject' => sprintf(
|
||||
/* translators: 1: blog name, 2: [your-subject] */
|
||||
_x( '%1$s "%2$s"', 'mail subject', 'contact-form-7' ),
|
||||
'[_site_title]',
|
||||
'[your-subject]'
|
||||
),
|
||||
'sender' => sprintf(
|
||||
'%s <%s>',
|
||||
'[_site_title]',
|
||||
self::from_email()
|
||||
),
|
||||
'body' =>
|
||||
__( 'Message Body:', 'contact-form-7' )
|
||||
. "\n" . '[your-message]' . "\n\n"
|
||||
. '-- ' . "\n"
|
||||
. sprintf(
|
||||
/* translators: 1: blog name, 2: blog URL */
|
||||
__( 'This email is a receipt for your contact form submission on our website (%1$s %2$s) in which your email address was used. If that was not you, please ignore this message.', 'contact-form-7' ),
|
||||
'[_site_title]',
|
||||
'[_site_url]'
|
||||
),
|
||||
'recipient' => '[your-email]',
|
||||
'additional_headers' => sprintf(
|
||||
'Reply-To: %s',
|
||||
'[_site_admin_email]'
|
||||
),
|
||||
'attachments' => '',
|
||||
'use_html' => 0,
|
||||
'exclude_blank' => 0,
|
||||
);
|
||||
|
||||
return $template;
|
||||
}
|
||||
|
||||
public static function from_email() {
|
||||
$admin_email = get_option( 'admin_email' );
|
||||
|
||||
if ( wpcf7_is_localhost() ) {
|
||||
return $admin_email;
|
||||
}
|
||||
|
||||
$sitename = wp_parse_url( network_home_url(), PHP_URL_HOST );
|
||||
$sitename = strtolower( $sitename );
|
||||
|
||||
if ( 'www.' === substr( $sitename, 0, 4 ) ) {
|
||||
$sitename = substr( $sitename, 4 );
|
||||
}
|
||||
|
||||
if ( strpbrk( $admin_email, '@' ) === '@' . $sitename ) {
|
||||
return $admin_email;
|
||||
}
|
||||
|
||||
return 'wordpress@' . $sitename;
|
||||
}
|
||||
|
||||
public static function messages() {
|
||||
$messages = array();
|
||||
|
||||
foreach ( wpcf7_messages() as $key => $arr ) {
|
||||
$messages[$key] = $arr['default'];
|
||||
}
|
||||
|
||||
return $messages;
|
||||
}
|
||||
}
|
||||
|
||||
function wpcf7_messages() {
|
||||
$messages = array(
|
||||
'mail_sent_ok' => array(
|
||||
'description' => __( 'Sender’s message was sent successfully', 'contact-form-7' ),
|
||||
'default' => __( 'Thank you for your message. It has been sent.', 'contact-form-7' ),
|
||||
),
|
||||
|
||||
'mail_sent_ng' => array(
|
||||
'description' => __( 'Sender’s message failed to send', 'contact-form-7' ),
|
||||
'default' => __( 'There was an error trying to send your message. Please try again later.', 'contact-form-7' ),
|
||||
),
|
||||
|
||||
'validation_error' => array(
|
||||
'description' => __( 'Validation errors occurred', 'contact-form-7' ),
|
||||
'default' => __( 'One or more fields have an error. Please check and try again.', 'contact-form-7' ),
|
||||
),
|
||||
|
||||
'spam' => array(
|
||||
'description' => __( 'Submission was referred to as spam', 'contact-form-7' ),
|
||||
'default' => __( 'There was an error trying to send your message. Please try again later.', 'contact-form-7' ),
|
||||
),
|
||||
|
||||
'accept_terms' => array(
|
||||
'description' => __( 'There are terms that the sender must accept', 'contact-form-7' ),
|
||||
'default' => __( 'You must accept the terms and conditions before sending your message.', 'contact-form-7' ),
|
||||
),
|
||||
|
||||
'invalid_required' => array(
|
||||
'description' => __( 'There is a field that the sender must fill in', 'contact-form-7' ),
|
||||
'default' => __( 'Please fill out this field.', 'contact-form-7' ),
|
||||
),
|
||||
|
||||
'invalid_too_long' => array(
|
||||
'description' => __( 'There is a field with input that is longer than the maximum allowed length', 'contact-form-7' ),
|
||||
'default' => __( 'This field has a too long input.', 'contact-form-7' ),
|
||||
),
|
||||
|
||||
'invalid_too_short' => array(
|
||||
'description' => __( 'There is a field with input that is shorter than the minimum allowed length', 'contact-form-7' ),
|
||||
'default' => __( 'This field has a too short input.', 'contact-form-7' ),
|
||||
),
|
||||
);
|
||||
|
||||
return apply_filters( 'wpcf7_messages', $messages );
|
||||
}
|
||||
1379
wp-content/plugins/contact-form-7/includes/contact-form.php
Normal file
184
wp-content/plugins/contact-form-7/includes/controller.php
Normal file
@ -0,0 +1,184 @@
|
||||
<?php
|
||||
/**
|
||||
* Controller for front-end requests, scripts, and styles
|
||||
*/
|
||||
|
||||
|
||||
add_action(
|
||||
'parse_request',
|
||||
'wpcf7_control_init',
|
||||
20, 0
|
||||
);
|
||||
|
||||
/**
|
||||
* Handles a submission in non-Ajax mode.
|
||||
*/
|
||||
function wpcf7_control_init() {
|
||||
if ( WPCF7_Submission::is_restful() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
$id = (int) wpcf7_superglobal_post( '_wpcf7' ) and
|
||||
$contact_form = wpcf7_contact_form( $id )
|
||||
) {
|
||||
$contact_form->submit();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Registers main scripts and styles.
|
||||
*/
|
||||
add_action(
|
||||
'wp_enqueue_scripts',
|
||||
static function () {
|
||||
$assets = include wpcf7_plugin_path( 'includes/js/index.asset.php' );
|
||||
|
||||
$assets = wp_parse_args( $assets, array(
|
||||
'dependencies' => array(),
|
||||
'version' => WPCF7_VERSION,
|
||||
) );
|
||||
|
||||
wp_register_script(
|
||||
'contact-form-7',
|
||||
wpcf7_plugin_url( 'includes/js/index.js' ),
|
||||
array_merge(
|
||||
$assets['dependencies'],
|
||||
array( 'swv' )
|
||||
),
|
||||
$assets['version'],
|
||||
array( 'in_footer' => true )
|
||||
);
|
||||
|
||||
wp_set_script_translations( 'contact-form-7', 'contact-form-7' );
|
||||
|
||||
wp_register_script(
|
||||
'contact-form-7-html5-fallback',
|
||||
wpcf7_plugin_url( 'includes/js/html5-fallback.js' ),
|
||||
array( 'jquery-ui-datepicker' ),
|
||||
WPCF7_VERSION,
|
||||
array( 'in_footer' => true )
|
||||
);
|
||||
|
||||
if ( wpcf7_load_js() ) {
|
||||
wpcf7_enqueue_scripts();
|
||||
}
|
||||
|
||||
wp_register_style(
|
||||
'contact-form-7',
|
||||
wpcf7_plugin_url( 'includes/css/styles.css' ),
|
||||
array(),
|
||||
WPCF7_VERSION,
|
||||
'all'
|
||||
);
|
||||
|
||||
wp_register_style(
|
||||
'contact-form-7-rtl',
|
||||
wpcf7_plugin_url( 'includes/css/styles-rtl.css' ),
|
||||
array( 'contact-form-7' ),
|
||||
WPCF7_VERSION,
|
||||
'all'
|
||||
);
|
||||
|
||||
wp_register_style(
|
||||
'jquery-ui-smoothness',
|
||||
wpcf7_plugin_url(
|
||||
'includes/js/jquery-ui/themes/smoothness/jquery-ui.min.css'
|
||||
),
|
||||
array(),
|
||||
'1.12.1',
|
||||
'screen'
|
||||
);
|
||||
|
||||
if ( wpcf7_load_css() ) {
|
||||
wpcf7_enqueue_styles();
|
||||
}
|
||||
},
|
||||
10, 0
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* Enqueues scripts.
|
||||
*/
|
||||
function wpcf7_enqueue_scripts() {
|
||||
wp_enqueue_script( 'contact-form-7' );
|
||||
|
||||
$wpcf7_obj = array(
|
||||
'api' => array(
|
||||
'root' => sanitize_url( get_rest_url() ),
|
||||
'namespace' => 'contact-form-7/v1',
|
||||
),
|
||||
);
|
||||
|
||||
if ( defined( 'WP_CACHE' ) and WP_CACHE ) {
|
||||
$wpcf7_obj = array_merge( $wpcf7_obj, array(
|
||||
'cached' => 1,
|
||||
) );
|
||||
}
|
||||
|
||||
wp_add_inline_script( 'contact-form-7',
|
||||
sprintf(
|
||||
'var wpcf7 = %s;',
|
||||
wp_json_encode( $wpcf7_obj, JSON_PRETTY_PRINT )
|
||||
),
|
||||
'before'
|
||||
);
|
||||
|
||||
do_action( 'wpcf7_enqueue_scripts' );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the main script is enqueued.
|
||||
*/
|
||||
function wpcf7_script_is() {
|
||||
return wp_script_is( 'contact-form-7' );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Enqueues styles.
|
||||
*/
|
||||
function wpcf7_enqueue_styles() {
|
||||
wp_enqueue_style( 'contact-form-7' );
|
||||
|
||||
if ( wpcf7_is_rtl() ) {
|
||||
wp_enqueue_style( 'contact-form-7-rtl' );
|
||||
}
|
||||
|
||||
do_action( 'wpcf7_enqueue_styles' );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the main stylesheet is enqueued.
|
||||
*/
|
||||
function wpcf7_style_is() {
|
||||
return wp_style_is( 'contact-form-7' );
|
||||
}
|
||||
|
||||
|
||||
add_action(
|
||||
'wp_enqueue_scripts',
|
||||
'wpcf7_html5_fallback',
|
||||
20, 0
|
||||
);
|
||||
|
||||
/**
|
||||
* Enqueues scripts and styles for the HTML5 fallback.
|
||||
*/
|
||||
function wpcf7_html5_fallback() {
|
||||
if ( ! wpcf7_support_html5_fallback() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( wpcf7_script_is() ) {
|
||||
wp_enqueue_script( 'contact-form-7-html5-fallback' );
|
||||
}
|
||||
|
||||
if ( wpcf7_style_is() ) {
|
||||
wp_enqueue_style( 'jquery-ui-smoothness' );
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
.wpcf7-not-valid-tip {
|
||||
direction: rtl;
|
||||
}
|
||||
|
||||
.use-floating-validation-tip .wpcf7-not-valid-tip {
|
||||
right: 1em;
|
||||
}
|
||||
|
||||
.wpcf7-list-item {
|
||||
margin: 0 1em 0 0;
|
||||
}
|
||||
176
wp-content/plugins/contact-form-7/includes/css/styles.css
Normal file
@ -0,0 +1,176 @@
|
||||
.wpcf7 .screen-reader-response {
|
||||
position: absolute;
|
||||
overflow: hidden;
|
||||
clip: rect(1px, 1px, 1px, 1px);
|
||||
clip-path: inset(50%);
|
||||
height: 1px;
|
||||
width: 1px;
|
||||
margin: -1px;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
word-wrap: normal !important;
|
||||
}
|
||||
|
||||
.wpcf7 .hidden-fields-container {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.wpcf7 form .wpcf7-response-output {
|
||||
margin: 2em 0.5em 1em;
|
||||
padding: 0.2em 1em;
|
||||
border: 2px solid #00a0d2; /* Blue */
|
||||
}
|
||||
|
||||
.wpcf7 form.init .wpcf7-response-output,
|
||||
.wpcf7 form.resetting .wpcf7-response-output,
|
||||
.wpcf7 form.submitting .wpcf7-response-output {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.wpcf7 form.sent .wpcf7-response-output {
|
||||
border-color: #46b450; /* Green */
|
||||
}
|
||||
|
||||
.wpcf7 form.failed .wpcf7-response-output,
|
||||
.wpcf7 form.aborted .wpcf7-response-output {
|
||||
border-color: #dc3232; /* Red */
|
||||
}
|
||||
|
||||
.wpcf7 form.spam .wpcf7-response-output {
|
||||
border-color: #f56e28; /* Orange */
|
||||
}
|
||||
|
||||
.wpcf7 form.invalid .wpcf7-response-output,
|
||||
.wpcf7 form.unaccepted .wpcf7-response-output,
|
||||
.wpcf7 form.payment-required .wpcf7-response-output {
|
||||
border-color: #ffb900; /* Yellow */
|
||||
}
|
||||
|
||||
.wpcf7-form-control-wrap {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.wpcf7-not-valid-tip {
|
||||
color: #dc3232; /* Red */
|
||||
font-size: 1em;
|
||||
font-weight: normal;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.use-floating-validation-tip .wpcf7-not-valid-tip {
|
||||
position: relative;
|
||||
top: -2ex;
|
||||
left: 1em;
|
||||
z-index: 100;
|
||||
border: 1px solid #dc3232;
|
||||
background: #fff;
|
||||
padding: .2em .8em;
|
||||
width: 24em;
|
||||
}
|
||||
|
||||
.wpcf7-list-item {
|
||||
display: inline-block;
|
||||
margin: 0 0 0 1em;
|
||||
}
|
||||
|
||||
.wpcf7-list-item-label::before,
|
||||
.wpcf7-list-item-label::after {
|
||||
content: " ";
|
||||
}
|
||||
|
||||
.wpcf7-spinner {
|
||||
visibility: hidden;
|
||||
display: inline-block;
|
||||
background-color: #23282d; /* Dark Gray 800 */
|
||||
opacity: 0.75;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border: none;
|
||||
border-radius: 100%;
|
||||
padding: 0;
|
||||
margin: 0 24px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
form.submitting .wpcf7-spinner {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.wpcf7-spinner::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
background-color: #fbfbfc; /* Light Gray 100 */
|
||||
top: 4px;
|
||||
left: 4px;
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border: none;
|
||||
border-radius: 100%;
|
||||
transform-origin: 8px 8px;
|
||||
animation-name: spin;
|
||||
animation-duration: 1000ms;
|
||||
animation-timing-function: linear;
|
||||
animation-iteration-count: infinite;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.wpcf7-spinner::before {
|
||||
animation-name: blink;
|
||||
animation-duration: 2000ms;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes blink {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
50% {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.wpcf7 [inert] {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.wpcf7 input[type="file"] {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.wpcf7 input[type="file"]:disabled {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.wpcf7 .wpcf7-submit:disabled {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.wpcf7 input[type="url"],
|
||||
.wpcf7 input[type="email"],
|
||||
.wpcf7 input[type="tel"] {
|
||||
direction: ltr;
|
||||
}
|
||||
|
||||
.wpcf7-reflection > output {
|
||||
display: list-item;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.wpcf7-reflection > output[hidden] {
|
||||
display: none;
|
||||
}
|
||||
440
wp-content/plugins/contact-form-7/includes/file.php
Normal file
@ -0,0 +1,440 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Validates uploaded files and moves them to the temporary directory.
|
||||
*
|
||||
* @param array $file An item of `$_FILES`.
|
||||
* @param string|array $options Optional. Options to control behavior.
|
||||
* @return array|WP_Error Array of file paths, or WP_Error if validation fails.
|
||||
*/
|
||||
function wpcf7_unship_uploaded_file( $file, $options = '' ) {
|
||||
$filesystem = WPCF7_Filesystem::get_instance();
|
||||
|
||||
$options = wp_parse_args( $options, array(
|
||||
'required' => false,
|
||||
'filetypes' => '',
|
||||
'limit' => MB_IN_BYTES,
|
||||
) );
|
||||
|
||||
foreach ( array( 'name', 'size', 'tmp_name', 'error' ) as $key ) {
|
||||
if ( ! isset( $file[$key] ) ) {
|
||||
$file[$key] = array();
|
||||
}
|
||||
}
|
||||
|
||||
$names = wpcf7_array_flatten( $file['name'] );
|
||||
$sizes = wpcf7_array_flatten( $file['size'] );
|
||||
$tmp_names = wpcf7_array_flatten( $file['tmp_name'] );
|
||||
$errors = wpcf7_array_flatten( $file['error'] );
|
||||
|
||||
foreach ( $errors as $error ) {
|
||||
if ( ! empty( $error ) and UPLOAD_ERR_NO_FILE !== $error ) {
|
||||
return new WP_Error( 'wpcf7_upload_failed_php_error',
|
||||
wpcf7_get_message( 'upload_failed_php_error' )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $options['schema'] ) and isset( $options['name'] ) ) {
|
||||
$context = array(
|
||||
'file' => true,
|
||||
'field' => $options['name'],
|
||||
);
|
||||
|
||||
foreach ( $options['schema']->validate( $context ) as $result ) {
|
||||
if ( is_wp_error( $result ) ) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Move uploaded file to tmp dir
|
||||
$uploads_dir = wpcf7_upload_tmp_dir();
|
||||
$uploads_dir = wpcf7_maybe_add_random_dir( $uploads_dir );
|
||||
|
||||
$uploaded_files = array();
|
||||
|
||||
foreach ( $names as $key => $name ) {
|
||||
$tmp_name = $tmp_names[$key];
|
||||
|
||||
if ( empty( $tmp_name ) or ! is_uploaded_file( $tmp_name ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$filename = $name;
|
||||
$filename = wpcf7_canonicalize( $filename, array( 'strto' => 'as-is' ) );
|
||||
$filename = wpcf7_antiscript_file_name( $filename );
|
||||
|
||||
$filename = apply_filters( 'wpcf7_upload_file_name',
|
||||
$filename, $name, $options
|
||||
);
|
||||
|
||||
$filename = wp_unique_filename( $uploads_dir, $filename );
|
||||
$new_file = path_join( $uploads_dir, $filename );
|
||||
|
||||
// phpcs:ignore Generic.PHP.ForbiddenFunctions.Found
|
||||
if ( false === @move_uploaded_file( $tmp_name, $new_file ) ) {
|
||||
return new WP_Error( 'wpcf7_upload_failed',
|
||||
wpcf7_get_message( 'upload_failed' )
|
||||
);
|
||||
}
|
||||
|
||||
// Make sure the uploaded file is only readable for the owner process.
|
||||
$filesystem->chmod( $new_file, 0400 );
|
||||
|
||||
$uploaded_files[] = $new_file;
|
||||
}
|
||||
|
||||
return $uploaded_files;
|
||||
}
|
||||
|
||||
|
||||
add_filter(
|
||||
'wpcf7_messages',
|
||||
'wpcf7_file_messages',
|
||||
10, 1
|
||||
);
|
||||
|
||||
/**
|
||||
* A wpcf7_messages filter callback that adds messages for
|
||||
* file-uploading fields.
|
||||
*/
|
||||
function wpcf7_file_messages( $messages ) {
|
||||
return array_merge( $messages, array(
|
||||
'upload_failed' => array(
|
||||
'description' => __( 'Uploading a file fails for any reason', 'contact-form-7' ),
|
||||
'default' => __( 'There was an unknown error uploading the file.', 'contact-form-7' ),
|
||||
),
|
||||
|
||||
'upload_file_type_invalid' => array(
|
||||
'description' => __( 'Uploaded file is not allowed for file type', 'contact-form-7' ),
|
||||
'default' => __( 'You are not allowed to upload files of this type.', 'contact-form-7' ),
|
||||
),
|
||||
|
||||
'upload_file_too_large' => array(
|
||||
'description' => __( 'Uploaded file is too large', 'contact-form-7' ),
|
||||
'default' => __( 'The uploaded file is too large.', 'contact-form-7' ),
|
||||
),
|
||||
|
||||
'upload_failed_php_error' => array(
|
||||
'description' => __( 'Uploading a file fails for PHP error', 'contact-form-7' ),
|
||||
'default' => __( 'There was an error uploading the file.', 'contact-form-7' ),
|
||||
),
|
||||
) );
|
||||
}
|
||||
|
||||
|
||||
add_filter(
|
||||
'wpcf7_form_enctype',
|
||||
'wpcf7_file_form_enctype_filter',
|
||||
10, 1
|
||||
);
|
||||
|
||||
/**
|
||||
* A wpcf7_form_enctype filter callback that sets the enctype attribute
|
||||
* to multipart/form-data if the form has file-uploading fields.
|
||||
*/
|
||||
function wpcf7_file_form_enctype_filter( $enctype ) {
|
||||
$multipart = (bool) wpcf7_scan_form_tags( array(
|
||||
'feature' => 'file-uploading',
|
||||
) );
|
||||
|
||||
if ( $multipart ) {
|
||||
$enctype = 'multipart/form-data';
|
||||
}
|
||||
|
||||
return $enctype;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Converts a MIME type string to an array of corresponding file extensions.
|
||||
*
|
||||
* @param string $mime MIME type.
|
||||
* Wildcard (*) is available for the subtype part.
|
||||
* @return array Corresponding file extensions.
|
||||
*/
|
||||
function wpcf7_convert_mime_to_ext( $mime ) {
|
||||
static $mime_types = array();
|
||||
|
||||
$mime_types = wp_get_mime_types();
|
||||
|
||||
$results = array();
|
||||
|
||||
if ( preg_match( '%^([a-z]+)/([*]|[a-z0-9.+-]+)$%i', $mime, $matches ) ) {
|
||||
foreach ( $mime_types as $key => $val ) {
|
||||
if (
|
||||
'*' === $matches[2] and str_starts_with( $val, $matches[1] . '/' ) or
|
||||
$val === $matches[0]
|
||||
) {
|
||||
$results = array_merge( $results, explode( '|', $key ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$results = array_unique( $results );
|
||||
$results = array_filter( $results );
|
||||
$results = array_values( $results );
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a formatted list of acceptable filetypes.
|
||||
*
|
||||
* @param string|array $types Optional. Array of filetypes.
|
||||
* @param string $format Optional. Pre-defined format designator.
|
||||
* @return string Formatted list of acceptable filetypes.
|
||||
*/
|
||||
function wpcf7_acceptable_filetypes( $types = 'default', $format = 'regex' ) {
|
||||
if ( 'default' === $types or empty( $types ) ) {
|
||||
$types = array(
|
||||
'audio/*',
|
||||
'video/*',
|
||||
'image/*',
|
||||
);
|
||||
} else {
|
||||
$types = array_map(
|
||||
static function ( $type ) {
|
||||
if ( is_string( $type ) ) {
|
||||
return preg_split( '/[\s|,]+/', strtolower( $type ) );
|
||||
}
|
||||
},
|
||||
(array) $types
|
||||
);
|
||||
|
||||
$types = wpcf7_array_flatten( $types );
|
||||
$types = array_filter( array_unique( $types ) );
|
||||
}
|
||||
|
||||
if ( 'attr' === $format or 'attribute' === $format ) {
|
||||
$types = array_map(
|
||||
static function ( $type ) {
|
||||
if ( false === strpos( $type, '/' ) ) {
|
||||
return sprintf( '.%s', trim( $type, '.' ) );
|
||||
} elseif ( preg_match( '%^([a-z]+)/[*]$%i', $type, $matches ) ) {
|
||||
if (
|
||||
in_array( $matches[1], array( 'audio', 'video', 'image' ), true )
|
||||
) {
|
||||
return $type;
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
} elseif ( wpcf7_convert_mime_to_ext( $type ) ) {
|
||||
return $type;
|
||||
}
|
||||
},
|
||||
$types
|
||||
);
|
||||
|
||||
$types = array_filter( $types );
|
||||
|
||||
return implode( ',', $types );
|
||||
|
||||
} elseif ( 'regex' === $format ) {
|
||||
$types = array_map(
|
||||
static function ( $type ) {
|
||||
if ( false === strpos( $type, '/' ) ) {
|
||||
return preg_quote( trim( $type, '.' ) );
|
||||
} elseif ( $type = wpcf7_convert_mime_to_ext( $type ) ) {
|
||||
return $type;
|
||||
}
|
||||
},
|
||||
$types
|
||||
);
|
||||
|
||||
$types = wpcf7_array_flatten( $types );
|
||||
$types = array_filter( array_unique( $types ) );
|
||||
|
||||
return implode( '|', $types );
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
|
||||
add_action(
|
||||
'wpcf7_init',
|
||||
'wpcf7_init_uploads',
|
||||
10, 0
|
||||
);
|
||||
|
||||
/**
|
||||
* Initializes the temporary directory for uploaded files.
|
||||
*/
|
||||
function wpcf7_init_uploads() {
|
||||
$dir = wpcf7_upload_tmp_dir();
|
||||
|
||||
if ( ! is_dir( $dir ) or ! wp_is_writable( $dir ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$htaccess_file = path_join( $dir, '.htaccess' );
|
||||
|
||||
if ( file_exists( $htaccess_file ) ) {
|
||||
list( $first_line_comment ) = (array) file(
|
||||
$htaccess_file,
|
||||
FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES
|
||||
);
|
||||
|
||||
if ( '# Apache 2.4+' === $first_line_comment ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$filesystem = WPCF7_Filesystem::get_instance();
|
||||
|
||||
$htaccess_body = '
|
||||
# Apache 2.4+
|
||||
<IfModule authz_core_module>
|
||||
Require all denied
|
||||
</IfModule>
|
||||
|
||||
# Apache 2.2
|
||||
<IfModule !authz_core_module>
|
||||
Deny from all
|
||||
</IfModule>
|
||||
';
|
||||
|
||||
$filesystem->put_contents( $htaccess_file, ltrim( $htaccess_body ) );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a child directory with a randomly generated name.
|
||||
*
|
||||
* @param string $dir The parent directory path.
|
||||
* @return string The child directory path if created, otherwise the parent.
|
||||
*/
|
||||
function wpcf7_maybe_add_random_dir( $dir ) {
|
||||
do {
|
||||
$dir_new = path_join( $dir, zeroise( wp_rand(), 10 ) );
|
||||
} while ( file_exists( $dir_new ) );
|
||||
|
||||
if ( wp_mkdir_p( $dir_new ) ) {
|
||||
return $dir_new;
|
||||
}
|
||||
|
||||
return $dir;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the directory path for uploaded files.
|
||||
*
|
||||
* @return string Directory path.
|
||||
*/
|
||||
function wpcf7_upload_tmp_dir() {
|
||||
static $output = '';
|
||||
|
||||
if ( $output ) {
|
||||
return $output;
|
||||
}
|
||||
|
||||
if ( defined( 'WPCF7_UPLOADS_TMP_DIR' ) ) {
|
||||
$dir = path_join( WP_CONTENT_DIR, WPCF7_UPLOADS_TMP_DIR );
|
||||
wp_mkdir_p( $dir );
|
||||
|
||||
if ( wpcf7_is_file_path_in_content_dir( $dir ) ) {
|
||||
return $output = $dir;
|
||||
}
|
||||
}
|
||||
|
||||
$dir = path_join( wpcf7_upload_dir( 'dir' ), 'wpcf7_uploads' );
|
||||
wp_mkdir_p( $dir );
|
||||
|
||||
return $output = $dir;
|
||||
}
|
||||
|
||||
|
||||
add_action(
|
||||
'shutdown',
|
||||
'wpcf7_cleanup_upload_files',
|
||||
20, 0
|
||||
);
|
||||
|
||||
/**
|
||||
* Cleans up files in the temporary directory for uploaded files.
|
||||
*
|
||||
* @param int $seconds Files older than this are removed. Default 60.
|
||||
* @param int $max Maximum number of files to be removed in a function call.
|
||||
* Default 100.
|
||||
*/
|
||||
function wpcf7_cleanup_upload_files( $seconds = 60, $max = 100 ) {
|
||||
$dir = trailingslashit( wpcf7_upload_tmp_dir() );
|
||||
|
||||
if (
|
||||
! is_dir( $dir ) or
|
||||
! is_readable( $dir ) or
|
||||
! wp_is_writable( $dir )
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
$seconds = absint( $seconds );
|
||||
$max = absint( $max );
|
||||
$count = 0;
|
||||
|
||||
if ( $handle = opendir( $dir ) ) {
|
||||
while ( false !== ( $file = readdir( $handle ) ) ) {
|
||||
if ( '.' === $file or '..' === $file or '.htaccess' === $file ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$mtime = @filemtime( path_join( $dir, $file ) );
|
||||
|
||||
if ( $mtime and time() < $mtime + $seconds ) { // less than $seconds old
|
||||
continue;
|
||||
}
|
||||
|
||||
wpcf7_rmdir_p( path_join( $dir, $file ) );
|
||||
$count += 1;
|
||||
|
||||
if ( $max <= $count ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
closedir( $handle );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
add_action(
|
||||
'wpcf7_admin_warnings',
|
||||
'wpcf7_file_display_warning_message',
|
||||
10, 3
|
||||
);
|
||||
|
||||
/**
|
||||
* Displays warning messages about file-uploading fields.
|
||||
*/
|
||||
function wpcf7_file_display_warning_message( $page, $action, $object ) {
|
||||
if ( $object instanceof WPCF7_ContactForm ) {
|
||||
$contact_form = $object;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
$has_tags = (bool) $contact_form->scan_form_tags( array(
|
||||
'feature' => 'file-uploading',
|
||||
) );
|
||||
|
||||
if ( ! $has_tags ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$uploads_dir = wpcf7_upload_tmp_dir();
|
||||
|
||||
if ( ! is_dir( $uploads_dir ) or ! wp_is_writable( $uploads_dir ) ) {
|
||||
wp_admin_notice(
|
||||
sprintf(
|
||||
/* translators: %s: the path of the temporary folder */
|
||||
__( 'This contact form has file uploading fields, but the temporary folder for the files (%s) does not exist or is not writable. You can create the folder or change its permission manually.', 'contact-form-7' ),
|
||||
$uploads_dir
|
||||
),
|
||||
array( 'type' => 'warning' )
|
||||
);
|
||||
}
|
||||
}
|
||||
127
wp-content/plugins/contact-form-7/includes/filesystem.php
Normal file
@ -0,0 +1,127 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class for filesystem operations.
|
||||
*/
|
||||
class WPCF7_Filesystem {
|
||||
|
||||
/**
|
||||
* The singleton instance.
|
||||
*
|
||||
* @var WPCF7_Filesystem
|
||||
*/
|
||||
private static $instance;
|
||||
|
||||
/**
|
||||
* Filesystem object.
|
||||
*
|
||||
* @var WP_Filesystem_Base
|
||||
*/
|
||||
private $filesystem;
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the singleton instance.
|
||||
*/
|
||||
public static function get_instance() {
|
||||
if ( empty( self::$instance ) ) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
private function __construct() {
|
||||
$this->connect();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Connects to the filesystem.
|
||||
*
|
||||
* @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass.
|
||||
*/
|
||||
private function connect() {
|
||||
global $wp_filesystem;
|
||||
|
||||
if ( $this->filesystem ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
require_once ABSPATH . 'wp-admin/includes/file.php';
|
||||
require_once ABSPATH . 'wp-admin/includes/class-wp-filesystem-base.php';
|
||||
require_once ABSPATH . 'wp-admin/includes/class-wp-filesystem-direct.php';
|
||||
|
||||
ob_start();
|
||||
$credentials = request_filesystem_credentials( '' );
|
||||
ob_end_clean();
|
||||
|
||||
if ( false === $credentials or ! WP_Filesystem( $credentials ) ) {
|
||||
wp_trigger_error(
|
||||
__FUNCTION__,
|
||||
__( 'Could not access filesystem.', 'contact-form-7' )
|
||||
);
|
||||
}
|
||||
|
||||
if ( $wp_filesystem instanceof WP_Filesystem_Base ) {
|
||||
$this->filesystem = $wp_filesystem;
|
||||
} else {
|
||||
$this->filesystem = new WP_Filesystem_Direct( 1 );
|
||||
}
|
||||
|
||||
if ( ! defined( 'FS_CHMOD_DIR' ) ) {
|
||||
define( 'FS_CHMOD_DIR', fileperms( ABSPATH ) & 0777 | 0755 );
|
||||
}
|
||||
|
||||
if ( ! defined( 'FS_CHMOD_FILE' ) ) {
|
||||
define( 'FS_CHMOD_FILE', fileperms( ABSPATH . 'index.php' ) & 0777 | 0644 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Changes filesystem permissions.
|
||||
*
|
||||
* @param string $file Path to the file.
|
||||
* @param int|false $mode Optional. The permissions as octal number.
|
||||
* @param bool $recursive Optional. If set to true,
|
||||
* changes file permissions recursively. Default false.
|
||||
* @return bool True on success, false on failure.
|
||||
*/
|
||||
public function chmod( $file, $mode = false, $recursive = false ) {
|
||||
return $this->filesystem->chmod( $file, $mode, $recursive );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Deletes a file or directory.
|
||||
*
|
||||
* @param string $file Path to the file or directory.
|
||||
* @param bool $recursive Optional. If set to true, deletes
|
||||
* files and folders recursively. Default false.
|
||||
* @param string|false $type Type of resource.
|
||||
* 'f' for file, 'd' for directory. Default false.
|
||||
* @return bool True on success, false on failure.
|
||||
*/
|
||||
public function delete( $file, $recursive = false, $type = false ) {
|
||||
return $this->filesystem->delete( $file, $recursive, $type );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Writes a string to a file.
|
||||
*
|
||||
* @param string $file Path to the file where to write the data.
|
||||
* @param string $contents The data to write.
|
||||
* @param int $mode The file permissions as octal number.
|
||||
* @return bool True on success, false on failure.
|
||||
*/
|
||||
public function put_contents( $file, $contents, $mode = false ) {
|
||||
return $this->filesystem->put_contents( $file, $contents, $mode );
|
||||
}
|
||||
|
||||
}
|
||||
618
wp-content/plugins/contact-form-7/includes/form-tag.php
Normal file
@ -0,0 +1,618 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* A form-tag.
|
||||
*
|
||||
* @link https://contactform7.com/tag-syntax/#form_tag
|
||||
*/
|
||||
class WPCF7_FormTag implements ArrayAccess {
|
||||
|
||||
public $type;
|
||||
public $basetype;
|
||||
public $raw_name = '';
|
||||
public $name = '';
|
||||
public $options = array();
|
||||
public $raw_values = array();
|
||||
public $values = array();
|
||||
public $pipes;
|
||||
public $labels = array();
|
||||
public $attr = '';
|
||||
public $content = '';
|
||||
|
||||
public function __construct( $tag = array() ) {
|
||||
if ( is_array( $tag ) or $tag instanceof self ) {
|
||||
foreach ( $tag as $key => $value ) {
|
||||
if ( property_exists( __CLASS__, $key ) ) {
|
||||
$this->{$key} = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the type has a trailing asterisk.
|
||||
*/
|
||||
public function is_required() {
|
||||
return str_ends_with( $this->type, '*' );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the form-tag has a specified option.
|
||||
*/
|
||||
public function has_option( $option_name ) {
|
||||
$pattern = sprintf( '/^%s(:.+)?$/i', preg_quote( $option_name, '/' ) );
|
||||
return (bool) preg_grep( $pattern, $this->options );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves option values with the specified option name.
|
||||
*
|
||||
* @param string $option_name Option name.
|
||||
* @param string $pattern Optional. A regular expression pattern or one of
|
||||
* the keys of preset patterns. If specified, only options
|
||||
* whose value part matches this pattern will be returned.
|
||||
* @param bool $single Optional. If true, only the first matching option
|
||||
* will be returned. Default false.
|
||||
* @return string|array|bool The option value or an array of option values.
|
||||
* False if there is no option matches the pattern.
|
||||
*/
|
||||
public function get_option( $option_name, $pattern = '', $single = false ) {
|
||||
$preset_patterns = array(
|
||||
'date' => '[0-9]{4}-[0-9]{2}-[0-9]{2}',
|
||||
'int' => '[0-9]+',
|
||||
'signed_int' => '[-]?[0-9]+',
|
||||
'num' => '(?:[0-9]+|(?:[0-9]+)?[.][0-9]+)',
|
||||
'signed_num' => '[-]?(?:[0-9]+|(?:[0-9]+)?[.][0-9]+)',
|
||||
'class' => '[-0-9a-zA-Z_]+',
|
||||
'id' => '[-0-9a-zA-Z_]+',
|
||||
);
|
||||
|
||||
if ( isset( $preset_patterns[$pattern] ) ) {
|
||||
$pattern = $preset_patterns[$pattern];
|
||||
}
|
||||
|
||||
if ( '' === $pattern ) {
|
||||
$pattern = '.+';
|
||||
}
|
||||
|
||||
$pattern = sprintf(
|
||||
'/^%s:%s$/i',
|
||||
preg_quote( $option_name, '/' ),
|
||||
$pattern
|
||||
);
|
||||
|
||||
if ( $single ) {
|
||||
$matches = $this->get_first_match_option( $pattern );
|
||||
|
||||
if ( ! $matches ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return substr( $matches[0], strlen( $option_name ) + 1 );
|
||||
} else {
|
||||
$matches_a = $this->get_all_match_options( $pattern );
|
||||
|
||||
if ( ! $matches_a ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$results = array();
|
||||
|
||||
foreach ( $matches_a as $matches ) {
|
||||
$results[] = substr( $matches[0], strlen( $option_name ) + 1 );
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the id option value from the form-tag.
|
||||
*/
|
||||
public function get_id_option() {
|
||||
static $used = array();
|
||||
|
||||
$option = $this->get_option( 'id', 'id', true );
|
||||
|
||||
if (
|
||||
! $option or
|
||||
str_starts_with( $option, 'wpcf7' ) or
|
||||
in_array( $option, $used, true )
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$used[] = $option;
|
||||
|
||||
return $option;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the class option value from the form-tag.
|
||||
*
|
||||
* @param string|array $default_classes Optional. Preset classes as an array
|
||||
* or a whitespace-separated list. Default empty string.
|
||||
* @return string|bool A whitespace-separated list of classes.
|
||||
* False if there is no class to return.
|
||||
*/
|
||||
public function get_class_option( $default_classes = '' ) {
|
||||
if ( is_string( $default_classes ) ) {
|
||||
$default_classes = explode( ' ', $default_classes );
|
||||
}
|
||||
|
||||
$options = array_merge(
|
||||
(array) $default_classes,
|
||||
(array) $this->get_option( 'class' )
|
||||
);
|
||||
|
||||
$options = array_map( 'sanitize_html_class', $options );
|
||||
$options = array_filter( array_unique( $options ) );
|
||||
|
||||
if ( empty( $options ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return implode( ' ', $options );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the autocomplete option value from the form-tag.
|
||||
*
|
||||
* @return string|bool A whitespace-separated list of tokens.
|
||||
* False if there is no token to return.
|
||||
*/
|
||||
public function get_autocomplete_option() {
|
||||
$options = (array) $this->get_option( 'autocomplete', '[-0-9a-zA-Z|]+' );
|
||||
|
||||
$options = array_reduce( $options, static function ( $carry, $item ) {
|
||||
return array_merge( $carry,
|
||||
array_map( 'strtolower', explode( '|', $item ) )
|
||||
);
|
||||
}, array() );
|
||||
|
||||
$options = array_filter( $options, static function ( $item ) {
|
||||
return preg_match( '/^[a-z]+(?:-[0-9a-z]+)*$/', $item );
|
||||
} );
|
||||
|
||||
$options = array_unique( $options );
|
||||
|
||||
if ( empty( $options ) ) {
|
||||
return false;
|
||||
} elseif ( in_array( 'off', $options, true ) ) {
|
||||
return 'off';
|
||||
} elseif ( in_array( 'on', $options, true ) ) {
|
||||
return 'on';
|
||||
} else {
|
||||
return implode( ' ', $options );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the size option value from the form-tag.
|
||||
*
|
||||
* @param string $default_value Optional default value.
|
||||
* @return string The option value.
|
||||
*/
|
||||
public function get_size_option( $default_value = false ) {
|
||||
$option = $this->get_option( 'size', 'int', true );
|
||||
|
||||
if ( $option ) {
|
||||
return $option;
|
||||
}
|
||||
|
||||
$matches_a = $this->get_all_match_options( '%^([0-9]*)/[0-9]*$%' );
|
||||
|
||||
foreach ( $matches_a as $matches ) {
|
||||
if ( isset( $matches[1] ) and '' !== $matches[1] ) {
|
||||
return $matches[1];
|
||||
}
|
||||
}
|
||||
|
||||
return $default_value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the maxlength option value from the form-tag.
|
||||
*
|
||||
* @param string $default_value Optional default value.
|
||||
* @return string The option value.
|
||||
*/
|
||||
public function get_maxlength_option( $default_value = false ) {
|
||||
$option = $this->get_option( 'maxlength', 'int', true );
|
||||
|
||||
if ( $option ) {
|
||||
return $option;
|
||||
}
|
||||
|
||||
$matches_a = $this->get_all_match_options(
|
||||
'%^(?:[0-9]*x?[0-9]*)?/([0-9]+)$%'
|
||||
);
|
||||
|
||||
foreach ( $matches_a as $matches ) {
|
||||
if ( isset( $matches[1] ) and '' !== $matches[1] ) {
|
||||
return $matches[1];
|
||||
}
|
||||
}
|
||||
|
||||
return $default_value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the minlength option value from the form-tag.
|
||||
*
|
||||
* @param string $default_value Optional default value.
|
||||
* @return string The option value.
|
||||
*/
|
||||
public function get_minlength_option( $default_value = false ) {
|
||||
$option = $this->get_option( 'minlength', 'int', true );
|
||||
|
||||
if ( $option ) {
|
||||
return $option;
|
||||
} else {
|
||||
return $default_value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the cols option value from the form-tag.
|
||||
*
|
||||
* @param string $default_value Optional default value.
|
||||
* @return string The option value.
|
||||
*/
|
||||
public function get_cols_option( $default_value = false ) {
|
||||
$option = $this->get_option( 'cols', 'int', true );
|
||||
|
||||
if ( $option ) {
|
||||
return $option;
|
||||
}
|
||||
|
||||
$matches_a = $this->get_all_match_options(
|
||||
'%^([0-9]*)x([0-9]*)(?:/[0-9]+)?$%'
|
||||
);
|
||||
|
||||
foreach ( $matches_a as $matches ) {
|
||||
if ( isset( $matches[1] ) and '' !== $matches[1] ) {
|
||||
return $matches[1];
|
||||
}
|
||||
}
|
||||
|
||||
return $default_value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the rows option value from the form-tag.
|
||||
*
|
||||
* @param string $default_value Optional default value.
|
||||
* @return string The option value.
|
||||
*/
|
||||
public function get_rows_option( $default_value = false ) {
|
||||
$option = $this->get_option( 'rows', 'int', true );
|
||||
|
||||
if ( $option ) {
|
||||
return $option;
|
||||
}
|
||||
|
||||
$matches_a = $this->get_all_match_options(
|
||||
'%^([0-9]*)x([0-9]*)(?:/[0-9]+)?$%'
|
||||
);
|
||||
|
||||
foreach ( $matches_a as $matches ) {
|
||||
if ( isset( $matches[2] ) and '' !== $matches[2] ) {
|
||||
return $matches[2];
|
||||
}
|
||||
}
|
||||
|
||||
return $default_value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves a date-type option value from the form-tag.
|
||||
*
|
||||
* @param string $option_name A date-type option name, such as 'min' or 'max'.
|
||||
* @return string|bool The option value in YYYY-MM-DD format. False if the
|
||||
* option does not exist or the date value is invalid.
|
||||
*/
|
||||
public function get_date_option( $option_name ) {
|
||||
$option_value = $this->get_option( $option_name, '', true );
|
||||
|
||||
if ( empty( $option_value ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$date = apply_filters( 'wpcf7_form_tag_date_option',
|
||||
null,
|
||||
array( $option_name => $option_value )
|
||||
);
|
||||
|
||||
if ( $date ) {
|
||||
$date_pattern = '/^([0-9]{4})-([0-9]{2})-([0-9]{2})$/';
|
||||
|
||||
if (
|
||||
preg_match( $date_pattern, $date, $matches ) and
|
||||
checkdate( $matches[2], $matches[3], $matches[1] )
|
||||
) {
|
||||
return $date;
|
||||
}
|
||||
} else {
|
||||
$datetime_obj = date_create_immutable(
|
||||
preg_replace( '/[_]+/', ' ', $option_value ),
|
||||
wp_timezone()
|
||||
);
|
||||
|
||||
if ( $datetime_obj ) {
|
||||
return $datetime_obj->format( 'Y-m-d' );
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the default option value from the form-tag.
|
||||
*
|
||||
* @param string|array $default_value Optional default value.
|
||||
* @param string|array $args Optional options for the option value retrieval.
|
||||
* @return string|array The option value. If the multiple option is enabled,
|
||||
* an array of option values.
|
||||
*/
|
||||
public function get_default_option( $default_value = '', $args = '' ) {
|
||||
$args = wp_parse_args( $args, array(
|
||||
'multiple' => false,
|
||||
'shifted' => false,
|
||||
) );
|
||||
|
||||
$options = (array) $this->get_option( 'default' );
|
||||
$values = array();
|
||||
|
||||
if ( empty( $options ) ) {
|
||||
return $args['multiple'] ? $values : $default_value;
|
||||
}
|
||||
|
||||
foreach ( $options as $opt ) {
|
||||
$opt = sanitize_key( $opt );
|
||||
|
||||
if ( 'user_' === substr( $opt, 0, 5 ) and is_user_logged_in() ) {
|
||||
$primary_props = array( 'user_login', 'user_email', 'user_url' );
|
||||
$opt = in_array( $opt, $primary_props, true ) ? $opt : substr( $opt, 5 );
|
||||
|
||||
$user = wp_get_current_user();
|
||||
$user_prop = $user->get( $opt );
|
||||
|
||||
if ( ! empty( $user_prop ) ) {
|
||||
if ( $args['multiple'] ) {
|
||||
$values[] = $user_prop;
|
||||
} else {
|
||||
return $user_prop;
|
||||
}
|
||||
}
|
||||
|
||||
} elseif ( 'post_meta' === $opt and in_the_loop() ) {
|
||||
if ( $args['multiple'] ) {
|
||||
$values = array_merge( $values,
|
||||
get_post_meta( get_the_ID(), $this->name )
|
||||
);
|
||||
} else {
|
||||
$val = (string) get_post_meta( get_the_ID(), $this->name, true );
|
||||
|
||||
if ( strlen( $val ) ) {
|
||||
return $val;
|
||||
}
|
||||
}
|
||||
|
||||
} elseif (
|
||||
'get' === $opt and
|
||||
$vals = wpcf7_superglobal_get( $this->name )
|
||||
) {
|
||||
$vals = array_map( 'wpcf7_sanitize_query_var', (array) $vals );
|
||||
|
||||
if ( $args['multiple'] ) {
|
||||
$values = array_merge( $values, $vals );
|
||||
} else {
|
||||
$val = isset( $vals[0] ) ? (string) $vals[0] : '';
|
||||
|
||||
if ( strlen( $val ) ) {
|
||||
return $val;
|
||||
}
|
||||
}
|
||||
|
||||
} elseif (
|
||||
'post' === $opt and
|
||||
$vals = wpcf7_superglobal_post( $this->name )
|
||||
) {
|
||||
$vals = array_map( 'wpcf7_sanitize_query_var', (array) $vals );
|
||||
|
||||
if ( $args['multiple'] ) {
|
||||
$values = array_merge( $values, $vals );
|
||||
} else {
|
||||
$val = isset( $vals[0] ) ? (string) $vals[0] : '';
|
||||
|
||||
if ( strlen( $val ) ) {
|
||||
return $val;
|
||||
}
|
||||
}
|
||||
|
||||
} elseif ( 'shortcode_attr' === $opt ) {
|
||||
if ( $contact_form = WPCF7_ContactForm::get_current() ) {
|
||||
$val = $contact_form->shortcode_attr( $this->name );
|
||||
|
||||
if ( isset( $val ) and strlen( $val ) ) {
|
||||
if ( $args['multiple'] ) {
|
||||
$values[] = $val;
|
||||
} else {
|
||||
return $val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} elseif ( preg_match( '/^[0-9_]+$/', $opt ) ) {
|
||||
$nums = explode( '_', $opt );
|
||||
|
||||
foreach ( $nums as $num ) {
|
||||
$num = absint( $num );
|
||||
$num = $args['shifted'] ? $num : $num - 1;
|
||||
|
||||
if ( isset( $this->values[$num] ) ) {
|
||||
if ( $args['multiple'] ) {
|
||||
$values[] = $this->values[$num];
|
||||
} else {
|
||||
return $this->values[$num];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( $args['multiple'] ) {
|
||||
$values = array_unique( $values );
|
||||
return $values;
|
||||
} else {
|
||||
return $default_value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the data option value from the form-tag.
|
||||
*
|
||||
* @param string|array $args Optional options for the option value retrieval.
|
||||
* @return mixed The option value.
|
||||
*/
|
||||
public function get_data_option( $args = '' ) {
|
||||
$options = (array) $this->get_option( 'data' );
|
||||
|
||||
return apply_filters( 'wpcf7_form_tag_data_option', null, $options, $args );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the limit option value from the form-tag.
|
||||
*
|
||||
* @param int $default_value Optional default value. Default 1048576.
|
||||
* @return int The option value.
|
||||
*/
|
||||
public function get_limit_option( $default_value = MB_IN_BYTES ) {
|
||||
$pattern = '/^limit:([1-9][0-9]*)([kKmM]?[bB])?$/';
|
||||
|
||||
$matches = $this->get_first_match_option( $pattern );
|
||||
|
||||
if ( $matches ) {
|
||||
$size = (int) $matches[1];
|
||||
|
||||
if ( ! empty( $matches[2] ) ) {
|
||||
$kbmb = strtolower( $matches[2] );
|
||||
|
||||
if ( 'kb' === $kbmb ) {
|
||||
$size *= KB_IN_BYTES;
|
||||
} elseif ( 'mb' === $kbmb ) {
|
||||
$size *= MB_IN_BYTES;
|
||||
}
|
||||
}
|
||||
|
||||
return $size;
|
||||
}
|
||||
|
||||
return (int) $default_value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the value of the first option matches the given
|
||||
* regular expression pattern.
|
||||
*
|
||||
* @param string $pattern Regular expression pattern.
|
||||
* @return array|bool Option value as an array of matched strings.
|
||||
* False if there is no option matches the pattern.
|
||||
*/
|
||||
public function get_first_match_option( $pattern ) {
|
||||
foreach ( (array) $this->options as $option ) {
|
||||
if ( preg_match( $pattern, $option, $matches ) ) {
|
||||
return $matches;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves values of options that match the given
|
||||
* regular expression pattern.
|
||||
*
|
||||
* @param string $pattern Regular expression pattern.
|
||||
* @return array Array of arrays of strings that match the pattern.
|
||||
*/
|
||||
public function get_all_match_options( $pattern ) {
|
||||
$result = array();
|
||||
|
||||
foreach ( (array) $this->options as $option ) {
|
||||
if ( preg_match( $pattern, $option, $matches ) ) {
|
||||
$result[] = $matches;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Assigns a value to the specified offset.
|
||||
*
|
||||
* @link https://www.php.net/manual/en/arrayaccess.offsetset.php
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function offsetSet( $offset, $value ) {
|
||||
if ( property_exists( __CLASS__, $offset ) ) {
|
||||
$this->{$offset} = $value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the value at specified offset.
|
||||
*
|
||||
* @link https://www.php.net/manual/en/arrayaccess.offsetget.php
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function offsetGet( $offset ) {
|
||||
if ( property_exists( __CLASS__, $offset ) ) {
|
||||
return $this->{$offset};
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the specified offset exists.
|
||||
*
|
||||
* @link https://www.php.net/manual/en/arrayaccess.offsetexists.php
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function offsetExists( $offset ) {
|
||||
return property_exists( __CLASS__, $offset );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Unsets an offset.
|
||||
*
|
||||
* @link https://www.php.net/manual/en/arrayaccess.offsetunset.php
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function offsetUnset( $offset ) {
|
||||
}
|
||||
|
||||
}
|
||||
615
wp-content/plugins/contact-form-7/includes/form-tags-manager.php
Normal file
@ -0,0 +1,615 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Wrapper function of WPCF7_FormTagsManager::add().
|
||||
*/
|
||||
function wpcf7_add_form_tag( $tag_types, $callback, $features = '' ) {
|
||||
$manager = WPCF7_FormTagsManager::get_instance();
|
||||
|
||||
return $manager->add( $tag_types, $callback, $features );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Wrapper function of WPCF7_FormTagsManager::remove().
|
||||
*/
|
||||
function wpcf7_remove_form_tag( $tag_type ) {
|
||||
$manager = WPCF7_FormTagsManager::get_instance();
|
||||
|
||||
return $manager->remove( $tag_type );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Wrapper function of WPCF7_FormTagsManager::replace_all().
|
||||
*/
|
||||
function wpcf7_replace_all_form_tags( $content ) {
|
||||
$manager = WPCF7_FormTagsManager::get_instance();
|
||||
|
||||
return $manager->replace_all( $content );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Wrapper function of WPCF7_ContactForm::scan_form_tags().
|
||||
*/
|
||||
function wpcf7_scan_form_tags( $cond = null ) {
|
||||
$contact_form = WPCF7_ContactForm::get_current();
|
||||
|
||||
if ( $contact_form ) {
|
||||
return $contact_form->scan_form_tags( $cond );
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Wrapper function of WPCF7_FormTagsManager::tag_type_supports().
|
||||
*/
|
||||
function wpcf7_form_tag_supports( $tag_type, $feature ) {
|
||||
$manager = WPCF7_FormTagsManager::get_instance();
|
||||
|
||||
return $manager->tag_type_supports( $tag_type, $feature );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The singleton instance of this class manages the collection of form-tags.
|
||||
*/
|
||||
class WPCF7_FormTagsManager {
|
||||
|
||||
private static $instance;
|
||||
|
||||
private $tag_types = array();
|
||||
private $scanned_tags = null; // Tags scanned at the last time of scan()
|
||||
private $placeholders = array();
|
||||
|
||||
private function __construct() {}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the singleton instance.
|
||||
*
|
||||
* @return WPCF7_FormTagsManager The singleton manager.
|
||||
*/
|
||||
public static function get_instance() {
|
||||
if ( empty( self::$instance ) ) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns scanned form-tags.
|
||||
*
|
||||
* @return array Array of WPCF7_FormTag objects.
|
||||
*/
|
||||
public function get_scanned_tags() {
|
||||
return $this->scanned_tags;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Registers form-tag types to the manager.
|
||||
*
|
||||
* @param string|array $tag_types The name of the form-tag type or
|
||||
* an array of the names.
|
||||
* @param callable $callback The callback to generates a form control HTML
|
||||
* for a form-tag in this type.
|
||||
* @param string|array $features Optional. Features a form-tag
|
||||
* in this type supports.
|
||||
*/
|
||||
public function add( $tag_types, $callback, $features = '' ) {
|
||||
if ( ! is_callable( $callback ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( true === $features ) { // for back-compat
|
||||
$features = array( 'name-attr' => true );
|
||||
}
|
||||
|
||||
$features = wp_parse_args( $features, array() );
|
||||
|
||||
$tag_types = array_filter( array_unique( (array) $tag_types ) );
|
||||
|
||||
foreach ( $tag_types as $tag_type ) {
|
||||
$tag_type = $this->sanitize_tag_type( $tag_type );
|
||||
|
||||
if ( ! $this->tag_type_exists( $tag_type ) ) {
|
||||
$this->tag_types[$tag_type] = array(
|
||||
'function' => $callback,
|
||||
'features' => $features,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the given tag type exists.
|
||||
*/
|
||||
public function tag_type_exists( $tag_type ) {
|
||||
return isset( $this->tag_types[$tag_type] );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the tag type supports the features.
|
||||
*
|
||||
* @param string $tag_type The name of the form-tag type.
|
||||
* @param array|string $features The feature to check or an array of features.
|
||||
* @return bool True if the form-tag type supports at least one of
|
||||
* the given features, false otherwise.
|
||||
*/
|
||||
public function tag_type_supports( $tag_type, $features ) {
|
||||
$features = array_filter( (array) $features );
|
||||
|
||||
if ( isset( $this->tag_types[$tag_type]['features'] ) ) {
|
||||
return (bool) array_intersect(
|
||||
array_keys( array_filter( $this->tag_types[$tag_type]['features'] ) ),
|
||||
$features
|
||||
);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns form-tag types that support the given features.
|
||||
*
|
||||
* @param array|string $features Optional. The feature to check or
|
||||
* an array of features. Default empty array.
|
||||
* @param bool $invert Optional. If this value is true, returns form-tag
|
||||
* types that do not support the given features. Default false.
|
||||
* @return array An array of form-tag types. If the $features param is empty,
|
||||
* returns all form-tag types that have been registered.
|
||||
*/
|
||||
public function collect_tag_types( $features = array(), $invert = false ) {
|
||||
$tag_types = array_keys( $this->tag_types );
|
||||
|
||||
if ( empty( $features ) ) {
|
||||
return $tag_types;
|
||||
}
|
||||
|
||||
$output = array();
|
||||
|
||||
foreach ( $tag_types as $tag_type ) {
|
||||
if (
|
||||
! $invert and $this->tag_type_supports( $tag_type, $features ) or
|
||||
$invert and ! $this->tag_type_supports( $tag_type, $features )
|
||||
) {
|
||||
$output[] = $tag_type;
|
||||
}
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sanitizes the form-tag type name.
|
||||
*/
|
||||
private function sanitize_tag_type( $tag_type ) {
|
||||
$tag_type = preg_replace( '/[^a-zA-Z0-9_*]+/', '_', $tag_type );
|
||||
$tag_type = rtrim( $tag_type, '_' );
|
||||
$tag_type = strtolower( $tag_type );
|
||||
return $tag_type;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Deregisters the form-tag type.
|
||||
*/
|
||||
public function remove( $tag_type ) {
|
||||
unset( $this->tag_types[$tag_type] );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Normalizes the text content that includes form-tags.
|
||||
*/
|
||||
public function normalize( $content ) {
|
||||
if ( empty( $this->tag_types ) ) {
|
||||
return $content;
|
||||
}
|
||||
|
||||
$content = preg_replace_callback(
|
||||
'/' . $this->tag_regex() . '/su',
|
||||
array( $this, 'normalize_callback' ),
|
||||
$content
|
||||
);
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The callback function used within normalize().
|
||||
*/
|
||||
private function normalize_callback( $matches ) {
|
||||
// allow [[foo]] syntax for escaping a tag
|
||||
if ( '[' === $matches[1] and ']' === $matches[6] ) {
|
||||
return $matches[0];
|
||||
}
|
||||
|
||||
$tag = $matches[2];
|
||||
|
||||
$attr = trim( preg_replace( '/[\r\n\t ]+/', ' ', $matches[3] ) );
|
||||
$attr = strtr( $attr, array( '<' => '<', '>' => '>' ) );
|
||||
|
||||
$content = trim( $matches[5] );
|
||||
$content = str_replace( "\n", '<WPPreserveNewline />', $content );
|
||||
|
||||
$result = $matches[1] . '[' . $tag
|
||||
. ( $attr ? ' ' . $attr : '' )
|
||||
. ( $matches[4] ? ' ' . $matches[4] : '' )
|
||||
. ']'
|
||||
. ( $content ? $content . '[/' . $tag . ']' : '' )
|
||||
. $matches[6];
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Replace all form-tags in the given text with placeholders.
|
||||
*/
|
||||
public function replace_with_placeholders( $content ) {
|
||||
if ( empty( $this->tag_types ) ) {
|
||||
return $content;
|
||||
}
|
||||
|
||||
$this->placeholders = array();
|
||||
|
||||
$callback = function ( $matches ) {
|
||||
// Allow [[foo]] syntax for escaping a tag.
|
||||
if ( '[' === $matches[1] and ']' === $matches[6] ) {
|
||||
return $matches[0];
|
||||
}
|
||||
|
||||
$tag = $matches[0];
|
||||
$tag_type = $matches[2];
|
||||
|
||||
$block_or_hidden = $this->tag_type_supports(
|
||||
$tag_type,
|
||||
array( 'display-block', 'display-hidden' )
|
||||
);
|
||||
|
||||
if ( $block_or_hidden ) {
|
||||
$placeholder_tag_name = WPCF7_HTMLFormatter::placeholder_block;
|
||||
} else {
|
||||
$placeholder_tag_name = WPCF7_HTMLFormatter::placeholder_inline;
|
||||
}
|
||||
|
||||
$placeholder = sprintf(
|
||||
'<%1$s id="%2$s" />',
|
||||
$placeholder_tag_name,
|
||||
hash( 'sha256', $tag )
|
||||
);
|
||||
|
||||
list( $placeholder ) =
|
||||
WPCF7_HTMLFormatter::normalize_start_tag( $placeholder );
|
||||
|
||||
$this->placeholders[$placeholder] = $tag;
|
||||
|
||||
return $placeholder;
|
||||
};
|
||||
|
||||
return preg_replace_callback(
|
||||
'/' . $this->tag_regex() . '/su',
|
||||
$callback,
|
||||
$content
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Replace placeholders in the given text with original form-tags.
|
||||
*/
|
||||
public function restore_from_placeholders( $content ) {
|
||||
return str_replace(
|
||||
array_keys( $this->placeholders ),
|
||||
array_values( $this->placeholders ),
|
||||
$content
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Replaces all form-tags in the text content.
|
||||
*
|
||||
* @param string $content The text content including form-tags.
|
||||
* @return string The result of replacements.
|
||||
*/
|
||||
public function replace_all( $content ) {
|
||||
return $this->scan( $content, true );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Scans form-tags in the text content.
|
||||
*
|
||||
* @param string $content The text content including form-tags.
|
||||
* @param bool $replace Optional. Whether scanned form-tags will be
|
||||
* replaced. Default false.
|
||||
* @return array|string An array of scanned form-tags if $replace is false.
|
||||
* Otherwise text that scanned form-tags are replaced.
|
||||
*/
|
||||
public function scan( $content, $replace = false ) {
|
||||
$this->scanned_tags = array();
|
||||
|
||||
if ( empty( $this->tag_types ) ) {
|
||||
if ( $replace ) {
|
||||
return $content;
|
||||
} else {
|
||||
return $this->scanned_tags;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $replace ) {
|
||||
$content = preg_replace_callback(
|
||||
'/' . $this->tag_regex() . '/su',
|
||||
array( $this, 'replace_callback' ),
|
||||
$content
|
||||
);
|
||||
|
||||
return $content;
|
||||
} else {
|
||||
preg_replace_callback(
|
||||
'/' . $this->tag_regex() . '/su',
|
||||
array( $this, 'scan_callback' ),
|
||||
$content
|
||||
);
|
||||
|
||||
return $this->scanned_tags;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Filters form-tags based on a condition array argument.
|
||||
*
|
||||
* @param array|string $input The original form-tags collection.
|
||||
* If it is a string, scans form-tags from it.
|
||||
* @param array $cond The conditions that filtering will be based on.
|
||||
* @return array The filtered form-tags collection.
|
||||
*/
|
||||
public function filter( $input, $cond ) {
|
||||
if ( is_array( $input ) ) {
|
||||
$tags = $input;
|
||||
} elseif ( is_string( $input ) ) {
|
||||
$tags = $this->scan( $input );
|
||||
} else {
|
||||
$tags = $this->scanned_tags;
|
||||
}
|
||||
|
||||
$cond = wp_parse_args( $cond, array(
|
||||
'type' => array(),
|
||||
'basetype' => array(),
|
||||
'name' => array(),
|
||||
'feature' => array(),
|
||||
) );
|
||||
|
||||
$cond = array_map( static function ( $c ) {
|
||||
return array_filter( array_map( 'trim', (array) $c ) );
|
||||
}, $cond );
|
||||
|
||||
$tags = array_filter(
|
||||
(array) $tags,
|
||||
function ( $tag ) use ( $cond ) {
|
||||
$tag = new WPCF7_FormTag( $tag );
|
||||
|
||||
if (
|
||||
$cond['type'] and
|
||||
! in_array( $tag->type, $cond['type'], true )
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (
|
||||
$cond['basetype'] and
|
||||
! in_array( $tag->basetype, $cond['basetype'], true )
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (
|
||||
$cond['name'] and
|
||||
! in_array( $tag->name, $cond['name'], true )
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ( $cond['feature'] as $feature ) {
|
||||
if ( str_starts_with( $feature, '!' ) ) { // Negation
|
||||
$feature = trim( substr( $feature, 1 ) );
|
||||
|
||||
if ( $this->tag_type_supports( $tag->type, $feature ) ) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if ( ! $this->tag_type_supports( $tag->type, $feature ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
);
|
||||
|
||||
return array_values( $tags );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the regular expression for a form-tag.
|
||||
*/
|
||||
private function tag_regex() {
|
||||
$tag_types = implode( '|',
|
||||
array_map( 'preg_quote', array_keys( $this->tag_types ) )
|
||||
);
|
||||
|
||||
$whitespaces = wpcf7_get_unicode_whitespaces();
|
||||
|
||||
return '(\[?)'
|
||||
. '\[(' . $tag_types . ')'
|
||||
. '(?:[' . $whitespaces . ']+(.*?))?'
|
||||
. '(?:[' . $whitespaces . ']+(\/))?\]'
|
||||
. '(?:([^[]*?)\[\/\2\])?'
|
||||
. '(\]?)';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The callback function for the form-tag replacement.
|
||||
*/
|
||||
private function replace_callback( $matches ) {
|
||||
return $this->scan_callback( $matches, true );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The callback function for the form-tag scanning.
|
||||
*/
|
||||
private function scan_callback( $matches, $replace = false ) {
|
||||
// allow [[foo]] syntax for escaping a tag
|
||||
if ( '[' === $matches[1] and ']' === $matches[6] ) {
|
||||
return substr( $matches[0], 1, -1 );
|
||||
}
|
||||
|
||||
$tag_type = $matches[2];
|
||||
$tag_basetype = trim( $tag_type, '*' );
|
||||
$attr = $this->parse_atts( $matches[3] );
|
||||
|
||||
$scanned_tag = array(
|
||||
'type' => $tag_type,
|
||||
'basetype' => $tag_basetype,
|
||||
'raw_name' => '',
|
||||
'name' => '',
|
||||
'options' => array(),
|
||||
'raw_values' => array(),
|
||||
'values' => array(),
|
||||
'pipes' => null,
|
||||
'labels' => array(),
|
||||
'attr' => '',
|
||||
'content' => '',
|
||||
);
|
||||
|
||||
if ( $this->tag_type_supports( $tag_type, 'singular' ) ) {
|
||||
$tags_in_same_basetype = $this->filter(
|
||||
$this->scanned_tags,
|
||||
array( 'basetype' => $tag_basetype )
|
||||
);
|
||||
|
||||
if ( $tags_in_same_basetype ) {
|
||||
// Another tag in the same base type already exists. Ignore this one.
|
||||
return $matches[0];
|
||||
}
|
||||
}
|
||||
|
||||
if ( $this->tag_type_supports( $tag_type, 'name-attr' ) ) {
|
||||
if ( ! is_array( $attr ) ) {
|
||||
return $matches[0]; // Invalid form-tag.
|
||||
}
|
||||
|
||||
$scanned_tag['raw_name'] = (string) array_shift( $attr['options'] );
|
||||
|
||||
if ( ! wpcf7_is_name( $scanned_tag['raw_name'] ) ) {
|
||||
return $matches[0]; // Invalid name is used. Ignore this tag.
|
||||
}
|
||||
|
||||
$scanned_tag['name'] = strtr( $scanned_tag['raw_name'], '.', '_' );
|
||||
}
|
||||
|
||||
if ( is_array( $attr ) ) {
|
||||
$scanned_tag['options'] = (array) $attr['options'];
|
||||
$scanned_tag['raw_values'] = (array) $attr['values'];
|
||||
|
||||
if ( WPCF7_USE_PIPE ) {
|
||||
$pipes = new WPCF7_Pipes( $scanned_tag['raw_values'] );
|
||||
$scanned_tag['values'] = $pipes->collect_befores();
|
||||
$scanned_tag['pipes'] = $pipes;
|
||||
} else {
|
||||
$scanned_tag['values'] = $scanned_tag['raw_values'];
|
||||
}
|
||||
|
||||
$scanned_tag['labels'] = $scanned_tag['values'];
|
||||
|
||||
} else {
|
||||
$scanned_tag['attr'] = $attr;
|
||||
}
|
||||
|
||||
$scanned_tag['values'] = array_map( 'trim', $scanned_tag['values'] );
|
||||
$scanned_tag['labels'] = array_map( 'trim', $scanned_tag['labels'] );
|
||||
|
||||
$content = trim( $matches[5] );
|
||||
$content = preg_replace( "/<br[\r\n\t ]*\/?>$/m", '', $content );
|
||||
$scanned_tag['content'] = $content;
|
||||
|
||||
$scanned_tag = apply_filters( 'wpcf7_form_tag', $scanned_tag, $replace );
|
||||
|
||||
$scanned_tag = new WPCF7_FormTag( $scanned_tag );
|
||||
|
||||
$this->scanned_tags[] = $scanned_tag;
|
||||
|
||||
if ( $replace ) {
|
||||
$callback = $this->tag_types[$tag_type]['function'];
|
||||
return $matches[1] . call_user_func( $callback, $scanned_tag ) . $matches[6];
|
||||
} else {
|
||||
return $matches[0];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parses the attributes of a form-tag to extract the name,
|
||||
* options, and values.
|
||||
*
|
||||
* @param string $text Attributes of a form-tag.
|
||||
* @return array|string An associative array of the options and values
|
||||
* if the input is in the correct syntax,
|
||||
* otherwise the input text itself.
|
||||
*/
|
||||
private function parse_atts( $text ) {
|
||||
$atts = array(
|
||||
'options' => array(),
|
||||
'values' => array(),
|
||||
);
|
||||
|
||||
$whitespaces = wpcf7_get_unicode_whitespaces();
|
||||
|
||||
$text = preg_replace( '/[\x{00a0}\x{200b}]+/u', ' ', $text );
|
||||
$text = wpcf7_strip_whitespaces( $text );
|
||||
|
||||
$pattern = '%^([-+*=0-9a-zA-Z:.!?#$&@_/|\%' . $whitespaces . ']*?)'
|
||||
. '((?:'
|
||||
. '[' . $whitespaces . ']*"[^"]*"'
|
||||
. '|'
|
||||
. '[' . $whitespaces . ']*\'[^\']*\''
|
||||
. ')*)$%u';
|
||||
|
||||
if ( preg_match( $pattern, $text, $matches ) ) {
|
||||
if ( ! empty( $matches[1] ) ) {
|
||||
$atts['options'] = preg_split(
|
||||
sprintf( '/[%s]+/u', $whitespaces ),
|
||||
wpcf7_strip_whitespaces( $matches[1] )
|
||||
);
|
||||
}
|
||||
|
||||
if ( ! empty( $matches[2] ) ) {
|
||||
preg_match_all( '/"[^"]*"|\'[^\']*\'/', $matches[2], $matched_values );
|
||||
$atts['values'] = wpcf7_strip_quote_deep( $matched_values[0] );
|
||||
}
|
||||
} else {
|
||||
$atts = $text;
|
||||
}
|
||||
|
||||
return $atts;
|
||||
}
|
||||
|
||||
}
|
||||
653
wp-content/plugins/contact-form-7/includes/formatting.php
Normal file
@ -0,0 +1,653 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Replaces double line breaks with paragraph elements.
|
||||
*
|
||||
* @param string $input The text which has to be formatted.
|
||||
* @param bool $br Optional. If set, this will convert all remaining
|
||||
* line breaks after paragraphing. Default true.
|
||||
* @return string Text which has been converted into correct paragraph tags.
|
||||
*/
|
||||
function wpcf7_autop( $input, $br = true ) {
|
||||
$placeholders = array();
|
||||
|
||||
// Replace non-HTML embedded elements with placeholders.
|
||||
$input = preg_replace_callback(
|
||||
'/<(math|svg).*?<\/\1>/is',
|
||||
static function ( $matches ) use ( &$placeholders ) {
|
||||
$placeholder = sprintf(
|
||||
'<%1$s id="%2$s" />',
|
||||
WPCF7_HTMLFormatter::placeholder_inline,
|
||||
hash( 'sha256', $matches[0] )
|
||||
);
|
||||
|
||||
list( $placeholder ) =
|
||||
WPCF7_HTMLFormatter::normalize_start_tag( $placeholder );
|
||||
|
||||
$placeholders[$placeholder] = $matches[0];
|
||||
|
||||
return $placeholder;
|
||||
},
|
||||
$input
|
||||
);
|
||||
|
||||
$formatter = new WPCF7_HTMLFormatter( array(
|
||||
'auto_br' => $br,
|
||||
'allowed_html' => null,
|
||||
) );
|
||||
|
||||
$chunks = $formatter->separate_into_chunks( $input );
|
||||
|
||||
$output = $formatter->format( $chunks );
|
||||
|
||||
// Restore from placeholders.
|
||||
$output = str_replace(
|
||||
array_keys( $placeholders ),
|
||||
array_values( $placeholders ),
|
||||
$output
|
||||
);
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Newline preservation help function for wpcf7_autop().
|
||||
*
|
||||
* @deprecated 5.7 Unnecessary to use any more.
|
||||
*
|
||||
* @param array $matches preg_replace_callback() matches array.
|
||||
* @return string Text including newline placeholders.
|
||||
*/
|
||||
function wpcf7_autop_preserve_newline_callback( $matches ) {
|
||||
return str_replace( "\n", '<WPPreserveNewline />', $matches[0] );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sanitizes the query variables.
|
||||
*
|
||||
* @param string $text Query variable.
|
||||
* @return string Text sanitized.
|
||||
*/
|
||||
function wpcf7_sanitize_query_var( $text ) {
|
||||
$text = wp_unslash( $text );
|
||||
$text = wp_check_invalid_utf8( $text );
|
||||
|
||||
if ( false !== strpos( $text, '<' ) ) {
|
||||
$text = wp_pre_kses_less_than( $text );
|
||||
$text = wp_strip_all_tags( $text );
|
||||
}
|
||||
|
||||
$text = preg_replace( '/%[a-f0-9]{2}/i', '', $text );
|
||||
$text = preg_replace( '/ +/', ' ', $text );
|
||||
$text = trim( $text, ' ' );
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Strips quote characters surrounding the input.
|
||||
*
|
||||
* @param string $text Input text.
|
||||
* @return string Processed output.
|
||||
*/
|
||||
function wpcf7_strip_quote( $text ) {
|
||||
$text = wpcf7_strip_whitespaces( $text );
|
||||
|
||||
if ( preg_match( '/^"(.*)"$/s', $text, $matches ) ) {
|
||||
$text = $matches[1];
|
||||
} elseif ( preg_match( "/^'(.*)'$/s", $text, $matches ) ) {
|
||||
$text = $matches[1];
|
||||
}
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Navigates through an array, object, or scalar, and
|
||||
* strips quote characters surrounding the each value.
|
||||
*
|
||||
* @param mixed $input The array or string to be processed.
|
||||
* @return mixed Processed value.
|
||||
*/
|
||||
function wpcf7_strip_quote_deep( $input ) {
|
||||
if ( is_string( $input ) ) {
|
||||
return wpcf7_strip_quote( $input );
|
||||
}
|
||||
|
||||
if ( is_array( $input ) ) {
|
||||
$result = array();
|
||||
|
||||
foreach ( $input as $key => $text ) {
|
||||
$result[$key] = wpcf7_strip_quote_deep( $text );
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Normalizes newline characters.
|
||||
*
|
||||
* @param string $text Input text.
|
||||
* @param string $to Optional. The newline character that is used in the output.
|
||||
* @return string Normalized text.
|
||||
*/
|
||||
function wpcf7_normalize_newline( $text, $to = "\n" ) {
|
||||
if ( ! is_string( $text ) ) {
|
||||
return $text;
|
||||
}
|
||||
|
||||
$nls = array( "\r\n", "\r", "\n" );
|
||||
|
||||
if ( ! in_array( $to, $nls, true ) ) {
|
||||
return $text;
|
||||
}
|
||||
|
||||
return str_replace( $nls, $to, $text );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Navigates through an array, object, or scalar, and
|
||||
* normalizes newline characters in the each value.
|
||||
*
|
||||
* @param mixed $input The array or string to be processed.
|
||||
* @param string $to Optional. The newline character that is used in the output.
|
||||
* @return mixed Processed value.
|
||||
*/
|
||||
function wpcf7_normalize_newline_deep( $input, $to = "\n" ) {
|
||||
if ( is_array( $input ) ) {
|
||||
$result = array();
|
||||
|
||||
foreach ( $input as $key => $text ) {
|
||||
$result[$key] = wpcf7_normalize_newline_deep( $text, $to );
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
return wpcf7_normalize_newline( $input, $to );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Strips newline characters.
|
||||
*
|
||||
* @param string $text Input text.
|
||||
* @return string Processed one-line text.
|
||||
*/
|
||||
function wpcf7_strip_newline( $text ) {
|
||||
$text = (string) $text;
|
||||
$text = str_replace( array( "\r", "\n" ), '', $text );
|
||||
return wpcf7_strip_whitespaces( $text );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Canonicalizes text.
|
||||
*
|
||||
* @param string $text Input text.
|
||||
* @param string|array|object $options Options.
|
||||
* @return string Canonicalized text.
|
||||
*/
|
||||
function wpcf7_canonicalize( $text, $options = '' ) {
|
||||
// for back-compat
|
||||
if (
|
||||
is_string( $options ) and
|
||||
'' !== $options and
|
||||
! str_contains( $options, '=' )
|
||||
) {
|
||||
$options = array(
|
||||
'strto' => $options,
|
||||
);
|
||||
}
|
||||
|
||||
$options = wp_parse_args( $options, array(
|
||||
'strto' => 'lower',
|
||||
'strip_separators' => false,
|
||||
) );
|
||||
|
||||
static $charset = null;
|
||||
|
||||
if ( ! isset( $charset ) ) {
|
||||
$charset = get_option( 'blog_charset' );
|
||||
|
||||
$is_utf8 = in_array(
|
||||
$charset,
|
||||
array( 'utf8', 'utf-8', 'UTF8', 'UTF-8' ),
|
||||
true
|
||||
);
|
||||
|
||||
if ( $is_utf8 ) {
|
||||
$charset = 'UTF-8';
|
||||
}
|
||||
}
|
||||
|
||||
$text = html_entity_decode( $text, ENT_QUOTES | ENT_HTML5, $charset );
|
||||
|
||||
if ( function_exists( 'mb_convert_kana' ) ) {
|
||||
$text = mb_convert_kana( $text, 'asKV', $charset );
|
||||
}
|
||||
|
||||
if ( $options['strip_separators'] ) {
|
||||
$text = preg_replace( '/[\r\n\t ]+/', '', $text );
|
||||
} else {
|
||||
$text = preg_replace( '/[\r\n\t ]+/', ' ', $text );
|
||||
}
|
||||
|
||||
if ( 'lower' === $options['strto'] ) {
|
||||
if ( function_exists( 'mb_strtolower' ) ) {
|
||||
$text = mb_strtolower( $text, $charset );
|
||||
} else {
|
||||
$text = strtolower( $text );
|
||||
}
|
||||
} elseif ( 'upper' === $options['strto'] ) {
|
||||
if ( function_exists( 'mb_strtoupper' ) ) {
|
||||
$text = mb_strtoupper( $text, $charset );
|
||||
} else {
|
||||
$text = strtoupper( $text );
|
||||
}
|
||||
}
|
||||
|
||||
return wpcf7_strip_whitespaces( $text );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a canonical keyword usable for a name or an ID purposes.
|
||||
*/
|
||||
function wpcf7_canonicalize_name( $text ) {
|
||||
return preg_replace( '/[^0-9a-z]+/i', '-', $text );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sanitizes Contact Form 7's form unit-tag.
|
||||
*
|
||||
* @param string $tag Unit-tag.
|
||||
* @return string Sanitized unit-tag.
|
||||
*/
|
||||
function wpcf7_sanitize_unit_tag( $tag ) {
|
||||
$tag = preg_replace( '/[^A-Za-z0-9_-]/', '', (string) $tag );
|
||||
return $tag;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Converts a file name to one that is not executable as a script.
|
||||
*
|
||||
* @param string $filename File name.
|
||||
* @return string Converted file name.
|
||||
*/
|
||||
function wpcf7_antiscript_file_name( $filename ) {
|
||||
$filename = wp_basename( $filename );
|
||||
|
||||
// Apply part of protection logic from sanitize_file_name().
|
||||
$filename = str_replace(
|
||||
array(
|
||||
'?', '[', ']', '/', '\\', '=', '<', '>', ':', ';', ',', "'", '"',
|
||||
'&', '$', '#', '*', '(', ')', '|', '~', '`', '!', '{', '}',
|
||||
'%', '+', '’', '«', '»', '”', '“', chr( 0 )
|
||||
),
|
||||
'',
|
||||
$filename
|
||||
);
|
||||
|
||||
$filename = preg_replace( '/[\r\n\t -]+/', '-', $filename );
|
||||
$filename = preg_replace( '/[\pC\pZ]+/iu', '', $filename );
|
||||
|
||||
$parts = explode( '.', $filename );
|
||||
|
||||
if ( count( $parts ) < 2 ) {
|
||||
return $filename;
|
||||
}
|
||||
|
||||
$script_pattern = '/^(php|phtml|pl|py|rb|cgi|asp|aspx)\d?$/i';
|
||||
|
||||
$filename = array_shift( $parts );
|
||||
$extension = array_pop( $parts );
|
||||
|
||||
foreach ( $parts as $part ) {
|
||||
if ( preg_match( $script_pattern, $part ) ) {
|
||||
$filename .= '.' . $part . '_';
|
||||
} else {
|
||||
$filename .= '.' . $part;
|
||||
}
|
||||
}
|
||||
|
||||
if ( preg_match( $script_pattern, $extension ) ) {
|
||||
$filename .= '.' . $extension . '_.txt';
|
||||
} else {
|
||||
$filename .= '.' . $extension;
|
||||
}
|
||||
|
||||
return $filename;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Masks a password with asterisks (*).
|
||||
*
|
||||
* @param int $right Length of right-hand unmasked text. Default 0.
|
||||
* @param int $left Length of left-hand unmasked text. Default 0.
|
||||
* @return string Text of masked password.
|
||||
*/
|
||||
function wpcf7_mask_password( $text, $right = 0, $left = 0 ) {
|
||||
$length = strlen( $text );
|
||||
|
||||
$right = absint( $right );
|
||||
$left = absint( $left );
|
||||
|
||||
if ( $length < $right + $left ) {
|
||||
$right = $left = 0;
|
||||
}
|
||||
|
||||
if ( $length <= 48 ) {
|
||||
$masked = str_repeat( '*', $length - ( $right + $left ) );
|
||||
} elseif ( $right + $left < 48 ) {
|
||||
$masked = str_repeat( '*', 48 - ( $right + $left ) );
|
||||
} else {
|
||||
$masked = '****';
|
||||
}
|
||||
|
||||
$left_unmasked = $left ? substr( $text, 0, $left ) : '';
|
||||
$right_unmasked = $right ? substr( $text, -1 * $right ) : '';
|
||||
|
||||
$text = $left_unmasked . $masked . $right_unmasked;
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array of allowed HTML tags and attributes for a given context.
|
||||
*
|
||||
* @param string $context Context used to decide allowed tags and attributes.
|
||||
* @return array Array of allowed HTML tags and their allowed attributes.
|
||||
*/
|
||||
function wpcf7_kses_allowed_html( $context = 'form' ) {
|
||||
static $allowed_tags = array();
|
||||
|
||||
if ( isset( $allowed_tags[$context] ) ) {
|
||||
return apply_filters(
|
||||
'wpcf7_kses_allowed_html',
|
||||
$allowed_tags[$context],
|
||||
$context
|
||||
);
|
||||
}
|
||||
|
||||
$allowed_tags[$context] = wp_kses_allowed_html( 'post' );
|
||||
|
||||
if ( 'form' === $context ) {
|
||||
$additional_tags_for_form = array(
|
||||
'button' => array(
|
||||
'disabled' => true,
|
||||
'name' => true,
|
||||
'type' => true,
|
||||
'value' => true,
|
||||
),
|
||||
'datalist' => array(),
|
||||
'fieldset' => array(
|
||||
'disabled' => true,
|
||||
'name' => true,
|
||||
),
|
||||
'input' => array(
|
||||
'accept' => true,
|
||||
'alt' => true,
|
||||
'autocomplete' => true,
|
||||
'capture' => true,
|
||||
'checked' => true,
|
||||
'disabled' => true,
|
||||
'list' => true,
|
||||
'max' => true,
|
||||
'maxlength' => true,
|
||||
'min' => true,
|
||||
'minlength' => true,
|
||||
'multiple' => true,
|
||||
'name' => true,
|
||||
'pattern' => true,
|
||||
'placeholder' => true,
|
||||
'readonly' => true,
|
||||
'required' => true,
|
||||
'size' => true,
|
||||
'step' => true,
|
||||
'type' => true,
|
||||
'value' => true,
|
||||
),
|
||||
'label' => array(
|
||||
'for' => true,
|
||||
),
|
||||
'legend' => array(),
|
||||
'meter' => array(
|
||||
'value' => true,
|
||||
'min' => true,
|
||||
'max' => true,
|
||||
'low' => true,
|
||||
'high' => true,
|
||||
'optimum' => true,
|
||||
),
|
||||
'optgroup' => array(
|
||||
'disabled' => true,
|
||||
'label' => true,
|
||||
),
|
||||
'option' => array(
|
||||
'disabled' => true,
|
||||
'label' => true,
|
||||
'selected' => true,
|
||||
'value' => true,
|
||||
),
|
||||
'output' => array(
|
||||
'for' => true,
|
||||
'name' => true,
|
||||
),
|
||||
'progress' => array(
|
||||
'max' => true,
|
||||
'value' => true,
|
||||
),
|
||||
'select' => array(
|
||||
'autocomplete' => true,
|
||||
'disabled' => true,
|
||||
'multiple' => true,
|
||||
'name' => true,
|
||||
'required' => true,
|
||||
'size' => true,
|
||||
),
|
||||
'textarea' => array(
|
||||
'autocomplete' => true,
|
||||
'cols' => true,
|
||||
'disabled' => true,
|
||||
'maxlength' => true,
|
||||
'minlength' => true,
|
||||
'name' => true,
|
||||
'placeholder' => true,
|
||||
'readonly' => true,
|
||||
'required' => true,
|
||||
'rows' => true,
|
||||
'wrap' => true,
|
||||
),
|
||||
);
|
||||
|
||||
$allowed_tags[$context] = array_merge(
|
||||
$allowed_tags[$context],
|
||||
$additional_tags_for_form
|
||||
);
|
||||
|
||||
$allowed_tags[$context] = array_map(
|
||||
static function ( $elm ) {
|
||||
$global_attributes = array(
|
||||
'aria-atomic' => true,
|
||||
'aria-checked' => true,
|
||||
'aria-controls' => true,
|
||||
'aria-current' => true,
|
||||
'aria-describedby' => true,
|
||||
'aria-details' => true,
|
||||
'aria-disabled' => true,
|
||||
'aria-expanded' => true,
|
||||
'aria-hidden' => true,
|
||||
'aria-invalid' => true,
|
||||
'aria-label' => true,
|
||||
'aria-labelledby' => true,
|
||||
'aria-live' => true,
|
||||
'aria-relevant' => true,
|
||||
'aria-required' => true,
|
||||
'aria-selected' => true,
|
||||
'class' => true,
|
||||
'data-*' => true,
|
||||
'dir' => true,
|
||||
'hidden' => true,
|
||||
'id' => true,
|
||||
'inputmode' => true,
|
||||
'lang' => true,
|
||||
'role' => true,
|
||||
'spellcheck' => true,
|
||||
'style' => true,
|
||||
'tabindex' => true,
|
||||
'title' => true,
|
||||
'xml:lang' => true,
|
||||
);
|
||||
|
||||
return array_merge( $global_attributes, (array) $elm );
|
||||
},
|
||||
$allowed_tags[$context]
|
||||
);
|
||||
}
|
||||
|
||||
return apply_filters(
|
||||
'wpcf7_kses_allowed_html',
|
||||
$allowed_tags[$context],
|
||||
$context
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sanitizes content for allowed HTML tags for the specified context.
|
||||
*
|
||||
* @param string $input Content to filter.
|
||||
* @param string $context Context used to decide allowed tags and attributes.
|
||||
* @return string Filtered text with allowed HTML tags and attributes intact.
|
||||
*/
|
||||
function wpcf7_kses( $input, $context = 'form' ) {
|
||||
$output = wp_kses(
|
||||
$input,
|
||||
wpcf7_kses_allowed_html( $context )
|
||||
);
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a formatted string of HTML attributes.
|
||||
*
|
||||
* @param array $atts Associative array of attribute name and value pairs.
|
||||
* @return string Formatted HTML attributes.
|
||||
*/
|
||||
function wpcf7_format_atts( $atts ) {
|
||||
$atts_filtered = array();
|
||||
|
||||
foreach ( $atts as $name => $value ) {
|
||||
$name = strtolower( trim( $name ) );
|
||||
|
||||
if ( ! preg_match( '/^[a-z_:][a-z_:.0-9-]*$/', $name ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
static $boolean_attributes = array(
|
||||
'checked',
|
||||
'disabled',
|
||||
'inert',
|
||||
'multiple',
|
||||
'readonly',
|
||||
'required',
|
||||
'selected',
|
||||
);
|
||||
|
||||
if ( in_array( $name, $boolean_attributes, true ) and '' === $value ) {
|
||||
$value = false;
|
||||
}
|
||||
|
||||
if ( is_numeric( $value ) ) {
|
||||
$value = (string) $value;
|
||||
}
|
||||
|
||||
if ( null === $value or false === $value ) {
|
||||
unset( $atts_filtered[$name] );
|
||||
} elseif ( true === $value ) {
|
||||
$atts_filtered[$name] = $name; // boolean attribute
|
||||
} elseif ( is_string( $value ) ) {
|
||||
$atts_filtered[$name] = trim( $value );
|
||||
}
|
||||
}
|
||||
|
||||
$output = '';
|
||||
|
||||
foreach ( $atts_filtered as $name => $value ) {
|
||||
$output .= sprintf( ' %1$s="%2$s"', $name, esc_attr( $value ) );
|
||||
}
|
||||
|
||||
return trim( $output );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the regular expression pattern that represents
|
||||
* whitespace characters Unicode defines.
|
||||
*
|
||||
* @link https://www.unicode.org/Public/UCD/latest/ucd/PropList.txt
|
||||
*
|
||||
* @return string Regular expression pattern.
|
||||
*/
|
||||
function wpcf7_get_unicode_whitespaces() {
|
||||
return '\x09-\x0D\x20\x85\xA0\x{1680}\x{2000}-\x{200A}\x{2028}\x{2029}\x{202F}\x{205F}\x{3000}';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Strips surrounding whitespaces.
|
||||
*
|
||||
* @link https://contactform7.com/2024/07/13/consistent-handling-policy-of-surrounding-whitespaces/
|
||||
*
|
||||
* @param string|array $input Input text.
|
||||
* @param string $side The side from which whitespaces are stripped.
|
||||
* 'start', 'end', or 'both' (default).
|
||||
* @return string|array Output text.
|
||||
*/
|
||||
function wpcf7_strip_whitespaces( $input, $side = 'both' ) {
|
||||
if ( is_array( $input ) ) {
|
||||
return array_map(
|
||||
static function ( $i ) use ( $side ) {
|
||||
return wpcf7_strip_whitespaces( $i, $side );
|
||||
},
|
||||
$input
|
||||
);
|
||||
}
|
||||
|
||||
// https://tc39.es/ecma262/multipage/ecmascript-language-lexical-grammar.html
|
||||
$whitespaces = wpcf7_get_unicode_whitespaces() . '\x{FEFF}';
|
||||
|
||||
if ( 'end' !== $side ) {
|
||||
// Strip leading whitespaces
|
||||
$input = preg_replace(
|
||||
sprintf( '/^[%s]+/u', $whitespaces ),
|
||||
'',
|
||||
$input
|
||||
);
|
||||
}
|
||||
|
||||
if ( 'start' !== $side ) {
|
||||
// Strip trailing whitespaces
|
||||
$input = preg_replace(
|
||||
sprintf( '/[%s]+$/u', $whitespaces ),
|
||||
'',
|
||||
$input
|
||||
);
|
||||
}
|
||||
|
||||
return $input;
|
||||
}
|
||||
749
wp-content/plugins/contact-form-7/includes/functions.php
Normal file
@ -0,0 +1,749 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* 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 $options Optional. Output options.
|
||||
* @return string Comma-separated list.
|
||||
*/
|
||||
function wpcf7_flat_join( $input, $options = '' ) {
|
||||
$options = wp_parse_args( $options, array(
|
||||
'separator' => ', ',
|
||||
) );
|
||||
|
||||
$input = wpcf7_array_flatten( $input );
|
||||
$output = array();
|
||||
|
||||
foreach ( $input as $value ) {
|
||||
if ( is_scalar( $value ) ) {
|
||||
$output[] = trim( (string) $value );
|
||||
}
|
||||
}
|
||||
|
||||
return implode( $options['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 $atts Optional. HTML attributes.
|
||||
* @return string Formatted anchor element.
|
||||
*/
|
||||
function wpcf7_link( $url, $anchor_text, $atts = '' ) {
|
||||
$atts = wp_parse_args( $atts, array(
|
||||
'id' => null,
|
||||
'class' => null,
|
||||
) );
|
||||
|
||||
$atts = array_merge( $atts, array(
|
||||
'href' => esc_url( $url ),
|
||||
) );
|
||||
|
||||
return sprintf(
|
||||
'<a %1$s>%2$s</a>',
|
||||
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() );
|
||||
$request_uri = '/' . ltrim( $request_uri, '/' );
|
||||
}
|
||||
|
||||
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 $options Optional. Output options.
|
||||
* @return string Version string.
|
||||
*/
|
||||
function wpcf7_version( $options = '' ) {
|
||||
$options = wp_parse_args( $options, array(
|
||||
'limit' => -1,
|
||||
'only_major' => false,
|
||||
) );
|
||||
|
||||
if ( $options['only_major'] ) {
|
||||
$options['limit'] = 2;
|
||||
}
|
||||
|
||||
$options['limit'] = (int) $options['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 < $options['limit'] ) {
|
||||
$ver = array_slice( $ver, 0, $options['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, true ) ) {
|
||||
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 ) {
|
||||
$filesystem = WPCF7_Filesystem::get_instance();
|
||||
|
||||
return $filesystem->delete( $dir, true );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Builds a URL-encoded query string.
|
||||
*
|
||||
* @link https://developer.wordpress.org/reference/functions/_http_build_query/
|
||||
*
|
||||
* @param array $data URL query parameters.
|
||||
* @param string $key Optional. If specified, used to prefix key name.
|
||||
* @return string Query string.
|
||||
*/
|
||||
function wpcf7_build_query( $data, $key = '' ) {
|
||||
$sep = '&';
|
||||
$ret = array();
|
||||
|
||||
foreach ( (array) $data 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|false 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;
|
||||
|
||||
if ( '' === $text ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$text = str_replace( "\r\n", "\n", $text );
|
||||
|
||||
$text = mb_convert_encoding(
|
||||
$text,
|
||||
'UTF-16',
|
||||
mb_detect_encoding( $text, mb_detect_order(), true ) ?: 'UTF-8'
|
||||
);
|
||||
|
||||
return intdiv( mb_strlen( $text, '8bit' ), 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' ),
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( function_exists( '__' ) ) {
|
||||
/* translators: 1: PHP function name, 2: version number, 3: alternative function name */
|
||||
$message = __( 'Function %1$s is <strong>deprecated</strong> since Contact Form 7 version %2$s! Use %3$s instead.', 'contact-form-7' );
|
||||
} else {
|
||||
$message = 'Function %1$s is <strong>deprecated</strong> since Contact Form 7 version %2$s! Use %3$s instead.';
|
||||
}
|
||||
|
||||
$message = sprintf( $message, $function_name, $version, $replacement );
|
||||
|
||||
wp_trigger_error( '', $message, 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 ) {
|
||||
wp_trigger_error(
|
||||
'',
|
||||
sprintf(
|
||||
/* translators: 1: WordPress hook name, 2: version number, 3: alternative hook name */
|
||||
__( 'Hook %1$s is <strong>deprecated</strong> since Contact Form 7 version %2$s! Use %3$s instead.', 'contact-form-7' ),
|
||||
$hook_name,
|
||||
$version,
|
||||
$replacement
|
||||
),
|
||||
E_USER_DEPRECATED
|
||||
);
|
||||
} else {
|
||||
wp_trigger_error(
|
||||
'',
|
||||
sprintf(
|
||||
/* translators: 1: WordPress hook name, 2: version number */
|
||||
__( 'Hook %1$s is <strong>deprecated</strong> 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 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
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
|
||||
);
|
||||
}
|
||||
|
||||
wp_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
|
||||
);
|
||||
}
|
||||
|
||||
wp_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 ) {
|
||||
|
||||
if ( ! WP_DEBUG ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$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 ) {
|
||||
wp_trigger_error( '', $log, E_USER_NOTICE );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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 ) );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves a sanitized value from the $_GET superglobal.
|
||||
*
|
||||
* @param string $key Array key.
|
||||
* @param mixed $default The default value returned when
|
||||
* the specified superglobal is not set.
|
||||
* @return mixed Sanitized value.
|
||||
*/
|
||||
function wpcf7_superglobal_get( $key, $default = '' ) {
|
||||
return wpcf7_superglobal( 'get', $key ) ?? $default;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves a sanitized value from the $_POST superglobal.
|
||||
*
|
||||
* @param string $key Array key.
|
||||
* @param mixed $default The default value returned when
|
||||
* the specified superglobal is not set.
|
||||
* @return mixed Sanitized value.
|
||||
*/
|
||||
function wpcf7_superglobal_post( $key, $default = '' ) {
|
||||
return wpcf7_superglobal( 'post', $key ) ?? $default;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves a sanitized value from the $_REQUEST superglobal.
|
||||
*
|
||||
* @param string $key Array key.
|
||||
* @param mixed $default The default value returned when
|
||||
* the specified superglobal is not set.
|
||||
* @return mixed Sanitized value.
|
||||
*/
|
||||
function wpcf7_superglobal_request( $key, $default = '' ) {
|
||||
return wpcf7_superglobal( 'request', $key ) ?? $default;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves a sanitized value from the $_SERVER superglobal.
|
||||
*
|
||||
* @param string $key Array key.
|
||||
* @param mixed $default The default value returned when
|
||||
* the specified superglobal is not set.
|
||||
* @return mixed Sanitized value.
|
||||
*/
|
||||
function wpcf7_superglobal_server( $key, $default = '' ) {
|
||||
return wpcf7_superglobal( 'server', $key ) ?? $default;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves a sanitized value from the specified superglobal.
|
||||
*
|
||||
* @param string $superglobal A superglobal type.
|
||||
* @param string $key Array key.
|
||||
* @return string|array|null Sanitized value.
|
||||
*/
|
||||
function wpcf7_superglobal( $superglobal, $key ) {
|
||||
$superglobals = array(
|
||||
'get' => $_GET,
|
||||
'post' => $_POST,
|
||||
'request' => $_REQUEST,
|
||||
'server' => $_SERVER,
|
||||
);
|
||||
|
||||
if ( isset( $superglobals[$superglobal][$key] ) ) {
|
||||
return map_deep(
|
||||
$superglobals[$superglobal][$key],
|
||||
static function ( $val ) {
|
||||
$val = wp_unslash( $val );
|
||||
$val = wp_check_invalid_utf8( $val );
|
||||
$val = wp_kses_no_null( $val );
|
||||
$val = wpcf7_strip_whitespaces( $val );
|
||||
return $val;
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
868
wp-content/plugins/contact-form-7/includes/html-formatter.php
Normal file
@ -0,0 +1,868 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Contact Form 7's class used for formatting HTML fragments.
|
||||
*/
|
||||
class WPCF7_HTMLFormatter {
|
||||
|
||||
// HTML component types.
|
||||
const text = 0;
|
||||
const start_tag = 1;
|
||||
const end_tag = 2;
|
||||
const comment = 3;
|
||||
|
||||
/**
|
||||
* Tag name reserved for a custom HTML element used as a block placeholder.
|
||||
*/
|
||||
const placeholder_block = 'placeholder:block';
|
||||
|
||||
/**
|
||||
* Tag name reserved for a custom HTML element used as an inline placeholder.
|
||||
*/
|
||||
const placeholder_inline = 'placeholder:inline';
|
||||
|
||||
/**
|
||||
* The void elements in HTML.
|
||||
*
|
||||
* @link https://developer.mozilla.org/en-US/docs/Glossary/Void_element
|
||||
*/
|
||||
const void_elements = array(
|
||||
'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input',
|
||||
'keygen', 'link', 'meta', 'param', 'source', 'track', 'wbr',
|
||||
self::placeholder_block, self::placeholder_inline,
|
||||
);
|
||||
|
||||
/**
|
||||
* HTML elements that can be a direct child of the same element.
|
||||
*/
|
||||
const nestable_elements = array(
|
||||
'article', 'aside', 'blockquote', 'div', 'fieldset', 'section', 'span',
|
||||
);
|
||||
|
||||
/**
|
||||
* HTML elements that can contain flow content.
|
||||
*/
|
||||
const p_parent_elements = array(
|
||||
'address', 'article', 'aside', 'blockquote', 'body', 'caption',
|
||||
'dd', 'details', 'dialog', 'div', 'dt', 'fieldset', 'figcaption',
|
||||
'figure', 'footer', 'form', 'header', 'li', 'main', 'nav',
|
||||
'section', 'td', 'th',
|
||||
);
|
||||
|
||||
/**
|
||||
* HTML elements that can be neither the parent nor a child of
|
||||
* a paragraph element.
|
||||
*/
|
||||
const p_nonparent_elements = array(
|
||||
'colgroup', 'dl', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head',
|
||||
'hgroup', 'html', 'legend', 'menu', 'ol', 'pre', 'style', 'summary',
|
||||
'table', 'tbody', 'template', 'tfoot', 'thead', 'title', 'tr', 'ul',
|
||||
);
|
||||
|
||||
/**
|
||||
* HTML elements in the phrasing content category, plus non-phrasing
|
||||
* content elements that can be grandchildren of a paragraph element.
|
||||
*/
|
||||
const p_child_elements = array(
|
||||
'a', 'abbr', 'area', 'audio', 'b', 'bdi', 'bdo', 'br', 'button',
|
||||
'canvas', 'cite', 'code', 'data', 'datalist', 'del', 'dfn',
|
||||
'em', 'embed', 'i', 'iframe', 'img', 'input', 'ins', 'kbd',
|
||||
'keygen', 'label', 'link', 'map', 'mark', 'meta',
|
||||
'meter', 'noscript', 'object', 'output', 'picture', 'progress',
|
||||
'q', 'ruby', 's', 'samp', 'script', 'select', 'slot', 'small',
|
||||
'span', 'strong', 'sub', 'sup', 'textarea',
|
||||
'time', 'u', 'var', 'video', 'wbr',
|
||||
'optgroup', 'option', 'rp', 'rt', // non-phrasing grandchildren
|
||||
self::placeholder_inline,
|
||||
);
|
||||
|
||||
/**
|
||||
* HTML elements that can contain phrasing content.
|
||||
*/
|
||||
const br_parent_elements = array(
|
||||
'a', 'abbr', 'address', 'article', 'aside', 'audio', 'b', 'bdi',
|
||||
'bdo', 'blockquote', 'button', 'canvas', 'caption', 'cite', 'code',
|
||||
'data', 'datalist', 'dd', 'del', 'details', 'dfn', 'dialog', 'div',
|
||||
'dt', 'em', 'fieldset', 'figcaption', 'figure', 'footer', 'form',
|
||||
'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'header', 'i', 'ins', 'kbd',
|
||||
'label', 'legend', 'li', 'main', 'map', 'mark', 'meter', 'nav',
|
||||
'noscript', 'object', 'output', 'p', 'progress', 'q', 'rt',
|
||||
'ruby', 's', 'samp', 'section', 'slot', 'small', 'span', 'strong',
|
||||
'sub', 'summary', 'sup', 'td', 'th', 'time', 'u', 'var',
|
||||
'video',
|
||||
);
|
||||
|
||||
|
||||
// Properties.
|
||||
private $options = array();
|
||||
private $stacked_elements = array();
|
||||
private $output = '';
|
||||
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct( $options = '' ) {
|
||||
$this->options = wp_parse_args( $options, array(
|
||||
'auto_br' => true,
|
||||
'auto_indent' => true,
|
||||
'allowed_html' => wpcf7_kses_allowed_html(),
|
||||
) );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Separates the given text into chunks of HTML. Each chunk must be an
|
||||
* associative array that includes 'position', 'type', and 'content' keys.
|
||||
*
|
||||
* @param string $input Text to be separated into chunks.
|
||||
* @return iterable Iterable of chunks.
|
||||
*/
|
||||
public function separate_into_chunks( $input ) {
|
||||
$input_bytelength = strlen( $input );
|
||||
$position = 0;
|
||||
|
||||
while ( $position < $input_bytelength ) {
|
||||
$next_tag = preg_match(
|
||||
'/(?:<!--.*?-->|<(?:\/?)[a-z].*?>)/is',
|
||||
$input,
|
||||
$matches,
|
||||
PREG_OFFSET_CAPTURE,
|
||||
$position
|
||||
);
|
||||
|
||||
if ( ! $next_tag ) {
|
||||
yield array(
|
||||
'position' => $position,
|
||||
'type' => self::text,
|
||||
'content' => substr( $input, $position ),
|
||||
);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
$next_tag = $matches[0][0];
|
||||
$next_tag_position = $matches[0][1];
|
||||
|
||||
if ( $position < $next_tag_position ) {
|
||||
yield array(
|
||||
'position' => $position,
|
||||
'type' => self::text,
|
||||
'content' => substr(
|
||||
$input,
|
||||
$position,
|
||||
$next_tag_position - $position
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
if ( '<!' === substr( $next_tag, 0, 2 ) ) {
|
||||
$next_tag_type = self::comment;
|
||||
} elseif ( '</' === substr( $next_tag, 0, 2 ) ) {
|
||||
$next_tag_type = self::end_tag;
|
||||
} else {
|
||||
$next_tag_type = self::start_tag;
|
||||
}
|
||||
|
||||
yield array(
|
||||
'position' => $next_tag_position,
|
||||
'type' => $next_tag_type,
|
||||
'content' => substr(
|
||||
$input,
|
||||
$next_tag_position,
|
||||
strlen( $next_tag )
|
||||
),
|
||||
);
|
||||
|
||||
$position = $next_tag_position + strlen( $next_tag );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Normalizes content in each chunk. This may change the type and position
|
||||
* of the chunk.
|
||||
*
|
||||
* @param iterable $chunks The original chunks.
|
||||
* @return iterable Normalized chunks.
|
||||
*/
|
||||
public function pre_format( $chunks ) {
|
||||
$position = 0;
|
||||
|
||||
foreach ( $chunks as $chunk ) {
|
||||
$chunk['position'] = $position;
|
||||
|
||||
// Standardize newline characters to "\n".
|
||||
$chunk['content'] = str_replace(
|
||||
array( "\r\n", "\r" ), "\n", $chunk['content']
|
||||
);
|
||||
|
||||
if ( self::start_tag === $chunk['type'] ) {
|
||||
list( $chunk['content'] ) =
|
||||
self::normalize_start_tag( $chunk['content'] );
|
||||
|
||||
// Replace <br /> by a line break.
|
||||
if (
|
||||
$this->options['auto_br'] and
|
||||
preg_match( '/^<br\s*\/?>$/i', $chunk['content'] )
|
||||
) {
|
||||
$chunk['type'] = self::text;
|
||||
$chunk['content'] = "\n";
|
||||
}
|
||||
}
|
||||
|
||||
yield $chunk;
|
||||
$position = self::calc_next_position( $chunk );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Concatenates neighboring text chunks to create a single chunk.
|
||||
*
|
||||
* @param iterable $chunks The original chunks.
|
||||
* @return iterable Processed chunks.
|
||||
*/
|
||||
public function concatenate_texts( $chunks ) {
|
||||
$position = 0;
|
||||
$text_left = null;
|
||||
|
||||
foreach ( $chunks as $chunk ) {
|
||||
$chunk['position'] = $position;
|
||||
|
||||
if ( self::text === $chunk['type'] ) {
|
||||
if ( isset( $text_left ) ) {
|
||||
$text_left['content'] .= $chunk['content'];
|
||||
} else {
|
||||
$text_left = $chunk;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( isset( $text_left ) ) {
|
||||
yield $text_left;
|
||||
$chunk['position'] = self::calc_next_position( $text_left );
|
||||
$text_left = null;
|
||||
}
|
||||
|
||||
yield $chunk;
|
||||
$position = self::calc_next_position( $chunk );
|
||||
}
|
||||
|
||||
if ( isset( $text_left ) ) {
|
||||
yield $text_left;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Outputs formatted HTML based on the given chunks.
|
||||
*
|
||||
* @param iterable $chunks The original chunks.
|
||||
* @return string Formatted HTML.
|
||||
*/
|
||||
public function format( $chunks ) {
|
||||
$chunks = $this->pre_format( $chunks );
|
||||
$chunks = $this->concatenate_texts( $chunks );
|
||||
|
||||
$this->output = '';
|
||||
$this->stacked_elements = array();
|
||||
|
||||
foreach ( $chunks as $chunk ) {
|
||||
|
||||
if ( self::text === $chunk['type'] ) {
|
||||
$this->append_text( $chunk['content'] );
|
||||
}
|
||||
|
||||
if ( self::start_tag === $chunk['type'] ) {
|
||||
$this->start_tag( $chunk['content'] );
|
||||
}
|
||||
|
||||
if ( self::end_tag === $chunk['type'] ) {
|
||||
$this->end_tag( $chunk['content'] );
|
||||
}
|
||||
|
||||
if ( self::comment === $chunk['type'] ) {
|
||||
$this->append_comment( $chunk['content'] );
|
||||
}
|
||||
}
|
||||
|
||||
return $this->output();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Appends preformatted text to the output property.
|
||||
*/
|
||||
public function append_preformatted( $content ) {
|
||||
$this->output .= $content;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Appends whitespace to the output property.
|
||||
*/
|
||||
public function append_whitespace() {
|
||||
$this->append_preformatted( ' ' );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Appends a text node content to the output property.
|
||||
*
|
||||
* @param string $content Text node content.
|
||||
*/
|
||||
public function append_text( $content ) {
|
||||
if ( $this->is_inside( array( 'pre', 'template' ) ) ) {
|
||||
$this->append_preformatted( $content );
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
empty( $this->stacked_elements ) or
|
||||
$this->has_parent( 'p' ) or
|
||||
$this->has_parent( self::p_parent_elements )
|
||||
) {
|
||||
// Close <p> if the content starts with multiple line breaks.
|
||||
if ( preg_match( '/^\s*\n\s*\n\s*/', $content ) ) {
|
||||
$this->end_tag( 'p' );
|
||||
}
|
||||
|
||||
// Split up the contents into paragraphs, separated by double line breaks.
|
||||
$paragraphs = preg_split( '/\s*\n\s*\n\s*/', $content );
|
||||
|
||||
$paragraphs = array_filter( $paragraphs, static function ( $paragraph ) {
|
||||
return '' !== wpcf7_strip_whitespaces( $paragraph );
|
||||
} );
|
||||
|
||||
$paragraphs = array_values( $paragraphs );
|
||||
|
||||
if ( $paragraphs ) {
|
||||
if ( $this->is_inside( 'p' ) ) {
|
||||
$paragraph = array_shift( $paragraphs );
|
||||
|
||||
$paragraph = self::normalize_paragraph(
|
||||
$paragraph,
|
||||
$this->options['auto_br']
|
||||
);
|
||||
|
||||
$this->append_preformatted( $paragraph );
|
||||
}
|
||||
|
||||
foreach ( $paragraphs as $paragraph ) {
|
||||
$this->start_tag( 'p' );
|
||||
|
||||
$paragraph = wpcf7_strip_whitespaces( $paragraph, 'start' );
|
||||
|
||||
$paragraph = self::normalize_paragraph(
|
||||
$paragraph,
|
||||
$this->options['auto_br']
|
||||
);
|
||||
|
||||
$this->append_preformatted( $paragraph );
|
||||
}
|
||||
}
|
||||
|
||||
// Close <p> if the content ends with multiple line breaks.
|
||||
if ( preg_match( '/\s*\n\s*\n\s*$/', $content ) ) {
|
||||
$this->end_tag( 'p' );
|
||||
}
|
||||
|
||||
// Cases where the content is a single line break.
|
||||
if ( preg_match( '/^\s*\n\s*$/', $content ) ) {
|
||||
$auto_br = $this->options['auto_br'] && $this->is_inside( 'p' );
|
||||
|
||||
$content = self::normalize_paragraph( $content, $auto_br );
|
||||
|
||||
$this->append_preformatted( $content );
|
||||
}
|
||||
} else {
|
||||
$auto_br = $this->options['auto_br'] &&
|
||||
$this->has_parent( self::br_parent_elements );
|
||||
|
||||
$content = self::normalize_paragraph( $content, $auto_br );
|
||||
|
||||
$this->append_preformatted( $content );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Appends a start tag to the output property.
|
||||
*
|
||||
* @param string $tag A start tag.
|
||||
*/
|
||||
public function start_tag( $tag ) {
|
||||
list( $tag, $tag_name ) = self::normalize_start_tag( $tag );
|
||||
|
||||
if (
|
||||
in_array( $tag_name, self::p_child_elements, true ) and
|
||||
! $this->is_inside( 'p' ) and
|
||||
! $this->is_inside( self::p_child_elements ) and
|
||||
! $this->has_parent( self::p_nonparent_elements )
|
||||
) {
|
||||
// Open <p> if it does not exist.
|
||||
$this->start_tag( 'p' );
|
||||
}
|
||||
|
||||
$this->append_start_tag( $tag_name, array(), $tag );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Appends a start tag to the output property.
|
||||
*
|
||||
* @param string $tag_name Tag name.
|
||||
* @param array $atts Associative array of attribute name and value pairs.
|
||||
* @param string $tag A start tag.
|
||||
*/
|
||||
public function append_start_tag( $tag_name, $atts = array(), $tag = '' ) {
|
||||
if ( ! self::validate_tag_name( $tag_name ) ) {
|
||||
wp_trigger_error(
|
||||
__METHOD__,
|
||||
sprintf(
|
||||
/* translators: %s: Invalid HTML tag name */
|
||||
__( 'Invalid tag name (%s) is specified.', 'contact-form-7' ),
|
||||
$tag_name
|
||||
),
|
||||
E_USER_WARNING
|
||||
);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( WP_DEBUG and ! empty( $this->options['allowed_html'] ) ) {
|
||||
$html_disallowance = array();
|
||||
|
||||
if ( ! isset( $this->options['allowed_html'][$tag_name] ) ) {
|
||||
$html_disallowance = array(
|
||||
'element' => $tag_name,
|
||||
);
|
||||
} else {
|
||||
$atts_allowed = $this->options['allowed_html'][$tag_name];
|
||||
|
||||
$atts_disallowed = array_diff_ukey( $atts, $atts_allowed,
|
||||
static function ( $key_1, $key_2 ) use ( $atts_allowed ) {
|
||||
if (
|
||||
str_starts_with( $key_1, 'data-' ) and
|
||||
! empty( $atts_allowed['data-*'] ) and
|
||||
preg_match( '/^data-[a-z0-9_-]+$/', $key_1 )
|
||||
) {
|
||||
return 0;
|
||||
} else {
|
||||
return $key_1 === $key_2 ? 0 : 1;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
if ( ! empty( $atts_disallowed ) ) {
|
||||
$html_disallowance = array(
|
||||
'element' => $tag_name,
|
||||
'attributes' => array_keys( $atts_disallowed ),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if ( $html_disallowance ) {
|
||||
$notice = sprintf(
|
||||
/* translators: %s: JSON-formatted array of disallowed HTML */
|
||||
__( 'HTML Disallowance: %s', 'contact-form-7' ),
|
||||
wp_json_encode( $html_disallowance, JSON_PRETTY_PRINT )
|
||||
);
|
||||
|
||||
wp_trigger_error( __METHOD__, $notice, E_USER_NOTICE );
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
'p' === $tag_name or
|
||||
in_array( $tag_name, self::p_parent_elements, true ) or
|
||||
in_array( $tag_name, self::p_nonparent_elements, true )
|
||||
) {
|
||||
// Close <p> if it exists.
|
||||
$this->end_tag( 'p' );
|
||||
}
|
||||
|
||||
if ( 'dd' === $tag_name or 'dt' === $tag_name ) {
|
||||
// Close <dd> and <dt> if closing tag is omitted.
|
||||
$this->end_tag( 'dd' );
|
||||
$this->end_tag( 'dt' );
|
||||
}
|
||||
|
||||
if ( 'li' === $tag_name ) {
|
||||
// Close <li> if closing tag is omitted.
|
||||
$this->end_tag( 'li' );
|
||||
}
|
||||
|
||||
if ( 'optgroup' === $tag_name ) {
|
||||
// Close <option> and <optgroup> if closing tag is omitted.
|
||||
$this->end_tag( 'option' );
|
||||
$this->end_tag( 'optgroup' );
|
||||
}
|
||||
|
||||
if ( 'option' === $tag_name ) {
|
||||
// Close <option> if closing tag is omitted.
|
||||
$this->end_tag( 'option' );
|
||||
}
|
||||
|
||||
if ( 'rp' === $tag_name or 'rt' === $tag_name ) {
|
||||
// Close <rp> and <rt> if closing tag is omitted.
|
||||
$this->end_tag( 'rp' );
|
||||
$this->end_tag( 'rt' );
|
||||
}
|
||||
|
||||
if ( 'td' === $tag_name or 'th' === $tag_name ) {
|
||||
// Close <td> and <th> if closing tag is omitted.
|
||||
$this->end_tag( 'td' );
|
||||
$this->end_tag( 'th' );
|
||||
}
|
||||
|
||||
if ( 'tr' === $tag_name ) {
|
||||
// Close <tr> if closing tag is omitted.
|
||||
$this->end_tag( 'tr' );
|
||||
}
|
||||
|
||||
if ( 'tbody' === $tag_name or 'tfoot' === $tag_name ) {
|
||||
// Close <thead> if closing tag is omitted.
|
||||
$this->end_tag( 'thead' );
|
||||
}
|
||||
|
||||
if ( 'tfoot' === $tag_name ) {
|
||||
// Close <tbody> if closing tag is omitted.
|
||||
$this->end_tag( 'tbody' );
|
||||
}
|
||||
|
||||
if (
|
||||
$this->has_parent( $tag_name ) and
|
||||
! in_array( $tag_name, self::nestable_elements, true )
|
||||
) {
|
||||
$this->end_tag( $tag_name );
|
||||
}
|
||||
|
||||
if ( ! in_array( $tag_name, self::void_elements, true ) ) {
|
||||
array_unshift( $this->stacked_elements, $tag_name );
|
||||
}
|
||||
|
||||
if ( ! in_array( $tag_name, self::p_child_elements, true ) ) {
|
||||
if ( '' !== $this->output ) {
|
||||
$this->output = wpcf7_strip_whitespaces( $this->output, 'end' ) . "\n";
|
||||
}
|
||||
|
||||
if ( $this->options['auto_indent'] ) {
|
||||
$this->append_preformatted(
|
||||
self::indent( count( $this->stacked_elements ) - 1 )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if ( $tag ) {
|
||||
$this->append_preformatted( $tag );
|
||||
} elseif ( $atts ) {
|
||||
if ( in_array( $tag_name, self::void_elements, true ) ) {
|
||||
$this->append_preformatted(
|
||||
sprintf(
|
||||
'<%1$s %2$s />',
|
||||
$tag_name,
|
||||
wpcf7_format_atts( $atts )
|
||||
)
|
||||
);
|
||||
} else {
|
||||
$this->append_preformatted(
|
||||
sprintf(
|
||||
'<%1$s %2$s>',
|
||||
$tag_name,
|
||||
wpcf7_format_atts( $atts )
|
||||
)
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if ( in_array( $tag_name, self::void_elements, true ) ) {
|
||||
$this->append_preformatted(
|
||||
sprintf(
|
||||
'<%s />',
|
||||
$tag_name
|
||||
)
|
||||
);
|
||||
} else {
|
||||
$this->append_preformatted(
|
||||
sprintf(
|
||||
'<%s>',
|
||||
$tag_name
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Closes an element and its open descendants at a time.
|
||||
*
|
||||
* @param string $tag An end tag.
|
||||
*/
|
||||
public function end_tag( $tag ) {
|
||||
if ( preg_match( '/<\/(.+?)(?:\s|>)/', $tag, $matches ) ) {
|
||||
$tag_name = strtolower( $matches[1] );
|
||||
} else {
|
||||
$tag_name = strtolower( $tag );
|
||||
}
|
||||
|
||||
$stacked_elements = array_values( $this->stacked_elements );
|
||||
|
||||
$tag_position = array_search( $tag_name, $stacked_elements, true );
|
||||
|
||||
if ( false === $tag_position ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Element groups that make up an indirect nesting structure.
|
||||
// Descendant can contain ancestors.
|
||||
static $nesting_families = array(
|
||||
array(
|
||||
'ancestors' => array( 'dl' ),
|
||||
'descendants' => array( 'dd', 'dt' ),
|
||||
),
|
||||
array(
|
||||
'ancestors' => array( 'ol', 'ul', 'menu' ),
|
||||
'descendants' => array( 'li' ),
|
||||
),
|
||||
array(
|
||||
'ancestors' => array( 'table' ),
|
||||
'descendants' => array( 'td', 'th', 'tr', 'thead', 'tbody', 'tfoot' ),
|
||||
),
|
||||
);
|
||||
|
||||
foreach ( $nesting_families as $family ) {
|
||||
$ancestors = (array) $family['ancestors'];
|
||||
$descendants = (array) $family['descendants'];
|
||||
|
||||
if ( in_array( $tag_name, $descendants, true ) ) {
|
||||
$intersect = array_intersect(
|
||||
$ancestors,
|
||||
array_slice( $stacked_elements, 0, $tag_position )
|
||||
);
|
||||
|
||||
if ( $intersect ) { // Ancestor appears after descendant.
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while ( $element = array_shift( $this->stacked_elements ) ) {
|
||||
$this->append_end_tag( $element );
|
||||
|
||||
if ( $element === $tag_name ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Appends an end tag to the output property.
|
||||
*
|
||||
* @param string $tag_name Tag name.
|
||||
*/
|
||||
public function append_end_tag( $tag_name ) {
|
||||
if ( ! in_array( $tag_name, self::p_child_elements, true ) ) {
|
||||
// Remove unnecessary <br />.
|
||||
$this->output = preg_replace( '/\s*<br \/>\s*$/', '', $this->output );
|
||||
|
||||
$this->output = wpcf7_strip_whitespaces( $this->output, 'end' ) . "\n";
|
||||
|
||||
if ( $this->options['auto_indent'] ) {
|
||||
$this->append_preformatted(
|
||||
self::indent( count( $this->stacked_elements ) )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$this->append_preformatted(
|
||||
sprintf( '</%s>', $tag_name )
|
||||
);
|
||||
|
||||
// Remove trailing <p></p>.
|
||||
$this->output = preg_replace( '/<p>\s*<\/p>$/', '', $this->output );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Closes all open tags.
|
||||
*/
|
||||
public function close_all_tags() {
|
||||
while ( $element = array_shift( $this->stacked_elements ) ) {
|
||||
$this->append_end_tag( $element );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Appends an HTML comment to the output property.
|
||||
*
|
||||
* @param string $tag An HTML comment.
|
||||
*/
|
||||
public function append_comment( $tag ) {
|
||||
$this->append_preformatted( $tag );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if it is currently inside one of HTML elements specified
|
||||
* by tag names.
|
||||
*
|
||||
* @param string|array $tag_names A tag name or an array of tag names.
|
||||
*/
|
||||
public function is_inside( $tag_names ) {
|
||||
$tag_names = (array) $tag_names;
|
||||
|
||||
foreach ( $this->stacked_elements as $element ) {
|
||||
if ( in_array( $element, $tag_names, true ) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the parent node is one of HTML elements specified
|
||||
* by tag names.
|
||||
*
|
||||
* @param string|array $tag_names A tag name or an array of tag names.
|
||||
*/
|
||||
public function has_parent( $tag_names ) {
|
||||
$tag_names = (array) $tag_names;
|
||||
|
||||
$parent = reset( $this->stacked_elements );
|
||||
|
||||
if ( false === $parent ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return in_array( $parent, $tag_names, true );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Calls the callback given by the first parameter. The buffered output
|
||||
* will be appended to the output property.
|
||||
*/
|
||||
public function call_user_func( $callback, ...$args ) {
|
||||
ob_start();
|
||||
$result = call_user_func( $callback, ...$args );
|
||||
$output = ob_get_clean();
|
||||
|
||||
if ( false !== $output ) {
|
||||
$this->append_preformatted( "\n" . $output . "\n" );
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Closes all remaining tags, returns and resets the output.
|
||||
*/
|
||||
public function output() {
|
||||
$this->close_all_tags();
|
||||
|
||||
$output = $this->output;
|
||||
$this->output = '';
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Prints the output. Returns false if the allowed_html option is empty.
|
||||
*/
|
||||
public function print() {
|
||||
if ( empty( $this->options['allowed_html'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
echo wp_kses( $this->output(), $this->options['allowed_html'] );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Calculates the position of the next chunk based on the position and
|
||||
* length of the current chunk.
|
||||
*
|
||||
* @param array $chunk An associative array of the current chunk.
|
||||
* @return int The position of the next chunk.
|
||||
*/
|
||||
public static function calc_next_position( $chunk ) {
|
||||
return $chunk['position'] + strlen( $chunk['content'] );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Outputs a set of tabs to indent.
|
||||
*
|
||||
* @param int $level Indentation level.
|
||||
* @return string A series of tabs.
|
||||
*/
|
||||
public static function indent( $level ) {
|
||||
$level = (int) $level;
|
||||
|
||||
if ( 0 < $level ) {
|
||||
return str_repeat( "\t", $level );
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Normalizes a start tag.
|
||||
*
|
||||
* @param string $tag A start tag or a tag name.
|
||||
* @return array An array includes the normalized start tag and tag name.
|
||||
*/
|
||||
public static function normalize_start_tag( $tag ) {
|
||||
if ( preg_match( '/<(.+?)[\s\/>]/', $tag, $matches ) ) {
|
||||
$tag_name = strtolower( $matches[1] );
|
||||
} else {
|
||||
$tag_name = strtolower( $tag );
|
||||
$tag = sprintf( '<%s>', $tag_name );
|
||||
}
|
||||
|
||||
if ( in_array( $tag_name, self::void_elements, true ) ) {
|
||||
// Normalize void element.
|
||||
$tag = preg_replace( '/\s*\/?>/', ' />', $tag );
|
||||
}
|
||||
|
||||
return array( $tag, $tag_name );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Normalizes a paragraph of text.
|
||||
*
|
||||
* @param string $paragraph A paragraph of text.
|
||||
* @param bool $auto_br Optional. If true, line breaks will be replaced
|
||||
* by a br element.
|
||||
* @return string The normalized paragraph.
|
||||
*/
|
||||
public static function normalize_paragraph( $paragraph, $auto_br = false ) {
|
||||
if ( $auto_br ) {
|
||||
$paragraph = preg_replace( '/\s*\n\s*/', "<br />\n", $paragraph );
|
||||
}
|
||||
|
||||
$paragraph = preg_replace( '/[ ]+/', ' ', $paragraph );
|
||||
|
||||
return $paragraph;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the specified tag name is valid.
|
||||
*/
|
||||
public static function validate_tag_name( $tag_name ) {
|
||||
return preg_match( '/^[a-z][0-9a-z]*(?:[:][a-z][0-9a-z]*)?$/', $tag_name );
|
||||
}
|
||||
|
||||
}
|
||||
430
wp-content/plugins/contact-form-7/includes/integration.php
Normal file
@ -0,0 +1,430 @@
|
||||
<?php
|
||||
/**
|
||||
* Integration API
|
||||
*
|
||||
* @link https://contactform7.com/integration-with-external-apis/
|
||||
*/
|
||||
|
||||
class WPCF7_Integration {
|
||||
|
||||
private static $instance;
|
||||
|
||||
private $services = array();
|
||||
private $categories = array();
|
||||
|
||||
private function __construct() {}
|
||||
|
||||
|
||||
/**
|
||||
* Returns initially supported service categories.
|
||||
*
|
||||
* @return array Service categories.
|
||||
*/
|
||||
public static function get_builtin_categories() {
|
||||
return array(
|
||||
'spam_protection' => __( 'Spam protection', 'contact-form-7' ),
|
||||
'email_marketing' => __( 'Email marketing', 'contact-form-7' ),
|
||||
'payments' => __( 'Payments', 'contact-form-7' ),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the singleton instance of this class.
|
||||
*
|
||||
* @return WPCF7_Integration The instance.
|
||||
*/
|
||||
public static function get_instance() {
|
||||
if ( empty( self::$instance ) ) {
|
||||
self::$instance = new self();
|
||||
self::$instance->categories = self::get_builtin_categories();
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds a service to the services list.
|
||||
*/
|
||||
public function add_service( $name, WPCF7_Service $service ) {
|
||||
$name = sanitize_key( $name );
|
||||
|
||||
if ( empty( $name ) or isset( $this->services[$name] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->services[$name] = $service;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds a service category to the categories list.
|
||||
*/
|
||||
public function add_category( $name, $title ) {
|
||||
$name = sanitize_key( $name );
|
||||
|
||||
if ( empty( $name ) or isset( $this->categories[$name] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->categories[$name] = $title;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if a service with the name exists in the services list.
|
||||
*
|
||||
* @param string $name The name of service to search.
|
||||
*/
|
||||
public function service_exists( $name = '' ) {
|
||||
if ( '' === $name ) {
|
||||
return (bool) count( $this->services );
|
||||
} else {
|
||||
return isset( $this->services[$name] );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a service object with the name.
|
||||
*
|
||||
* @param string $name The name of service.
|
||||
* @return WPCF7_Service|bool The service object if it exists,
|
||||
* false otherwise.
|
||||
*/
|
||||
public function get_service( $name ) {
|
||||
if ( $this->service_exists( $name ) ) {
|
||||
return $this->services[$name];
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Prints services list.
|
||||
*/
|
||||
public function list_services( $args = '' ) {
|
||||
$args = wp_parse_args( $args, array(
|
||||
'include' => array(),
|
||||
) );
|
||||
|
||||
$singular = false;
|
||||
$services = (array) $this->services;
|
||||
|
||||
if ( ! empty( $args['include'] ) ) {
|
||||
$services = array_intersect_key( $services,
|
||||
array_flip( (array) $args['include'] )
|
||||
);
|
||||
|
||||
if ( 1 === count( $services ) ) {
|
||||
$singular = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( empty( $services ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$action = wpcf7_current_action();
|
||||
|
||||
foreach ( $services as $name => $service ) {
|
||||
$cats = array_intersect_key( $this->categories,
|
||||
array_flip( $service->get_categories() )
|
||||
);
|
||||
?>
|
||||
<div class="card<?php echo $service->is_active() ? ' active' : ''; ?>" id="<?php echo esc_attr( $name ); ?>">
|
||||
<?php $service->icon(); ?>
|
||||
<h2 class="title"><?php echo esc_html( $service->get_title() ); ?></h2>
|
||||
<div class="infobox">
|
||||
<?php echo esc_html( implode( ', ', $cats ) ); ?>
|
||||
<br />
|
||||
<?php $service->link(); ?>
|
||||
</div>
|
||||
<br class="clear" />
|
||||
|
||||
<div class="inside">
|
||||
<?php
|
||||
if ( $singular ) {
|
||||
$service->display( $action );
|
||||
} else {
|
||||
$service->display();
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Abstract class for services.
|
||||
*
|
||||
* Only instances of this class's subclasses are allowed to be
|
||||
* listed on the Integration page.
|
||||
*/
|
||||
abstract class WPCF7_Service {
|
||||
|
||||
abstract public function get_title();
|
||||
abstract public function is_active();
|
||||
|
||||
|
||||
public function get_categories() {
|
||||
return array();
|
||||
}
|
||||
|
||||
|
||||
public function icon() {
|
||||
return '';
|
||||
}
|
||||
|
||||
|
||||
public function link() {
|
||||
return '';
|
||||
}
|
||||
|
||||
|
||||
public function load( $action = '' ) {
|
||||
}
|
||||
|
||||
|
||||
public function display( $action = '' ) {
|
||||
}
|
||||
|
||||
|
||||
public function admin_notice( $message = '' ) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Class for services that use OAuth.
|
||||
*
|
||||
* While this is not an abstract class, subclassing this class for
|
||||
* your aim is advised.
|
||||
*/
|
||||
class WPCF7_Service_OAuth2 extends WPCF7_Service {
|
||||
|
||||
protected $client_id = '';
|
||||
protected $client_secret = '';
|
||||
protected $access_token = '';
|
||||
protected $refresh_token = '';
|
||||
protected $authorization_endpoint = 'https://example.com/authorization';
|
||||
protected $token_endpoint = 'https://example.com/token';
|
||||
|
||||
|
||||
public function get_title() {
|
||||
return '';
|
||||
}
|
||||
|
||||
|
||||
public function is_active() {
|
||||
return ! empty( $this->refresh_token );
|
||||
}
|
||||
|
||||
|
||||
protected function save_data() {
|
||||
}
|
||||
|
||||
|
||||
protected function reset_data() {
|
||||
}
|
||||
|
||||
|
||||
protected function get_redirect_uri() {
|
||||
return admin_url();
|
||||
}
|
||||
|
||||
|
||||
protected function menu_page_url( $args = '' ) {
|
||||
return menu_page_url( 'wpcf7-integration', false );
|
||||
}
|
||||
|
||||
|
||||
public function load( $action = '' ) {
|
||||
if ( 'auth_redirect' === $action ) {
|
||||
$code = wpcf7_superglobal_get( 'code' );
|
||||
|
||||
if ( $code ) {
|
||||
$this->request_token( $code );
|
||||
}
|
||||
|
||||
if ( ! empty( $this->access_token ) ) {
|
||||
$message = 'success';
|
||||
} else {
|
||||
$message = 'failed';
|
||||
}
|
||||
|
||||
wp_safe_redirect( $this->menu_page_url(
|
||||
array(
|
||||
'action' => 'setup',
|
||||
'message' => $message,
|
||||
)
|
||||
) );
|
||||
|
||||
exit();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected function authorize( $scope = '' ) {
|
||||
$endpoint = add_query_arg(
|
||||
array(
|
||||
'response_type' => 'code',
|
||||
'client_id' => $this->client_id,
|
||||
'redirect_uri' => urlencode( $this->get_redirect_uri() ),
|
||||
'scope' => $scope,
|
||||
),
|
||||
$this->authorization_endpoint
|
||||
);
|
||||
|
||||
if ( wp_redirect( sanitize_url( $endpoint ) ) ) {
|
||||
exit();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected function get_http_authorization_header( $scheme = 'basic' ) {
|
||||
$scheme = strtolower( trim( $scheme ) );
|
||||
|
||||
switch ( $scheme ) {
|
||||
case 'bearer':
|
||||
return sprintf( 'Bearer %s', $this->access_token );
|
||||
case 'basic':
|
||||
default:
|
||||
return sprintf( 'Basic %s',
|
||||
base64_encode( $this->client_id . ':' . $this->client_secret )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected function request_token( $authorization_code ) {
|
||||
$endpoint = add_query_arg(
|
||||
array(
|
||||
'code' => $authorization_code,
|
||||
'redirect_uri' => urlencode( $this->get_redirect_uri() ),
|
||||
'grant_type' => 'authorization_code',
|
||||
),
|
||||
$this->token_endpoint
|
||||
);
|
||||
|
||||
$request = array(
|
||||
'headers' => array(
|
||||
'Authorization' => $this->get_http_authorization_header( 'basic' ),
|
||||
),
|
||||
);
|
||||
|
||||
$response = wp_remote_post( sanitize_url( $endpoint ), $request );
|
||||
$response_code = (int) wp_remote_retrieve_response_code( $response );
|
||||
$response_body = wp_remote_retrieve_body( $response );
|
||||
$response_body = json_decode( $response_body, true );
|
||||
|
||||
if ( WP_DEBUG and 400 <= $response_code ) {
|
||||
$this->log( $endpoint, $request, $response );
|
||||
}
|
||||
|
||||
if ( 401 === $response_code ) { // Unauthorized
|
||||
$this->access_token = null;
|
||||
$this->refresh_token = null;
|
||||
} else {
|
||||
if ( isset( $response_body['access_token'] ) ) {
|
||||
$this->access_token = $response_body['access_token'];
|
||||
} else {
|
||||
$this->access_token = null;
|
||||
}
|
||||
|
||||
if ( isset( $response_body['refresh_token'] ) ) {
|
||||
$this->refresh_token = $response_body['refresh_token'];
|
||||
} else {
|
||||
$this->refresh_token = null;
|
||||
}
|
||||
}
|
||||
|
||||
$this->save_data();
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
|
||||
protected function refresh_token() {
|
||||
$endpoint = add_query_arg(
|
||||
array(
|
||||
'refresh_token' => $this->refresh_token,
|
||||
'grant_type' => 'refresh_token',
|
||||
),
|
||||
$this->token_endpoint
|
||||
);
|
||||
|
||||
$request = array(
|
||||
'headers' => array(
|
||||
'Authorization' => $this->get_http_authorization_header( 'basic' ),
|
||||
),
|
||||
);
|
||||
|
||||
$response = wp_remote_post( sanitize_url( $endpoint ), $request );
|
||||
$response_code = (int) wp_remote_retrieve_response_code( $response );
|
||||
$response_body = wp_remote_retrieve_body( $response );
|
||||
$response_body = json_decode( $response_body, true );
|
||||
|
||||
if ( WP_DEBUG and 400 <= $response_code ) {
|
||||
$this->log( $endpoint, $request, $response );
|
||||
}
|
||||
|
||||
if ( 401 === $response_code ) { // Unauthorized
|
||||
$this->access_token = null;
|
||||
$this->refresh_token = null;
|
||||
} else {
|
||||
if ( isset( $response_body['access_token'] ) ) {
|
||||
$this->access_token = $response_body['access_token'];
|
||||
} else {
|
||||
$this->access_token = null;
|
||||
}
|
||||
|
||||
if ( isset( $response_body['refresh_token'] ) ) {
|
||||
$this->refresh_token = $response_body['refresh_token'];
|
||||
}
|
||||
}
|
||||
|
||||
$this->save_data();
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
|
||||
protected function remote_request( $url, $request = array() ) {
|
||||
static $refreshed = false;
|
||||
|
||||
$request = wp_parse_args( $request, array() );
|
||||
|
||||
$request['headers'] = array_merge(
|
||||
$request['headers'],
|
||||
array(
|
||||
'Authorization' => $this->get_http_authorization_header( 'bearer' ),
|
||||
)
|
||||
);
|
||||
|
||||
$response = wp_remote_request( sanitize_url( $url ), $request );
|
||||
|
||||
if ( 401 === wp_remote_retrieve_response_code( $response )
|
||||
and ! $refreshed ) {
|
||||
$this->refresh_token();
|
||||
$refreshed = true;
|
||||
|
||||
$response = $this->remote_request( $url, $request );
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
|
||||
protected function log( $url, $request, $response ) {
|
||||
wpcf7_log_remote_request( $url, $request, $response );
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
( function( $ ) {
|
||||
$( function() {
|
||||
var supportHtml5 = ( function() {
|
||||
var features = {};
|
||||
var input = document.createElement( 'input' );
|
||||
var inputTypes = [ 'date' ];
|
||||
|
||||
$.each( inputTypes, function( index, value ) {
|
||||
input.setAttribute( 'type', value );
|
||||
features[ value ] = input.type !== 'text';
|
||||
} );
|
||||
|
||||
return features;
|
||||
} )();
|
||||
|
||||
if ( ! supportHtml5.date ) {
|
||||
$( 'input.wpcf7-date[type="date"]' ).each( function() {
|
||||
$( this ).datepicker( {
|
||||
dateFormat: 'yy-mm-dd',
|
||||
minDate: new Date( $( this ).attr( 'min' ) ),
|
||||
maxDate: new Date( $( this ).attr( 'max' ) )
|
||||
} );
|
||||
} );
|
||||
}
|
||||
} );
|
||||
} )( jQuery );
|
||||
@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
return array(
|
||||
'dependencies' => array(
|
||||
'wp-i18n',
|
||||
),
|
||||
'version' => WPCF7_VERSION,
|
||||
);
|
||||
1
wp-content/plugins/contact-form-7/includes/js/index.js
Normal file
|
After Width: | Height: | Size: 393 B |
|
After Width: | Height: | Size: 265 B |
|
After Width: | Height: | Size: 323 B |
|
After Width: | Height: | Size: 324 B |
|
After Width: | Height: | Size: 390 B |
|
After Width: | Height: | Size: 325 B |
|
After Width: | Height: | Size: 6.9 KiB |
|
After Width: | Height: | Size: 4.6 KiB |
|
After Width: | Height: | Size: 6.9 KiB |
|
After Width: | Height: | Size: 6.9 KiB |
|
After Width: | Height: | Size: 4.6 KiB |
1311
wp-content/plugins/contact-form-7/includes/js/jquery-ui/themes/smoothness/jquery-ui.css
vendored
Normal file
7
wp-content/plugins/contact-form-7/includes/js/jquery-ui/themes/smoothness/jquery-ui.min.css
vendored
Normal file
@ -0,0 +1,443 @@
|
||||
/*!
|
||||
* jQuery UI CSS Framework 1.12.1
|
||||
* http://jqueryui.com
|
||||
*
|
||||
* Copyright jQuery Foundation and other contributors
|
||||
* Released under the MIT license.
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* http://api.jqueryui.com/category/theming/
|
||||
*
|
||||
* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana%2CArial%2Csans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=cccccc&bgTextureHeader=highlight_soft&bgImgOpacityHeader=75&borderColorHeader=aaaaaa&fcHeader=222222&iconColorHeader=222222&bgColorContent=ffffff&bgTextureContent=flat&bgImgOpacityContent=75&borderColorContent=aaaaaa&fcContent=222222&iconColorContent=222222&bgColorDefault=e6e6e6&bgTextureDefault=glass&bgImgOpacityDefault=75&borderColorDefault=d3d3d3&fcDefault=555555&iconColorDefault=888888&bgColorHover=dadada&bgTextureHover=glass&bgImgOpacityHover=75&borderColorHover=999999&fcHover=212121&iconColorHover=454545&bgColorActive=ffffff&bgTextureActive=glass&bgImgOpacityActive=65&borderColorActive=aaaaaa&fcActive=212121&iconColorActive=454545&bgColorHighlight=fbf9ee&bgTextureHighlight=glass&bgImgOpacityHighlight=55&borderColorHighlight=fcefa1&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=glass&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=flat&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=flat&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px
|
||||
*/
|
||||
|
||||
|
||||
/* Component containers
|
||||
----------------------------------*/
|
||||
.ui-widget {
|
||||
font-family: Verdana,Arial,sans-serif;
|
||||
font-size: 1.1em;
|
||||
}
|
||||
.ui-widget .ui-widget {
|
||||
font-size: 1em;
|
||||
}
|
||||
.ui-widget input,
|
||||
.ui-widget select,
|
||||
.ui-widget textarea,
|
||||
.ui-widget button {
|
||||
font-family: Verdana,Arial,sans-serif;
|
||||
font-size: 1em;
|
||||
}
|
||||
.ui-widget.ui-widget-content {
|
||||
border: 1px solid #d3d3d3;
|
||||
}
|
||||
.ui-widget-content {
|
||||
border: 1px solid #aaaaaa;
|
||||
background: #ffffff;
|
||||
color: #222222;
|
||||
}
|
||||
.ui-widget-content a {
|
||||
color: #222222;
|
||||
}
|
||||
.ui-widget-header {
|
||||
border: 1px solid #aaaaaa;
|
||||
background: #cccccc url("images/ui-bg_highlight-soft_75_cccccc_1x100.png") 50% 50% repeat-x;
|
||||
color: #222222;
|
||||
font-weight: bold;
|
||||
}
|
||||
.ui-widget-header a {
|
||||
color: #222222;
|
||||
}
|
||||
|
||||
/* Interaction states
|
||||
----------------------------------*/
|
||||
.ui-state-default,
|
||||
.ui-widget-content .ui-state-default,
|
||||
.ui-widget-header .ui-state-default,
|
||||
.ui-button,
|
||||
|
||||
/* We use html here because we need a greater specificity to make sure disabled
|
||||
works properly when clicked or hovered */
|
||||
html .ui-button.ui-state-disabled:hover,
|
||||
html .ui-button.ui-state-disabled:active {
|
||||
border: 1px solid #d3d3d3;
|
||||
background: #e6e6e6 url("images/ui-bg_glass_75_e6e6e6_1x400.png") 50% 50% repeat-x;
|
||||
font-weight: normal;
|
||||
color: #555555;
|
||||
}
|
||||
.ui-state-default a,
|
||||
.ui-state-default a:link,
|
||||
.ui-state-default a:visited,
|
||||
a.ui-button,
|
||||
a:link.ui-button,
|
||||
a:visited.ui-button,
|
||||
.ui-button {
|
||||
color: #555555;
|
||||
text-decoration: none;
|
||||
}
|
||||
.ui-state-hover,
|
||||
.ui-widget-content .ui-state-hover,
|
||||
.ui-widget-header .ui-state-hover,
|
||||
.ui-state-focus,
|
||||
.ui-widget-content .ui-state-focus,
|
||||
.ui-widget-header .ui-state-focus,
|
||||
.ui-button:hover,
|
||||
.ui-button:focus {
|
||||
border: 1px solid #999999;
|
||||
background: #dadada url("images/ui-bg_glass_75_dadada_1x400.png") 50% 50% repeat-x;
|
||||
font-weight: normal;
|
||||
color: #212121;
|
||||
}
|
||||
.ui-state-hover a,
|
||||
.ui-state-hover a:hover,
|
||||
.ui-state-hover a:link,
|
||||
.ui-state-hover a:visited,
|
||||
.ui-state-focus a,
|
||||
.ui-state-focus a:hover,
|
||||
.ui-state-focus a:link,
|
||||
.ui-state-focus a:visited,
|
||||
a.ui-button:hover,
|
||||
a.ui-button:focus {
|
||||
color: #212121;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.ui-visual-focus {
|
||||
box-shadow: 0 0 3px 1px rgb(94, 158, 214);
|
||||
}
|
||||
.ui-state-active,
|
||||
.ui-widget-content .ui-state-active,
|
||||
.ui-widget-header .ui-state-active,
|
||||
a.ui-button:active,
|
||||
.ui-button:active,
|
||||
.ui-button.ui-state-active:hover {
|
||||
border: 1px solid #aaaaaa;
|
||||
background: #ffffff url("images/ui-bg_glass_65_ffffff_1x400.png") 50% 50% repeat-x;
|
||||
font-weight: normal;
|
||||
color: #212121;
|
||||
}
|
||||
.ui-icon-background,
|
||||
.ui-state-active .ui-icon-background {
|
||||
border: #aaaaaa;
|
||||
background-color: #212121;
|
||||
}
|
||||
.ui-state-active a,
|
||||
.ui-state-active a:link,
|
||||
.ui-state-active a:visited {
|
||||
color: #212121;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* Interaction Cues
|
||||
----------------------------------*/
|
||||
.ui-state-highlight,
|
||||
.ui-widget-content .ui-state-highlight,
|
||||
.ui-widget-header .ui-state-highlight {
|
||||
border: 1px solid #fcefa1;
|
||||
background: #fbf9ee url("images/ui-bg_glass_55_fbf9ee_1x400.png") 50% 50% repeat-x;
|
||||
color: #363636;
|
||||
}
|
||||
.ui-state-checked {
|
||||
border: 1px solid #fcefa1;
|
||||
background: #fbf9ee;
|
||||
}
|
||||
.ui-state-highlight a,
|
||||
.ui-widget-content .ui-state-highlight a,
|
||||
.ui-widget-header .ui-state-highlight a {
|
||||
color: #363636;
|
||||
}
|
||||
.ui-state-error,
|
||||
.ui-widget-content .ui-state-error,
|
||||
.ui-widget-header .ui-state-error {
|
||||
border: 1px solid #cd0a0a;
|
||||
background: #fef1ec url("images/ui-bg_glass_95_fef1ec_1x400.png") 50% 50% repeat-x;
|
||||
color: #cd0a0a;
|
||||
}
|
||||
.ui-state-error a,
|
||||
.ui-widget-content .ui-state-error a,
|
||||
.ui-widget-header .ui-state-error a {
|
||||
color: #cd0a0a;
|
||||
}
|
||||
.ui-state-error-text,
|
||||
.ui-widget-content .ui-state-error-text,
|
||||
.ui-widget-header .ui-state-error-text {
|
||||
color: #cd0a0a;
|
||||
}
|
||||
.ui-priority-primary,
|
||||
.ui-widget-content .ui-priority-primary,
|
||||
.ui-widget-header .ui-priority-primary {
|
||||
font-weight: bold;
|
||||
}
|
||||
.ui-priority-secondary,
|
||||
.ui-widget-content .ui-priority-secondary,
|
||||
.ui-widget-header .ui-priority-secondary {
|
||||
opacity: .7;
|
||||
filter:Alpha(Opacity=70); /* support: IE8 */
|
||||
font-weight: normal;
|
||||
}
|
||||
.ui-state-disabled,
|
||||
.ui-widget-content .ui-state-disabled,
|
||||
.ui-widget-header .ui-state-disabled {
|
||||
opacity: .35;
|
||||
filter:Alpha(Opacity=35); /* support: IE8 */
|
||||
background-image: none;
|
||||
}
|
||||
.ui-state-disabled .ui-icon {
|
||||
filter:Alpha(Opacity=35); /* support: IE8 - See #6059 */
|
||||
}
|
||||
|
||||
/* Icons
|
||||
----------------------------------*/
|
||||
|
||||
/* states and images */
|
||||
.ui-icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
.ui-icon,
|
||||
.ui-widget-content .ui-icon {
|
||||
background-image: url("images/ui-icons_222222_256x240.png");
|
||||
}
|
||||
.ui-widget-header .ui-icon {
|
||||
background-image: url("images/ui-icons_222222_256x240.png");
|
||||
}
|
||||
.ui-state-hover .ui-icon,
|
||||
.ui-state-focus .ui-icon,
|
||||
.ui-button:hover .ui-icon,
|
||||
.ui-button:focus .ui-icon {
|
||||
background-image: url("images/ui-icons_454545_256x240.png");
|
||||
}
|
||||
.ui-state-active .ui-icon,
|
||||
.ui-button:active .ui-icon {
|
||||
background-image: url("images/ui-icons_454545_256x240.png");
|
||||
}
|
||||
.ui-state-highlight .ui-icon,
|
||||
.ui-button .ui-state-highlight.ui-icon {
|
||||
background-image: url("images/ui-icons_2e83ff_256x240.png");
|
||||
}
|
||||
.ui-state-error .ui-icon,
|
||||
.ui-state-error-text .ui-icon {
|
||||
background-image: url("images/ui-icons_cd0a0a_256x240.png");
|
||||
}
|
||||
.ui-button .ui-icon {
|
||||
background-image: url("images/ui-icons_888888_256x240.png");
|
||||
}
|
||||
|
||||
/* positioning */
|
||||
.ui-icon-blank { background-position: 16px 16px; }
|
||||
.ui-icon-caret-1-n { background-position: 0 0; }
|
||||
.ui-icon-caret-1-ne { background-position: -16px 0; }
|
||||
.ui-icon-caret-1-e { background-position: -32px 0; }
|
||||
.ui-icon-caret-1-se { background-position: -48px 0; }
|
||||
.ui-icon-caret-1-s { background-position: -65px 0; }
|
||||
.ui-icon-caret-1-sw { background-position: -80px 0; }
|
||||
.ui-icon-caret-1-w { background-position: -96px 0; }
|
||||
.ui-icon-caret-1-nw { background-position: -112px 0; }
|
||||
.ui-icon-caret-2-n-s { background-position: -128px 0; }
|
||||
.ui-icon-caret-2-e-w { background-position: -144px 0; }
|
||||
.ui-icon-triangle-1-n { background-position: 0 -16px; }
|
||||
.ui-icon-triangle-1-ne { background-position: -16px -16px; }
|
||||
.ui-icon-triangle-1-e { background-position: -32px -16px; }
|
||||
.ui-icon-triangle-1-se { background-position: -48px -16px; }
|
||||
.ui-icon-triangle-1-s { background-position: -65px -16px; }
|
||||
.ui-icon-triangle-1-sw { background-position: -80px -16px; }
|
||||
.ui-icon-triangle-1-w { background-position: -96px -16px; }
|
||||
.ui-icon-triangle-1-nw { background-position: -112px -16px; }
|
||||
.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
|
||||
.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
|
||||
.ui-icon-arrow-1-n { background-position: 0 -32px; }
|
||||
.ui-icon-arrow-1-ne { background-position: -16px -32px; }
|
||||
.ui-icon-arrow-1-e { background-position: -32px -32px; }
|
||||
.ui-icon-arrow-1-se { background-position: -48px -32px; }
|
||||
.ui-icon-arrow-1-s { background-position: -65px -32px; }
|
||||
.ui-icon-arrow-1-sw { background-position: -80px -32px; }
|
||||
.ui-icon-arrow-1-w { background-position: -96px -32px; }
|
||||
.ui-icon-arrow-1-nw { background-position: -112px -32px; }
|
||||
.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
|
||||
.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
|
||||
.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
|
||||
.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
|
||||
.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
|
||||
.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
|
||||
.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
|
||||
.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
|
||||
.ui-icon-arrowthick-1-n { background-position: 1px -48px; }
|
||||
.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
|
||||
.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
|
||||
.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
|
||||
.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
|
||||
.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
|
||||
.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
|
||||
.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
|
||||
.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
|
||||
.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
|
||||
.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
|
||||
.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
|
||||
.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
|
||||
.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
|
||||
.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
|
||||
.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
|
||||
.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
|
||||
.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
|
||||
.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
|
||||
.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
|
||||
.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
|
||||
.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
|
||||
.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
|
||||
.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
|
||||
.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
|
||||
.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
|
||||
.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
|
||||
.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
|
||||
.ui-icon-arrow-4 { background-position: 0 -80px; }
|
||||
.ui-icon-arrow-4-diag { background-position: -16px -80px; }
|
||||
.ui-icon-extlink { background-position: -32px -80px; }
|
||||
.ui-icon-newwin { background-position: -48px -80px; }
|
||||
.ui-icon-refresh { background-position: -64px -80px; }
|
||||
.ui-icon-shuffle { background-position: -80px -80px; }
|
||||
.ui-icon-transfer-e-w { background-position: -96px -80px; }
|
||||
.ui-icon-transferthick-e-w { background-position: -112px -80px; }
|
||||
.ui-icon-folder-collapsed { background-position: 0 -96px; }
|
||||
.ui-icon-folder-open { background-position: -16px -96px; }
|
||||
.ui-icon-document { background-position: -32px -96px; }
|
||||
.ui-icon-document-b { background-position: -48px -96px; }
|
||||
.ui-icon-note { background-position: -64px -96px; }
|
||||
.ui-icon-mail-closed { background-position: -80px -96px; }
|
||||
.ui-icon-mail-open { background-position: -96px -96px; }
|
||||
.ui-icon-suitcase { background-position: -112px -96px; }
|
||||
.ui-icon-comment { background-position: -128px -96px; }
|
||||
.ui-icon-person { background-position: -144px -96px; }
|
||||
.ui-icon-print { background-position: -160px -96px; }
|
||||
.ui-icon-trash { background-position: -176px -96px; }
|
||||
.ui-icon-locked { background-position: -192px -96px; }
|
||||
.ui-icon-unlocked { background-position: -208px -96px; }
|
||||
.ui-icon-bookmark { background-position: -224px -96px; }
|
||||
.ui-icon-tag { background-position: -240px -96px; }
|
||||
.ui-icon-home { background-position: 0 -112px; }
|
||||
.ui-icon-flag { background-position: -16px -112px; }
|
||||
.ui-icon-calendar { background-position: -32px -112px; }
|
||||
.ui-icon-cart { background-position: -48px -112px; }
|
||||
.ui-icon-pencil { background-position: -64px -112px; }
|
||||
.ui-icon-clock { background-position: -80px -112px; }
|
||||
.ui-icon-disk { background-position: -96px -112px; }
|
||||
.ui-icon-calculator { background-position: -112px -112px; }
|
||||
.ui-icon-zoomin { background-position: -128px -112px; }
|
||||
.ui-icon-zoomout { background-position: -144px -112px; }
|
||||
.ui-icon-search { background-position: -160px -112px; }
|
||||
.ui-icon-wrench { background-position: -176px -112px; }
|
||||
.ui-icon-gear { background-position: -192px -112px; }
|
||||
.ui-icon-heart { background-position: -208px -112px; }
|
||||
.ui-icon-star { background-position: -224px -112px; }
|
||||
.ui-icon-link { background-position: -240px -112px; }
|
||||
.ui-icon-cancel { background-position: 0 -128px; }
|
||||
.ui-icon-plus { background-position: -16px -128px; }
|
||||
.ui-icon-plusthick { background-position: -32px -128px; }
|
||||
.ui-icon-minus { background-position: -48px -128px; }
|
||||
.ui-icon-minusthick { background-position: -64px -128px; }
|
||||
.ui-icon-close { background-position: -80px -128px; }
|
||||
.ui-icon-closethick { background-position: -96px -128px; }
|
||||
.ui-icon-key { background-position: -112px -128px; }
|
||||
.ui-icon-lightbulb { background-position: -128px -128px; }
|
||||
.ui-icon-scissors { background-position: -144px -128px; }
|
||||
.ui-icon-clipboard { background-position: -160px -128px; }
|
||||
.ui-icon-copy { background-position: -176px -128px; }
|
||||
.ui-icon-contact { background-position: -192px -128px; }
|
||||
.ui-icon-image { background-position: -208px -128px; }
|
||||
.ui-icon-video { background-position: -224px -128px; }
|
||||
.ui-icon-script { background-position: -240px -128px; }
|
||||
.ui-icon-alert { background-position: 0 -144px; }
|
||||
.ui-icon-info { background-position: -16px -144px; }
|
||||
.ui-icon-notice { background-position: -32px -144px; }
|
||||
.ui-icon-help { background-position: -48px -144px; }
|
||||
.ui-icon-check { background-position: -64px -144px; }
|
||||
.ui-icon-bullet { background-position: -80px -144px; }
|
||||
.ui-icon-radio-on { background-position: -96px -144px; }
|
||||
.ui-icon-radio-off { background-position: -112px -144px; }
|
||||
.ui-icon-pin-w { background-position: -128px -144px; }
|
||||
.ui-icon-pin-s { background-position: -144px -144px; }
|
||||
.ui-icon-play { background-position: 0 -160px; }
|
||||
.ui-icon-pause { background-position: -16px -160px; }
|
||||
.ui-icon-seek-next { background-position: -32px -160px; }
|
||||
.ui-icon-seek-prev { background-position: -48px -160px; }
|
||||
.ui-icon-seek-end { background-position: -64px -160px; }
|
||||
.ui-icon-seek-start { background-position: -80px -160px; }
|
||||
/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
|
||||
.ui-icon-seek-first { background-position: -80px -160px; }
|
||||
.ui-icon-stop { background-position: -96px -160px; }
|
||||
.ui-icon-eject { background-position: -112px -160px; }
|
||||
.ui-icon-volume-off { background-position: -128px -160px; }
|
||||
.ui-icon-volume-on { background-position: -144px -160px; }
|
||||
.ui-icon-power { background-position: 0 -176px; }
|
||||
.ui-icon-signal-diag { background-position: -16px -176px; }
|
||||
.ui-icon-signal { background-position: -32px -176px; }
|
||||
.ui-icon-battery-0 { background-position: -48px -176px; }
|
||||
.ui-icon-battery-1 { background-position: -64px -176px; }
|
||||
.ui-icon-battery-2 { background-position: -80px -176px; }
|
||||
.ui-icon-battery-3 { background-position: -96px -176px; }
|
||||
.ui-icon-circle-plus { background-position: 0 -192px; }
|
||||
.ui-icon-circle-minus { background-position: -16px -192px; }
|
||||
.ui-icon-circle-close { background-position: -32px -192px; }
|
||||
.ui-icon-circle-triangle-e { background-position: -48px -192px; }
|
||||
.ui-icon-circle-triangle-s { background-position: -64px -192px; }
|
||||
.ui-icon-circle-triangle-w { background-position: -80px -192px; }
|
||||
.ui-icon-circle-triangle-n { background-position: -96px -192px; }
|
||||
.ui-icon-circle-arrow-e { background-position: -112px -192px; }
|
||||
.ui-icon-circle-arrow-s { background-position: -128px -192px; }
|
||||
.ui-icon-circle-arrow-w { background-position: -144px -192px; }
|
||||
.ui-icon-circle-arrow-n { background-position: -160px -192px; }
|
||||
.ui-icon-circle-zoomin { background-position: -176px -192px; }
|
||||
.ui-icon-circle-zoomout { background-position: -192px -192px; }
|
||||
.ui-icon-circle-check { background-position: -208px -192px; }
|
||||
.ui-icon-circlesmall-plus { background-position: 0 -208px; }
|
||||
.ui-icon-circlesmall-minus { background-position: -16px -208px; }
|
||||
.ui-icon-circlesmall-close { background-position: -32px -208px; }
|
||||
.ui-icon-squaresmall-plus { background-position: -48px -208px; }
|
||||
.ui-icon-squaresmall-minus { background-position: -64px -208px; }
|
||||
.ui-icon-squaresmall-close { background-position: -80px -208px; }
|
||||
.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
|
||||
.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
|
||||
.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
|
||||
.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
|
||||
.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
|
||||
.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
|
||||
|
||||
|
||||
/* Misc visuals
|
||||
----------------------------------*/
|
||||
|
||||
/* Corner radius */
|
||||
.ui-corner-all,
|
||||
.ui-corner-top,
|
||||
.ui-corner-left,
|
||||
.ui-corner-tl {
|
||||
border-top-left-radius: 4px;
|
||||
}
|
||||
.ui-corner-all,
|
||||
.ui-corner-top,
|
||||
.ui-corner-right,
|
||||
.ui-corner-tr {
|
||||
border-top-right-radius: 4px;
|
||||
}
|
||||
.ui-corner-all,
|
||||
.ui-corner-bottom,
|
||||
.ui-corner-left,
|
||||
.ui-corner-bl {
|
||||
border-bottom-left-radius: 4px;
|
||||
}
|
||||
.ui-corner-all,
|
||||
.ui-corner-bottom,
|
||||
.ui-corner-right,
|
||||
.ui-corner-br {
|
||||
border-bottom-right-radius: 4px;
|
||||
}
|
||||
|
||||
/* Overlays */
|
||||
.ui-widget-overlay {
|
||||
background: #aaaaaa;
|
||||
opacity: .3;
|
||||
filter: Alpha(Opacity=30); /* support: IE8 */
|
||||
}
|
||||
.ui-widget-shadow {
|
||||
-webkit-box-shadow: -8px -8px 8px #aaaaaa;
|
||||
box-shadow: -8px -8px 8px #aaaaaa;
|
||||
}
|
||||
156
wp-content/plugins/contact-form-7/includes/l10n.php
Normal file
@ -0,0 +1,156 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Retrieves an associative array of languages to which
|
||||
* this plugin is translated.
|
||||
*
|
||||
* @return array Array of languages.
|
||||
*/
|
||||
function wpcf7_l10n() {
|
||||
static $l10n = array();
|
||||
|
||||
if ( ! empty( $l10n ) ) {
|
||||
return $l10n;
|
||||
}
|
||||
|
||||
if ( ! is_admin() ) {
|
||||
return $l10n;
|
||||
}
|
||||
|
||||
require_once ABSPATH . 'wp-admin/includes/translation-install.php';
|
||||
|
||||
$api = translations_api( 'plugins', array(
|
||||
'slug' => 'contact-form-7',
|
||||
'version' => WPCF7_VERSION,
|
||||
) );
|
||||
|
||||
if ( is_wp_error( $api ) or empty( $api['translations'] ) ) {
|
||||
return $l10n;
|
||||
}
|
||||
|
||||
foreach ( (array) $api['translations'] as $translation ) {
|
||||
if (
|
||||
! empty( $translation['language'] ) and
|
||||
! empty( $translation['english_name'] )
|
||||
) {
|
||||
$l10n[$translation['language']] = $translation['english_name'];
|
||||
}
|
||||
}
|
||||
|
||||
return $l10n;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the given locale code looks valid.
|
||||
*
|
||||
* @param string $locale Locale code.
|
||||
*/
|
||||
function wpcf7_is_valid_locale( $locale ) {
|
||||
if ( ! is_string( $locale ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$pattern = '/^[a-z]{2,3}(?:_[a-zA-Z_]{2,})?$/';
|
||||
return (bool) preg_match( $pattern, $locale );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the given locale is an RTL language.
|
||||
*/
|
||||
function wpcf7_is_rtl( $locale = '' ) {
|
||||
static $rtl_locales = array(
|
||||
'ar' => 'Arabic',
|
||||
'ary' => 'Moroccan Arabic',
|
||||
'azb' => 'South Azerbaijani',
|
||||
'fa_IR' => 'Persian',
|
||||
'haz' => 'Hazaragi',
|
||||
'he_IL' => 'Hebrew',
|
||||
'ps' => 'Pashto',
|
||||
'ug_CN' => 'Uighur',
|
||||
);
|
||||
|
||||
if ( empty( $locale ) and function_exists( 'is_rtl' ) ) {
|
||||
return is_rtl();
|
||||
}
|
||||
|
||||
if ( empty( $locale ) ) {
|
||||
$locale = determine_locale();
|
||||
}
|
||||
|
||||
return isset( $rtl_locales[$locale] );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Loads a translation file into the plugin's text domain.
|
||||
*
|
||||
* @param string $locale Locale code.
|
||||
* @return bool True on success, false on failure.
|
||||
*/
|
||||
function wpcf7_load_textdomain( $locale = '' ) {
|
||||
$mofile = path_join(
|
||||
WP_LANG_DIR . '/plugins/',
|
||||
sprintf( '%s-%s.mo', WPCF7_TEXT_DOMAIN, $locale )
|
||||
);
|
||||
|
||||
return load_textdomain( WPCF7_TEXT_DOMAIN, $mofile, $locale );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Unloads translations for the plugin's text domain.
|
||||
*
|
||||
* @param bool $reloadable Whether the text domain can be loaded
|
||||
* just-in-time again.
|
||||
* @return bool True on success, false on failure.
|
||||
*/
|
||||
function wpcf7_unload_textdomain( $reloadable = false ) {
|
||||
return unload_textdomain( WPCF7_TEXT_DOMAIN, $reloadable );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Switches translation locale, calls the callback, then switches back
|
||||
* to the original locale.
|
||||
*
|
||||
* @param string $locale Locale code.
|
||||
* @param callable $callback The callable to be called.
|
||||
* @param mixed $args Parameters to be passed to the callback.
|
||||
* @return mixed The return value of the callback.
|
||||
*/
|
||||
function wpcf7_switch_locale( $locale, callable $callback, ...$args ) {
|
||||
static $available_locales = null;
|
||||
|
||||
if ( ! isset( $available_locales ) ) {
|
||||
$available_locales = array_merge(
|
||||
array( 'en_US' ),
|
||||
get_available_languages()
|
||||
);
|
||||
}
|
||||
|
||||
$previous_locale = determine_locale();
|
||||
|
||||
$do_switch_locale = (
|
||||
$locale !== $previous_locale &&
|
||||
in_array( $locale, $available_locales, true ) &&
|
||||
in_array( $previous_locale, $available_locales, true )
|
||||
);
|
||||
|
||||
if ( $do_switch_locale ) {
|
||||
wpcf7_unload_textdomain();
|
||||
switch_to_locale( $locale );
|
||||
wpcf7_load_textdomain( $locale );
|
||||
}
|
||||
|
||||
$result = call_user_func( $callback, ...$args );
|
||||
|
||||
if ( $do_switch_locale ) {
|
||||
wpcf7_unload_textdomain( true );
|
||||
restore_previous_locale();
|
||||
wpcf7_load_textdomain( $previous_locale );
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
198
wp-content/plugins/contact-form-7/includes/mail-tag.php
Normal file
@ -0,0 +1,198 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class that represents a mail-tag.
|
||||
*/
|
||||
class WPCF7_MailTag {
|
||||
|
||||
private $tag;
|
||||
private $tagname = '';
|
||||
private $name = '';
|
||||
private $options = array();
|
||||
private $values = array();
|
||||
private $form_tag = null;
|
||||
|
||||
|
||||
/**
|
||||
* The constructor method.
|
||||
*/
|
||||
public function __construct( $tag, $tagname, $values ) {
|
||||
$this->tag = $tag;
|
||||
$this->name = $this->tagname = $tagname;
|
||||
|
||||
$this->options = array(
|
||||
'do_not_heat' => false,
|
||||
'format' => '',
|
||||
);
|
||||
|
||||
if ( ! empty( $values ) ) {
|
||||
preg_match_all( '/"[^"]*"|\'[^\']*\'/', $values, $matches );
|
||||
$this->values = wpcf7_strip_quote_deep( $matches[0] );
|
||||
}
|
||||
|
||||
if ( preg_match( '/^_raw_(.+)$/', $tagname, $matches ) ) {
|
||||
$this->name = trim( $matches[1] );
|
||||
$this->options['do_not_heat'] = true;
|
||||
}
|
||||
|
||||
if ( preg_match( '/^_format_(.+)$/', $tagname, $matches ) ) {
|
||||
$this->name = trim( $matches[1] );
|
||||
$this->options['format'] = $this->values[0];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the name part of this mail-tag.
|
||||
*/
|
||||
public function tag_name() {
|
||||
return $this->tagname;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the form field name corresponding to this mail-tag.
|
||||
*/
|
||||
public function field_name() {
|
||||
return strtr( $this->name, '.', '_' );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the value of the specified option.
|
||||
*/
|
||||
public function get_option( $option ) {
|
||||
return $this->options[$option];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the values part of this mail-tag.
|
||||
*/
|
||||
public function values() {
|
||||
return $this->values;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the WPCF7_FormTag object that corresponds to this mail-tag.
|
||||
*/
|
||||
public function corresponding_form_tag() {
|
||||
if ( $this->form_tag instanceof WPCF7_FormTag ) {
|
||||
return $this->form_tag;
|
||||
}
|
||||
|
||||
if ( $submission = WPCF7_Submission::get_instance() ) {
|
||||
$contact_form = $submission->get_contact_form();
|
||||
|
||||
$tags = $contact_form->scan_form_tags( array(
|
||||
'name' => $this->field_name(),
|
||||
'feature' => '! zero-controls-container',
|
||||
) );
|
||||
|
||||
if ( $tags ) {
|
||||
$this->form_tag = $tags[0];
|
||||
}
|
||||
}
|
||||
|
||||
return $this->form_tag;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
use Contactable\SWV;
|
||||
|
||||
/**
|
||||
* Mail-tag output calculator.
|
||||
*/
|
||||
class WPCF7_MailTag_OutputCalculator {
|
||||
|
||||
const email = 0b100;
|
||||
const text = 0b010;
|
||||
const blank = 0b001;
|
||||
|
||||
private $contact_form;
|
||||
|
||||
public function __construct( WPCF7_ContactForm $contact_form ) {
|
||||
$this->contact_form = $contact_form;
|
||||
}
|
||||
|
||||
public function calc_output( WPCF7_MailTag $mail_tag ) {
|
||||
return $this->calc_swv_result(
|
||||
$mail_tag,
|
||||
$this->contact_form->get_schema()
|
||||
);
|
||||
}
|
||||
|
||||
private function calc_swv_result( WPCF7_MailTag $mail_tag, SWV\Rule $rule ) {
|
||||
|
||||
if ( $rule instanceof SWV\AnyRule ) {
|
||||
$result = 0b000;
|
||||
|
||||
foreach ( $rule->rules() as $child_rule ) {
|
||||
$result |= $this->calc_swv_result( $mail_tag, $child_rule );
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
if ( $rule instanceof SWV\CompositeRule ) {
|
||||
$result = 0b111;
|
||||
|
||||
foreach ( $rule->rules() as $child_rule ) {
|
||||
$result &= $this->calc_swv_result( $mail_tag, $child_rule );
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
$field_prop = $rule->get_property( 'field' );
|
||||
|
||||
if ( empty( $field_prop ) or $field_prop !== $mail_tag->field_name() ) {
|
||||
return self::email | self::text | self::blank;
|
||||
}
|
||||
|
||||
if ( $rule instanceof SWV\RequiredRule ) {
|
||||
return ~ self::blank;
|
||||
}
|
||||
|
||||
if ( $rule instanceof SWV\EmailRule ) {
|
||||
return self::email | self::blank;
|
||||
}
|
||||
|
||||
if ( $rule instanceof SWV\EnumRule ) {
|
||||
$acceptable_values = (array) $rule->get_property( 'accept' );
|
||||
$acceptable_values = array_map( 'strval', $acceptable_values );
|
||||
$acceptable_values = array_filter( $acceptable_values );
|
||||
$acceptable_values = array_unique( $acceptable_values );
|
||||
|
||||
if ( ! $mail_tag->get_option( 'do_not_heat' ) ) {
|
||||
$pipes = $this->contact_form->get_pipes(
|
||||
$mail_tag->field_name()
|
||||
);
|
||||
|
||||
$acceptable_values = array_map(
|
||||
static function ( $val ) use ( $pipes ) {
|
||||
return $pipes->do_pipe( $val );
|
||||
},
|
||||
$acceptable_values
|
||||
);
|
||||
}
|
||||
|
||||
$email_values = array_filter(
|
||||
$acceptable_values,
|
||||
'wpcf7_is_mailbox_list'
|
||||
);
|
||||
|
||||
if ( count( $email_values ) === count( $acceptable_values ) ) {
|
||||
return self::email | self::blank;
|
||||
} else {
|
||||
return self::email | self::text | self::blank;
|
||||
}
|
||||
}
|
||||
|
||||
return self::email | self::text | self::blank;
|
||||
}
|
||||
|
||||
}
|
||||
632
wp-content/plugins/contact-form-7/includes/mail.php
Normal file
@ -0,0 +1,632 @@
|
||||
<?php
|
||||
|
||||
add_filter( 'wpcf7_mail_html_body', 'wpcf7_mail_html_body_autop', 10, 1 );
|
||||
|
||||
/**
|
||||
* Filter callback that applies auto-p to HTML email message body.
|
||||
*/
|
||||
function wpcf7_mail_html_body_autop( $body ) {
|
||||
if ( wpcf7_autop_or_not( array( 'for' => 'mail' ) ) ) {
|
||||
$body = wpcf7_autop( $body );
|
||||
}
|
||||
|
||||
return $body;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Class that represents an attempt to compose and send email.
|
||||
*/
|
||||
class WPCF7_Mail {
|
||||
|
||||
private static $current = null;
|
||||
|
||||
private $name = '';
|
||||
private $locale = '';
|
||||
private $template = array();
|
||||
private $component = '';
|
||||
private $use_html = false;
|
||||
private $exclude_blank = false;
|
||||
|
||||
|
||||
/**
|
||||
* Returns the singleton instance of this class.
|
||||
*/
|
||||
public static function get_current() {
|
||||
return self::$current;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the name of the email template currently processed.
|
||||
*
|
||||
* Expected output: 'mail' or 'mail_2'
|
||||
*/
|
||||
public static function get_current_template_name() {
|
||||
$current = self::get_current();
|
||||
|
||||
if ( $current instanceof self ) {
|
||||
return $current->get_template_name();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the name of the email template component currently processed.
|
||||
*
|
||||
* Expected output: 'recipient', 'sender', 'subject',
|
||||
* 'additional_headers', 'body', or 'attachments'
|
||||
*/
|
||||
public static function get_current_component_name() {
|
||||
$current = self::get_current();
|
||||
|
||||
if ( $current instanceof self ) {
|
||||
return $current->get_component_name();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Composes and sends email based on the specified template.
|
||||
*
|
||||
* @param array $template Array of email template.
|
||||
* @param string $name Optional name of the template, such as
|
||||
* 'mail' or 'mail_2'. Default empty string.
|
||||
* @return bool Whether the email was sent successfully.
|
||||
*/
|
||||
public static function send( $template, $name = '' ) {
|
||||
self::$current = new self( $name, $template );
|
||||
return self::$current->compose();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The constructor method.
|
||||
*
|
||||
* @param string $name The name of the email template.
|
||||
* Such as 'mail' or 'mail_2'.
|
||||
* @param array $template Array of email template.
|
||||
*/
|
||||
private function __construct( $name, $template ) {
|
||||
$this->name = trim( $name );
|
||||
$this->use_html = ! empty( $template['use_html'] );
|
||||
$this->exclude_blank = ! empty( $template['exclude_blank'] );
|
||||
|
||||
$this->template = wp_parse_args( $template, array(
|
||||
'subject' => '',
|
||||
'sender' => '',
|
||||
'body' => '',
|
||||
'recipient' => '',
|
||||
'additional_headers' => '',
|
||||
'attachments' => '',
|
||||
) );
|
||||
|
||||
if ( $submission = WPCF7_Submission::get_instance() ) {
|
||||
$contact_form = $submission->get_contact_form();
|
||||
$this->locale = $contact_form->locale();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the name of the email template.
|
||||
*/
|
||||
public function name() {
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the name of the email template. A wrapper method of name().
|
||||
*/
|
||||
public function get_template_name() {
|
||||
return $this->name();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the name of the email template component currently processed.
|
||||
*/
|
||||
public function get_component_name() {
|
||||
return $this->component;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves a component from the email template.
|
||||
*
|
||||
* @param string $component The name of the component.
|
||||
* @param bool $replace_tags Whether to replace mail-tags
|
||||
* within the component.
|
||||
* @return string The text representation of the email component.
|
||||
*/
|
||||
public function get( $component, $replace_tags = false ) {
|
||||
$this->component = $component;
|
||||
|
||||
$use_html = ( $this->use_html && 'body' === $component );
|
||||
$exclude_blank = ( $this->exclude_blank && 'body' === $component );
|
||||
|
||||
$template = $this->template;
|
||||
$component = isset( $template[$component] ) ? $template[$component] : '';
|
||||
|
||||
if ( $replace_tags ) {
|
||||
$component = $this->replace_tags( $component, array(
|
||||
'html' => $use_html,
|
||||
'exclude_blank' => $exclude_blank,
|
||||
) );
|
||||
|
||||
if ( $use_html ) {
|
||||
// Convert <example@example.com> to <example@example.com>.
|
||||
$component = preg_replace_callback(
|
||||
'/<(.*?)>/',
|
||||
static function ( $matches ) {
|
||||
if ( is_email( $matches[1] ) ) {
|
||||
return sprintf( '<%s>', $matches[1] );
|
||||
} else {
|
||||
return $matches[0];
|
||||
}
|
||||
},
|
||||
$component
|
||||
);
|
||||
|
||||
if ( ! preg_match( '%<html[>\s].*</html>%is', $component ) ) {
|
||||
$component = $this->htmlize( $component );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->component = '';
|
||||
|
||||
return $component;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates HTML message body by adding the header and footer.
|
||||
*
|
||||
* @param string $body The body part of HTML.
|
||||
* @return string Formatted HTML.
|
||||
*/
|
||||
private function htmlize( $body ) {
|
||||
if ( $this->locale ) {
|
||||
$lang_atts = sprintf( ' %s',
|
||||
wpcf7_format_atts( array(
|
||||
'dir' => wpcf7_is_rtl( $this->locale ) ? 'rtl' : 'ltr',
|
||||
'lang' => str_replace( '_', '-', $this->locale ),
|
||||
) )
|
||||
);
|
||||
} else {
|
||||
$lang_atts = '';
|
||||
}
|
||||
|
||||
$header = apply_filters( 'wpcf7_mail_html_header',
|
||||
'<!doctype html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml"' . $lang_atts . '>
|
||||
<head>
|
||||
<title>' . esc_html( $this->get( 'subject', true ) ) . '</title>
|
||||
</head>
|
||||
<body>
|
||||
',
|
||||
$this
|
||||
);
|
||||
|
||||
$body = apply_filters( 'wpcf7_mail_html_body', $body, $this );
|
||||
|
||||
$footer = apply_filters( 'wpcf7_mail_html_footer',
|
||||
'</body>
|
||||
</html>',
|
||||
$this
|
||||
);
|
||||
|
||||
return $header . $body . $footer;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Composes an email message and attempts to send it.
|
||||
*
|
||||
* @param bool $send Whether to attempt to send email. Default true.
|
||||
*/
|
||||
private function compose( $send = true ) {
|
||||
$components = array(
|
||||
'subject' => $this->get( 'subject', true ),
|
||||
'sender' => $this->get( 'sender', true ),
|
||||
'body' => $this->get( 'body', true ),
|
||||
'recipient' => $this->get( 'recipient', true ),
|
||||
'additional_headers' => $this->get( 'additional_headers', true ),
|
||||
'attachments' => $this->attachments(),
|
||||
);
|
||||
|
||||
$components = apply_filters( 'wpcf7_mail_components',
|
||||
$components, wpcf7_get_current_contact_form(), $this
|
||||
);
|
||||
|
||||
if ( ! $send ) {
|
||||
return $components;
|
||||
}
|
||||
|
||||
$subject = wpcf7_strip_newline( $components['subject'] );
|
||||
$sender = wpcf7_strip_newline( $components['sender'] );
|
||||
$recipient = wpcf7_strip_newline( $components['recipient'] );
|
||||
$body = $components['body'];
|
||||
$additional_headers = trim( $components['additional_headers'] );
|
||||
|
||||
$headers = "From: $sender\n";
|
||||
|
||||
if ( $this->use_html ) {
|
||||
$headers .= "Content-Type: text/html\n";
|
||||
$headers .= "X-WPCF7-Content-Type: text/html\n";
|
||||
} else {
|
||||
$headers .= "X-WPCF7-Content-Type: text/plain\n";
|
||||
}
|
||||
|
||||
if ( $additional_headers ) {
|
||||
$headers .= $additional_headers . "\n";
|
||||
}
|
||||
|
||||
$attachments = array_filter(
|
||||
(array) $components['attachments'],
|
||||
function ( $attachment ) {
|
||||
$path = path_join( WP_CONTENT_DIR, $attachment );
|
||||
|
||||
if ( ! wpcf7_is_file_path_in_content_dir( $path ) ) {
|
||||
wp_trigger_error(
|
||||
'',
|
||||
sprintf(
|
||||
/* translators: %s: Attachment file path. */
|
||||
__( 'Failed to attach a file. %s is not in the allowed directory.', 'contact-form-7' ),
|
||||
$path
|
||||
),
|
||||
E_USER_NOTICE
|
||||
);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! is_readable( $path ) or ! is_file( $path ) ) {
|
||||
wp_trigger_error(
|
||||
'',
|
||||
sprintf(
|
||||
/* translators: %s: Attachment file path. */
|
||||
__( 'Failed to attach a file. %s is not a readable file.', 'contact-form-7' ),
|
||||
$path
|
||||
),
|
||||
E_USER_NOTICE
|
||||
);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static $total_size = array();
|
||||
|
||||
if ( ! isset( $total_size[$this->name] ) ) {
|
||||
$total_size[$this->name] = 0;
|
||||
}
|
||||
|
||||
$file_size = (int) @filesize( $path );
|
||||
|
||||
if ( 25 * MB_IN_BYTES < $total_size[$this->name] + $file_size ) {
|
||||
wp_trigger_error(
|
||||
'',
|
||||
__( 'Failed to attach a file. The total file size exceeds the limit of 25 megabytes.', 'contact-form-7' ),
|
||||
E_USER_NOTICE
|
||||
);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$total_size[$this->name] += $file_size;
|
||||
|
||||
return true;
|
||||
}
|
||||
);
|
||||
|
||||
return wp_mail( $recipient, $subject, $body, $headers, $attachments );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Replaces mail-tags within the given text.
|
||||
*/
|
||||
public function replace_tags( $content, $options = '' ) {
|
||||
if ( true === $options ) {
|
||||
$options = array( 'html' => true );
|
||||
}
|
||||
|
||||
$options = wp_parse_args( $options, array(
|
||||
'html' => false,
|
||||
'exclude_blank' => false,
|
||||
) );
|
||||
|
||||
return wpcf7_mail_replace_tags( $content, $options );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates an array of attachments based on uploaded files and local files.
|
||||
*/
|
||||
private function attachments( $template = null ) {
|
||||
if ( ! $template ) {
|
||||
$template = $this->get( 'attachments' );
|
||||
}
|
||||
|
||||
$attachments = array();
|
||||
|
||||
if ( $submission = WPCF7_Submission::get_instance() ) {
|
||||
$uploaded_files = $submission->uploaded_files();
|
||||
|
||||
foreach ( (array) $uploaded_files as $name => $paths ) {
|
||||
if ( false !== strpos( $template, "[{$name}]" ) ) {
|
||||
$attachments = array_merge( $attachments, (array) $paths );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ( explode( "\n", $template ) as $line ) {
|
||||
$line = trim( $line );
|
||||
|
||||
if ( '' === $line or '[' === substr( $line, 0, 1 ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$attachments[] = path_join( WP_CONTENT_DIR, $line );
|
||||
}
|
||||
|
||||
if ( $submission = WPCF7_Submission::get_instance() ) {
|
||||
$attachments = array_merge(
|
||||
$attachments,
|
||||
(array) $submission->extra_attachments( $this->name )
|
||||
);
|
||||
}
|
||||
|
||||
return $attachments;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Replaces all mail-tags within the given text content.
|
||||
*
|
||||
* @param string $content Text including mail-tags.
|
||||
* @param string|array $options Optional. Output options.
|
||||
* @return string Result of replacement.
|
||||
*/
|
||||
function wpcf7_mail_replace_tags( $content, $options = '' ) {
|
||||
$options = wp_parse_args( $options, array(
|
||||
'html' => false,
|
||||
'exclude_blank' => false,
|
||||
) );
|
||||
|
||||
if ( is_array( $content ) ) {
|
||||
foreach ( $content as $key => $value ) {
|
||||
$content[$key] = wpcf7_mail_replace_tags( $value, $options );
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
$content = explode( "\n", $content );
|
||||
|
||||
foreach ( $content as $num => $line ) {
|
||||
$line = new WPCF7_MailTaggedText( $line, $options );
|
||||
$replaced = $line->replace_tags();
|
||||
|
||||
if ( $options['exclude_blank'] ) {
|
||||
$replaced_tags = $line->get_replaced_tags();
|
||||
|
||||
if (
|
||||
empty( $replaced_tags ) or
|
||||
array_filter( $replaced_tags, 'strlen' )
|
||||
) {
|
||||
$content[$num] = $replaced;
|
||||
} else {
|
||||
unset( $content[$num] ); // Remove a line.
|
||||
}
|
||||
} else {
|
||||
$content[$num] = $replaced;
|
||||
}
|
||||
}
|
||||
|
||||
$content = implode( "\n", $content );
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
|
||||
add_action( 'phpmailer_init', 'wpcf7_phpmailer_init', 10, 1 );
|
||||
|
||||
/**
|
||||
* Adds custom properties to the PHPMailer object.
|
||||
*/
|
||||
function wpcf7_phpmailer_init( $phpmailer ) {
|
||||
$custom_headers = $phpmailer->getCustomHeaders();
|
||||
$phpmailer->clearCustomHeaders();
|
||||
$wpcf7_content_type = false;
|
||||
|
||||
foreach ( (array) $custom_headers as $custom_header ) {
|
||||
$name = $custom_header[0];
|
||||
$value = $custom_header[1];
|
||||
|
||||
if ( 'X-WPCF7-Content-Type' === $name ) {
|
||||
$wpcf7_content_type = trim( $value );
|
||||
} else {
|
||||
$phpmailer->addCustomHeader( $name, $value );
|
||||
}
|
||||
}
|
||||
|
||||
if ( 'text/html' === $wpcf7_content_type ) {
|
||||
$phpmailer->msgHTML( $phpmailer->Body );
|
||||
} elseif ( 'text/plain' === $wpcf7_content_type ) {
|
||||
$phpmailer->AltBody = '';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Class that represents a single-line text including mail-tags.
|
||||
*/
|
||||
class WPCF7_MailTaggedText {
|
||||
|
||||
private $html = false;
|
||||
private $callback = null;
|
||||
private $content = '';
|
||||
private $replaced_tags = array();
|
||||
|
||||
|
||||
/**
|
||||
* The constructor method.
|
||||
*/
|
||||
public function __construct( $content, $options = '' ) {
|
||||
$options = wp_parse_args( $options, array(
|
||||
'html' => false,
|
||||
'callback' => null,
|
||||
) );
|
||||
|
||||
$this->html = (bool) $options['html'];
|
||||
|
||||
if (
|
||||
null !== $options['callback'] and
|
||||
is_callable( $options['callback'] )
|
||||
) {
|
||||
$this->callback = $options['callback'];
|
||||
} elseif ( $this->html ) {
|
||||
$this->callback = array( $this, 'replace_tags_callback_html' );
|
||||
} else {
|
||||
$this->callback = array( $this, 'replace_tags_callback' );
|
||||
}
|
||||
|
||||
$this->content = $content;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves mail-tags that have been replaced by this instance.
|
||||
*
|
||||
* @return array List of mail-tags replaced.
|
||||
*/
|
||||
public function get_replaced_tags() {
|
||||
return $this->replaced_tags;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Replaces mail-tags based on regexp.
|
||||
*/
|
||||
public function replace_tags() {
|
||||
$regex = '/(\[?)\[[\t ]*'
|
||||
. '([a-zA-Z_][0-9a-zA-Z:._-]*)' // [2] = name
|
||||
. '((?:[\t ]+"[^"]*"|[\t ]+\'[^\']*\')*)' // [3] = values
|
||||
. '[\t ]*\](\]?)/';
|
||||
|
||||
return preg_replace_callback( $regex, $this->callback, $this->content );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Callback function for replacement. For HTML message body.
|
||||
*/
|
||||
private function replace_tags_callback_html( $matches ) {
|
||||
return $this->replace_tags_callback( $matches, true );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Callback function for replacement.
|
||||
*/
|
||||
private function replace_tags_callback( $matches, $html = false ) {
|
||||
// allow [[foo]] syntax for escaping a tag
|
||||
if ( '[' === $matches[1] and ']' === $matches[4] ) {
|
||||
return substr( $matches[0], 1, -1 );
|
||||
}
|
||||
|
||||
$tag = $matches[0];
|
||||
$tagname = $matches[2];
|
||||
$values = $matches[3];
|
||||
|
||||
$mail_tag = new WPCF7_MailTag( $tag, $tagname, $values );
|
||||
$field_name = $mail_tag->field_name();
|
||||
|
||||
$submission = WPCF7_Submission::get_instance();
|
||||
$submitted = $submission
|
||||
? $submission->get_posted_data( $field_name )
|
||||
: null;
|
||||
|
||||
if ( $mail_tag->get_option( 'do_not_heat' ) ) {
|
||||
$submitted = wpcf7_superglobal_post( $field_name );
|
||||
}
|
||||
|
||||
$replaced = $submitted;
|
||||
|
||||
if ( null !== $replaced ) {
|
||||
if ( $format = $mail_tag->get_option( 'format' ) ) {
|
||||
$replaced = $this->format( $replaced, $format );
|
||||
}
|
||||
|
||||
$separator = ( 'body' === WPCF7_Mail::get_current_component_name() )
|
||||
? wp_get_list_item_separator()
|
||||
: ', ';
|
||||
|
||||
$replaced = wpcf7_flat_join( $replaced, array(
|
||||
'separator' => $separator,
|
||||
) );
|
||||
|
||||
if ( $html ) {
|
||||
$replaced = esc_html( $replaced );
|
||||
$replaced = wptexturize( $replaced );
|
||||
}
|
||||
}
|
||||
|
||||
if ( $form_tag = $mail_tag->corresponding_form_tag() ) {
|
||||
$type = $form_tag->type;
|
||||
|
||||
$replaced = apply_filters(
|
||||
"wpcf7_mail_tag_replaced_{$type}", $replaced,
|
||||
$submitted, $html, $mail_tag
|
||||
);
|
||||
}
|
||||
|
||||
$replaced = apply_filters(
|
||||
'wpcf7_mail_tag_replaced', $replaced,
|
||||
$submitted, $html, $mail_tag
|
||||
);
|
||||
|
||||
if ( null !== $replaced ) {
|
||||
$replaced = trim( $replaced );
|
||||
|
||||
$this->replaced_tags[$tag] = $replaced;
|
||||
return $replaced;
|
||||
}
|
||||
|
||||
$special = apply_filters( 'wpcf7_special_mail_tags', null,
|
||||
$mail_tag->tag_name(), $html, $mail_tag
|
||||
);
|
||||
|
||||
if ( null !== $special ) {
|
||||
$this->replaced_tags[$tag] = $special;
|
||||
return $special;
|
||||
}
|
||||
|
||||
return $tag;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Formats string based on the formatting option in the form-tag.
|
||||
*/
|
||||
public function format( $original, $format ) {
|
||||
$original = (array) $original;
|
||||
|
||||
foreach ( $original as $key => $value ) {
|
||||
if ( preg_match( '/^[0-9]{4}-[0-9]{2}-[0-9]{2}$/', $value ) ) {
|
||||
$datetime = date_create( $value, wp_timezone() );
|
||||
|
||||
if ( false !== $datetime ) {
|
||||
$original[$key] = wp_date( $format, $datetime->getTimestamp() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $original;
|
||||
}
|
||||
|
||||
}
|
||||
149
wp-content/plugins/contact-form-7/includes/pipe.php
Normal file
@ -0,0 +1,149 @@
|
||||
<?php
|
||||
/**
|
||||
* 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 = wpcf7_strip_whitespaces( $text );
|
||||
} else {
|
||||
$this->before = wpcf7_strip_whitespaces( substr( $text, 0, $pipe_pos ) );
|
||||
$this->after = wpcf7_strip_whitespaces( substr( $text, $pipe_pos + 1 ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Class representing a list of pipes.
|
||||
*/
|
||||
class WPCF7_Pipes {
|
||||
|
||||
private $pipes = array();
|
||||
|
||||
public function __construct( $texts = null ) {
|
||||
foreach ( (array) $texts as $text ) {
|
||||
$this->add_pipe( $text );
|
||||
}
|
||||
}
|
||||
|
||||
private function add_pipe( $text ) {
|
||||
$pipe = new WPCF7_Pipe( $text );
|
||||
$this->pipes[] = $pipe;
|
||||
}
|
||||
|
||||
public function merge( self $another ) {
|
||||
$this->pipes = array_merge( $this->pipes, $another->pipes );
|
||||
}
|
||||
|
||||
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
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Trait for classes that hold cross-tag WPCF7_Pipes object.
|
||||
*/
|
||||
trait WPCF7_PipesHolder {
|
||||
|
||||
protected $pipes;
|
||||
|
||||
public function get_pipes( $field_name ) {
|
||||
if ( isset( $this->pipes[$field_name] ) ) {
|
||||
return $this->pipes[$field_name];
|
||||
}
|
||||
|
||||
$result = new WPCF7_Pipes();
|
||||
|
||||
$tags = $this->scan_form_tags( array(
|
||||
'name' => $field_name,
|
||||
) );
|
||||
|
||||
foreach ( $tags as $tag ) {
|
||||
if ( $tag->pipes instanceof WPCF7_Pipes ) {
|
||||
$result->merge( $tag->pipes );
|
||||
}
|
||||
}
|
||||
|
||||
return $this->pipes[$field_name] = $result;
|
||||
}
|
||||
|
||||
public function scan_form_tags() {
|
||||
return array();
|
||||
}
|
||||
|
||||
}
|
||||
20
wp-content/plugins/contact-form-7/includes/pocket-holder.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
}
|
||||
524
wp-content/plugins/contact-form-7/includes/rest-api.php
Normal file
@ -0,0 +1,524 @@
|
||||
<?php
|
||||
|
||||
add_action(
|
||||
'rest_api_init',
|
||||
static function () {
|
||||
$controller = new WPCF7_REST_Controller();
|
||||
$controller->register_routes();
|
||||
},
|
||||
10, 0
|
||||
);
|
||||
|
||||
|
||||
class WPCF7_REST_Controller {
|
||||
|
||||
const route_namespace = 'contact-form-7/v1';
|
||||
|
||||
public function register_routes() {
|
||||
|
||||
register_rest_route( self::route_namespace,
|
||||
'/contact-forms',
|
||||
array(
|
||||
array(
|
||||
'methods' => WP_REST_Server::READABLE,
|
||||
'callback' => array( $this, 'get_contact_forms' ),
|
||||
'permission_callback' => static function () {
|
||||
if ( current_user_can( 'wpcf7_read_contact_forms' ) ) {
|
||||
return true;
|
||||
} else {
|
||||
return new WP_Error( 'wpcf7_forbidden',
|
||||
__( 'You are not allowed to access contact forms.', 'contact-form-7' ),
|
||||
array( 'status' => 403 )
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
array(
|
||||
'methods' => WP_REST_Server::CREATABLE,
|
||||
'callback' => array( $this, 'create_contact_form' ),
|
||||
'permission_callback' => static function () {
|
||||
if ( current_user_can( 'wpcf7_edit_contact_forms' ) ) {
|
||||
return true;
|
||||
} else {
|
||||
return new WP_Error( 'wpcf7_forbidden',
|
||||
__( 'You are not allowed to create a contact form.', 'contact-form-7' ),
|
||||
array( 'status' => 403 )
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
register_rest_route( self::route_namespace,
|
||||
'/contact-forms/(?P<id>\d+)',
|
||||
array(
|
||||
array(
|
||||
'methods' => WP_REST_Server::READABLE,
|
||||
'callback' => array( $this, 'get_contact_form' ),
|
||||
'permission_callback' => static function ( WP_REST_Request $request ) {
|
||||
$id = (int) $request->get_param( 'id' );
|
||||
|
||||
if ( current_user_can( 'wpcf7_edit_contact_form', $id ) ) {
|
||||
return true;
|
||||
} else {
|
||||
return new WP_Error( 'wpcf7_forbidden',
|
||||
__( 'You are not allowed to access the requested contact form.', 'contact-form-7' ),
|
||||
array( 'status' => 403 )
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
array(
|
||||
'methods' => WP_REST_Server::EDITABLE,
|
||||
'callback' => array( $this, 'update_contact_form' ),
|
||||
'permission_callback' => static function ( WP_REST_Request $request ) {
|
||||
$id = (int) $request->get_param( 'id' );
|
||||
|
||||
if ( current_user_can( 'wpcf7_edit_contact_form', $id ) ) {
|
||||
return true;
|
||||
} else {
|
||||
return new WP_Error( 'wpcf7_forbidden',
|
||||
__( 'You are not allowed to access the requested contact form.', 'contact-form-7' ),
|
||||
array( 'status' => 403 )
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
array(
|
||||
'methods' => WP_REST_Server::DELETABLE,
|
||||
'callback' => array( $this, 'delete_contact_form' ),
|
||||
'permission_callback' => static function ( WP_REST_Request $request ) {
|
||||
$id = (int) $request->get_param( 'id' );
|
||||
|
||||
if ( current_user_can( 'wpcf7_delete_contact_form', $id ) ) {
|
||||
return true;
|
||||
} else {
|
||||
return new WP_Error( 'wpcf7_forbidden',
|
||||
__( 'You are not allowed to access the requested contact form.', 'contact-form-7' ),
|
||||
array( 'status' => 403 )
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
register_rest_route( self::route_namespace,
|
||||
'/contact-forms/(?P<id>\d+)/feedback',
|
||||
array(
|
||||
array(
|
||||
'methods' => WP_REST_Server::CREATABLE,
|
||||
'callback' => array( $this, 'create_feedback' ),
|
||||
'permission_callback' => '__return_true',
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
register_rest_route( self::route_namespace,
|
||||
'/contact-forms/(?P<id>\d+)/feedback/schema',
|
||||
array(
|
||||
array(
|
||||
'methods' => WP_REST_Server::READABLE,
|
||||
'callback' => array( $this, 'get_schema' ),
|
||||
'permission_callback' => '__return_true',
|
||||
),
|
||||
'schema' => 'wpcf7_swv_get_meta_schema',
|
||||
)
|
||||
);
|
||||
|
||||
register_rest_route( self::route_namespace,
|
||||
'/contact-forms/(?P<id>\d+)/refill',
|
||||
array(
|
||||
array(
|
||||
'methods' => WP_REST_Server::READABLE,
|
||||
'callback' => array( $this, 'get_refill' ),
|
||||
'permission_callback' => '__return_true',
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public function get_contact_forms( WP_REST_Request $request ) {
|
||||
$args = array();
|
||||
|
||||
$per_page = $request->get_param( 'per_page' );
|
||||
|
||||
if ( null !== $per_page ) {
|
||||
$args['posts_per_page'] = (int) $per_page;
|
||||
}
|
||||
|
||||
$offset = $request->get_param( 'offset' );
|
||||
|
||||
if ( null !== $offset ) {
|
||||
$args['offset'] = (int) $offset;
|
||||
}
|
||||
|
||||
$order = $request->get_param( 'order' );
|
||||
|
||||
if ( null !== $order ) {
|
||||
$args['order'] = (string) $order;
|
||||
}
|
||||
|
||||
$orderby = $request->get_param( 'orderby' );
|
||||
|
||||
if ( null !== $orderby ) {
|
||||
$args['orderby'] = (string) $orderby;
|
||||
}
|
||||
|
||||
$search = $request->get_param( 'search' );
|
||||
|
||||
if ( null !== $search ) {
|
||||
$args['s'] = (string) $search;
|
||||
}
|
||||
|
||||
$items = WPCF7_ContactForm::find( $args );
|
||||
|
||||
$response = array();
|
||||
|
||||
foreach ( $items as $item ) {
|
||||
$response[] = array(
|
||||
'id' => $item->id(),
|
||||
'hash' => $item->hash(),
|
||||
'slug' => $item->name(),
|
||||
'title' => $item->title(),
|
||||
'locale' => $item->locale(),
|
||||
);
|
||||
}
|
||||
|
||||
return rest_ensure_response( $response );
|
||||
}
|
||||
|
||||
public function create_contact_form( WP_REST_Request $request ) {
|
||||
$id = (int) $request->get_param( 'id' );
|
||||
|
||||
if ( $id ) {
|
||||
return new WP_Error( 'wpcf7_post_exists',
|
||||
__( 'Cannot create existing contact form.', 'contact-form-7' ),
|
||||
array( 'status' => 400 )
|
||||
);
|
||||
}
|
||||
|
||||
$args = $request->get_params();
|
||||
$args['id'] = -1; // Create
|
||||
$context = $request->get_param( 'context' );
|
||||
$item = wpcf7_save_contact_form( $args, $context );
|
||||
|
||||
if ( ! $item ) {
|
||||
return new WP_Error( 'wpcf7_cannot_save',
|
||||
__( 'There was an error saving the contact form.', 'contact-form-7' ),
|
||||
array( 'status' => 500 )
|
||||
);
|
||||
}
|
||||
|
||||
$response = array(
|
||||
'id' => $item->id(),
|
||||
'slug' => $item->name(),
|
||||
'title' => $item->title(),
|
||||
'locale' => $item->locale(),
|
||||
'properties' => $this->get_properties( $item ),
|
||||
'config_errors' => array(),
|
||||
);
|
||||
|
||||
if ( wpcf7_validate_configuration() ) {
|
||||
$config_validator = new WPCF7_ConfigValidator( $item );
|
||||
$config_validator->validate();
|
||||
|
||||
$response['config_errors'] = $config_validator->collect_error_messages(
|
||||
array( 'decodes_html_entities' => true )
|
||||
);
|
||||
|
||||
if ( 'save' === $context ) {
|
||||
$config_validator->save();
|
||||
}
|
||||
}
|
||||
|
||||
return rest_ensure_response( $response );
|
||||
}
|
||||
|
||||
public function get_contact_form( WP_REST_Request $request ) {
|
||||
$id = (int) $request->get_param( 'id' );
|
||||
$item = wpcf7_contact_form( $id );
|
||||
|
||||
if ( ! $item ) {
|
||||
return new WP_Error( 'wpcf7_not_found',
|
||||
__( 'The requested contact form was not found.', 'contact-form-7' ),
|
||||
array( 'status' => 404 )
|
||||
);
|
||||
}
|
||||
|
||||
$response = array(
|
||||
'id' => $item->id(),
|
||||
'slug' => $item->name(),
|
||||
'title' => $item->title(),
|
||||
'locale' => $item->locale(),
|
||||
'properties' => $this->get_properties( $item ),
|
||||
);
|
||||
|
||||
return rest_ensure_response( $response );
|
||||
}
|
||||
|
||||
public function update_contact_form( WP_REST_Request $request ) {
|
||||
$id = (int) $request->get_param( 'id' );
|
||||
$item = wpcf7_contact_form( $id );
|
||||
|
||||
if ( ! $item ) {
|
||||
return new WP_Error( 'wpcf7_not_found',
|
||||
__( 'The requested contact form was not found.', 'contact-form-7' ),
|
||||
array( 'status' => 404 )
|
||||
);
|
||||
}
|
||||
|
||||
$args = $request->get_params();
|
||||
$context = $request->get_param( 'context' );
|
||||
$item = wpcf7_save_contact_form( $args, $context );
|
||||
|
||||
if ( ! $item ) {
|
||||
return new WP_Error( 'wpcf7_cannot_save',
|
||||
__( 'There was an error saving the contact form.', 'contact-form-7' ),
|
||||
array( 'status' => 500 )
|
||||
);
|
||||
}
|
||||
|
||||
$response = array(
|
||||
'id' => $item->id(),
|
||||
'slug' => $item->name(),
|
||||
'title' => $item->title(),
|
||||
'locale' => $item->locale(),
|
||||
'properties' => $this->get_properties( $item ),
|
||||
'config_errors' => array(),
|
||||
);
|
||||
|
||||
if ( wpcf7_validate_configuration() ) {
|
||||
$config_validator = new WPCF7_ConfigValidator( $item );
|
||||
$config_validator->validate();
|
||||
|
||||
$response['config_errors'] = $config_validator->collect_error_messages(
|
||||
array( 'decodes_html_entities' => true )
|
||||
);
|
||||
|
||||
if ( 'save' === $context ) {
|
||||
$config_validator->save();
|
||||
}
|
||||
}
|
||||
|
||||
return rest_ensure_response( $response );
|
||||
}
|
||||
|
||||
public function delete_contact_form( WP_REST_Request $request ) {
|
||||
$id = (int) $request->get_param( 'id' );
|
||||
$item = wpcf7_contact_form( $id );
|
||||
|
||||
if ( ! $item ) {
|
||||
return new WP_Error( 'wpcf7_not_found',
|
||||
__( 'The requested contact form was not found.', 'contact-form-7' ),
|
||||
array( 'status' => 404 )
|
||||
);
|
||||
}
|
||||
|
||||
$result = $item->delete();
|
||||
|
||||
if ( ! $result ) {
|
||||
return new WP_Error( 'wpcf7_cannot_delete',
|
||||
__( 'There was an error deleting the contact form.', 'contact-form-7' ),
|
||||
array( 'status' => 500 )
|
||||
);
|
||||
}
|
||||
|
||||
$response = array( 'deleted' => true );
|
||||
|
||||
return rest_ensure_response( $response );
|
||||
}
|
||||
|
||||
public function create_feedback( WP_REST_Request $request ) {
|
||||
$content_type = $request->get_header( 'Content-Type' ) ?? '';
|
||||
|
||||
if ( ! str_starts_with( $content_type, 'multipart/form-data' ) ) {
|
||||
return new WP_Error( 'wpcf7_unsupported_media_type',
|
||||
__( 'The request payload format is not supported.', 'contact-form-7' ),
|
||||
array( 'status' => 415 )
|
||||
);
|
||||
}
|
||||
|
||||
$url_params = $request->get_url_params();
|
||||
|
||||
$item = null;
|
||||
|
||||
if ( ! empty( $url_params['id'] ) ) {
|
||||
$item = wpcf7_contact_form( $url_params['id'] );
|
||||
}
|
||||
|
||||
if ( ! $item ) {
|
||||
return new WP_Error( 'wpcf7_not_found',
|
||||
__( 'The requested contact form was not found.', 'contact-form-7' ),
|
||||
array( 'status' => 404 )
|
||||
);
|
||||
}
|
||||
|
||||
$unit_tag = wpcf7_sanitize_unit_tag(
|
||||
$request->get_param( '_wpcf7_unit_tag' )
|
||||
);
|
||||
|
||||
if ( empty( $unit_tag ) ) {
|
||||
return new WP_Error( 'wpcf7_unit_tag_not_found',
|
||||
__( 'There is no valid unit tag.', 'contact-form-7' ),
|
||||
array( 'status' => 400 )
|
||||
);
|
||||
}
|
||||
|
||||
$result = $item->submit();
|
||||
|
||||
$response = array_merge( $result, array(
|
||||
'into' => sprintf( '#%s', $unit_tag ),
|
||||
'invalid_fields' => array(),
|
||||
) );
|
||||
|
||||
if ( ! empty( $result['invalid_fields'] ) ) {
|
||||
$invalid_fields = array();
|
||||
|
||||
foreach ( (array) $result['invalid_fields'] as $name => $field ) {
|
||||
if ( ! wpcf7_is_name( $name ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$name = strtr( $name, '.', '_' );
|
||||
|
||||
$invalid_fields[] = array(
|
||||
'field' => $name,
|
||||
'message' => $field['reason'],
|
||||
'idref' => $field['idref'],
|
||||
'error_id' => sprintf(
|
||||
'%1$s-ve-%2$s',
|
||||
$unit_tag,
|
||||
$name
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
$response['invalid_fields'] = $invalid_fields;
|
||||
}
|
||||
|
||||
$response = wpcf7_apply_filters_deprecated(
|
||||
'wpcf7_ajax_json_echo',
|
||||
array( $response, $result ),
|
||||
'5.2',
|
||||
'wpcf7_feedback_response'
|
||||
);
|
||||
|
||||
$response = apply_filters( 'wpcf7_feedback_response', $response, $result );
|
||||
|
||||
return rest_ensure_response( $response );
|
||||
}
|
||||
|
||||
|
||||
public function get_schema( WP_REST_Request $request ) {
|
||||
$url_params = $request->get_url_params();
|
||||
|
||||
$item = null;
|
||||
|
||||
if ( ! empty( $url_params['id'] ) ) {
|
||||
$item = wpcf7_contact_form( $url_params['id'] );
|
||||
}
|
||||
|
||||
if ( ! $item ) {
|
||||
return new WP_Error( 'wpcf7_not_found',
|
||||
__( 'The requested contact form was not found.', 'contact-form-7' ),
|
||||
array( 'status' => 404 )
|
||||
);
|
||||
}
|
||||
|
||||
$schema = $item->get_schema();
|
||||
|
||||
$response = isset( $schema ) ? $schema->to_array() : array();
|
||||
|
||||
return rest_ensure_response( $response );
|
||||
}
|
||||
|
||||
|
||||
public function get_refill( WP_REST_Request $request ) {
|
||||
$id = (int) $request->get_param( 'id' );
|
||||
$item = wpcf7_contact_form( $id );
|
||||
|
||||
if ( ! $item ) {
|
||||
return new WP_Error( 'wpcf7_not_found',
|
||||
__( 'The requested contact form was not found.', 'contact-form-7' ),
|
||||
array( 'status' => 404 )
|
||||
);
|
||||
}
|
||||
|
||||
$response = wpcf7_apply_filters_deprecated(
|
||||
'wpcf7_ajax_onload',
|
||||
array( array() ),
|
||||
'5.2',
|
||||
'wpcf7_refill_response'
|
||||
);
|
||||
|
||||
$response = apply_filters( 'wpcf7_refill_response', array() );
|
||||
|
||||
return rest_ensure_response( $response );
|
||||
}
|
||||
|
||||
private function get_properties( WPCF7_ContactForm $contact_form ) {
|
||||
$properties = $contact_form->get_properties();
|
||||
|
||||
$properties['form'] = array(
|
||||
'content' => (string) $properties['form'],
|
||||
'fields' => array_map(
|
||||
static function ( WPCF7_FormTag $form_tag ) {
|
||||
return array(
|
||||
'type' => $form_tag->type,
|
||||
'basetype' => $form_tag->basetype,
|
||||
'name' => $form_tag->name,
|
||||
'options' => $form_tag->options,
|
||||
'raw_values' => $form_tag->raw_values,
|
||||
'labels' => $form_tag->labels,
|
||||
'values' => $form_tag->values,
|
||||
'pipes' => $form_tag->pipes instanceof WPCF7_Pipes
|
||||
? $form_tag->pipes->to_array()
|
||||
: $form_tag->pipes,
|
||||
'content' => $form_tag->content,
|
||||
);
|
||||
},
|
||||
$contact_form->scan_form_tags()
|
||||
),
|
||||
);
|
||||
|
||||
$properties['additional_settings'] = array(
|
||||
'content' => (string) $properties['additional_settings'],
|
||||
'settings' => array_filter( array_map(
|
||||
static function ( $setting ) {
|
||||
$pattern = '/^([a-zA-Z0-9_]+)[\t ]*:(.*)$/';
|
||||
|
||||
if ( preg_match( $pattern, $setting, $matches ) ) {
|
||||
$name = trim( $matches[1] );
|
||||
$value = trim( $matches[2] );
|
||||
|
||||
if ( in_array( $value, array( 'on', 'true' ), true ) ) {
|
||||
$value = true;
|
||||
} elseif ( in_array( $value, array( 'off', 'false' ), true ) ) {
|
||||
$value = false;
|
||||
}
|
||||
|
||||
return array( $name, $value );
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
explode( "\n", $properties['additional_settings'] )
|
||||
) ),
|
||||
);
|
||||
|
||||
return $properties;
|
||||
}
|
||||
|
||||
private function get_argument_schema() {
|
||||
return array(
|
||||
'id' => array(
|
||||
'description' => __( 'Unique identifier for the contact form.', 'contact-form-7' ),
|
||||
'type' => 'integer',
|
||||
'required' => true,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
108
wp-content/plugins/contact-form-7/includes/shortcodes.php
Normal file
@ -0,0 +1,108 @@
|
||||
<?php
|
||||
/**
|
||||
* All the functions and classes in this file are deprecated.
|
||||
* You should not use them. The functions and classes will be
|
||||
* removed in a later version.
|
||||
*/
|
||||
|
||||
function wpcf7_add_shortcode( $tag, $callback, $has_name = false ) {
|
||||
wpcf7_deprecated_function( __FUNCTION__, '4.6', 'wpcf7_add_form_tag' );
|
||||
|
||||
return wpcf7_add_form_tag( $tag, $callback, $has_name );
|
||||
}
|
||||
|
||||
function wpcf7_remove_shortcode( $tag ) {
|
||||
wpcf7_deprecated_function( __FUNCTION__, '4.6', 'wpcf7_remove_form_tag' );
|
||||
|
||||
return wpcf7_remove_form_tag( $tag );
|
||||
}
|
||||
|
||||
function wpcf7_do_shortcode( $content ) {
|
||||
wpcf7_deprecated_function( __FUNCTION__, '4.6',
|
||||
'wpcf7_replace_all_form_tags' );
|
||||
|
||||
return wpcf7_replace_all_form_tags( $content );
|
||||
}
|
||||
|
||||
function wpcf7_scan_shortcode( $cond = null ) {
|
||||
wpcf7_deprecated_function( __FUNCTION__, '4.6', 'wpcf7_scan_form_tags' );
|
||||
|
||||
return wpcf7_scan_form_tags( $cond );
|
||||
}
|
||||
|
||||
class WPCF7_ShortcodeManager {
|
||||
|
||||
private static $form_tags_manager;
|
||||
|
||||
private function __construct() {}
|
||||
|
||||
public static function get_instance() {
|
||||
wpcf7_deprecated_function( __METHOD__, '4.6',
|
||||
'WPCF7_FormTagsManager::get_instance'
|
||||
);
|
||||
|
||||
self::$form_tags_manager = WPCF7_FormTagsManager::get_instance();
|
||||
return new self();
|
||||
}
|
||||
|
||||
public function get_scanned_tags() {
|
||||
wpcf7_deprecated_function( __METHOD__, '4.6',
|
||||
'WPCF7_FormTagsManager::get_scanned_tags'
|
||||
);
|
||||
|
||||
return self::$form_tags_manager->get_scanned_tags();
|
||||
}
|
||||
|
||||
public function add_shortcode( $tag, $callback, $has_name = false ) {
|
||||
wpcf7_deprecated_function( __METHOD__, '4.6',
|
||||
'WPCF7_FormTagsManager::add'
|
||||
);
|
||||
|
||||
return self::$form_tags_manager->add( $tag, $callback, $has_name );
|
||||
}
|
||||
|
||||
public function remove_shortcode( $tag ) {
|
||||
wpcf7_deprecated_function( __METHOD__, '4.6',
|
||||
'WPCF7_FormTagsManager::remove'
|
||||
);
|
||||
|
||||
return self::$form_tags_manager->remove( $tag );
|
||||
}
|
||||
|
||||
public function normalize_shortcode( $content ) {
|
||||
wpcf7_deprecated_function( __METHOD__, '4.6',
|
||||
'WPCF7_FormTagsManager::normalize'
|
||||
);
|
||||
|
||||
return self::$form_tags_manager->normalize( $content );
|
||||
}
|
||||
|
||||
public function do_shortcode( $content, $exec = true ) {
|
||||
wpcf7_deprecated_function( __METHOD__, '4.6',
|
||||
'WPCF7_FormTagsManager::replace_all'
|
||||
);
|
||||
|
||||
if ( $exec ) {
|
||||
return self::$form_tags_manager->replace_all( $content );
|
||||
} else {
|
||||
return self::$form_tags_manager->scan( $content );
|
||||
}
|
||||
}
|
||||
|
||||
public function scan_shortcode( $content ) {
|
||||
wpcf7_deprecated_function( __METHOD__, '4.6',
|
||||
'WPCF7_FormTagsManager::scan'
|
||||
);
|
||||
|
||||
return self::$form_tags_manager->scan( $content );
|
||||
}
|
||||
}
|
||||
|
||||
class WPCF7_Shortcode extends WPCF7_FormTag {
|
||||
|
||||
public function __construct( $tag ) {
|
||||
wpcf7_deprecated_function( 'WPCF7_Shortcode', '4.6', 'WPCF7_FormTag' );
|
||||
|
||||
parent::__construct( $tag );
|
||||
}
|
||||
}
|
||||
271
wp-content/plugins/contact-form-7/includes/special-mail-tags.php
Normal file
@ -0,0 +1,271 @@
|
||||
<?php
|
||||
/**
|
||||
** Special Mail Tags
|
||||
** https://contactform7.com/special-mail-tags/
|
||||
**/
|
||||
|
||||
add_filter( 'wpcf7_special_mail_tags', 'wpcf7_special_mail_tag', 10, 4 );
|
||||
|
||||
/**
|
||||
* Returns output string of a special mail-tag.
|
||||
*
|
||||
* @param string $output The string to be output.
|
||||
* @param string $name The tag name of the special mail-tag.
|
||||
* @param bool $html Whether the mail-tag is used in an HTML content.
|
||||
* @param WPCF7_MailTag $mail_tag An object representation of the mail-tag.
|
||||
* @return string Output of the given special mail-tag.
|
||||
*/
|
||||
function wpcf7_special_mail_tag( $output, $name, $html, $mail_tag = null ) {
|
||||
if ( ! $mail_tag instanceof WPCF7_MailTag ) {
|
||||
wpcf7_doing_it_wrong(
|
||||
sprintf( '%s()', __FUNCTION__ ),
|
||||
__( 'The fourth parameter ($mail_tag) must be an instance of the WPCF7_MailTag class.', 'contact-form-7' ),
|
||||
'5.2.2'
|
||||
);
|
||||
}
|
||||
|
||||
$name = preg_replace( '/^wpcf7\./', '_', $name ); // for back-compat
|
||||
|
||||
$submission = WPCF7_Submission::get_instance();
|
||||
|
||||
if ( ! $submission ) {
|
||||
return $output;
|
||||
}
|
||||
|
||||
if ( '_remote_ip' === $name ) {
|
||||
if ( $remote_ip = $submission->get_meta( 'remote_ip' ) ) {
|
||||
return $remote_ip;
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
if ( '_user_agent' === $name ) {
|
||||
if ( $user_agent = $submission->get_meta( 'user_agent' ) ) {
|
||||
return $html ? esc_html( $user_agent ) : $user_agent;
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
if ( '_url' === $name ) {
|
||||
if ( $url = $submission->get_meta( 'url' ) ) {
|
||||
return $url;
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
if ( '_date' === $name or '_time' === $name ) {
|
||||
if ( $timestamp = $submission->get_meta( 'timestamp' ) ) {
|
||||
if ( '_date' === $name ) {
|
||||
return wp_date( get_option( 'date_format' ), $timestamp );
|
||||
}
|
||||
|
||||
if ( '_time' === $name ) {
|
||||
return wp_date( get_option( 'time_format' ), $timestamp );
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
if ( '_invalid_fields' === $name ) {
|
||||
return (string) count( $submission->get_invalid_fields() );
|
||||
}
|
||||
|
||||
if ( '_contact_form_title' === $name ) {
|
||||
$contact_form = $submission->get_contact_form();
|
||||
|
||||
return $html
|
||||
? esc_html( $contact_form->title() )
|
||||
: $contact_form->title();
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
|
||||
add_filter( 'wpcf7_special_mail_tags', 'wpcf7_post_related_smt', 10, 4 );
|
||||
|
||||
/**
|
||||
* Returns output string of a special mail-tag.
|
||||
*
|
||||
* @param string $output The string to be output.
|
||||
* @param string $name The tag name of the special mail-tag.
|
||||
* @param bool $html Whether the mail-tag is used in an HTML content.
|
||||
* @param WPCF7_MailTag $mail_tag An object representation of the mail-tag.
|
||||
* @return string Output of the given special mail-tag.
|
||||
*/
|
||||
function wpcf7_post_related_smt( $output, $name, $html, $mail_tag = null ) {
|
||||
if ( ! $mail_tag instanceof WPCF7_MailTag ) {
|
||||
wpcf7_doing_it_wrong(
|
||||
sprintf( '%s()', __FUNCTION__ ),
|
||||
__( 'The fourth parameter ($mail_tag) must be an instance of the WPCF7_MailTag class.', 'contact-form-7' ),
|
||||
'5.2.2'
|
||||
);
|
||||
}
|
||||
|
||||
if ( ! str_starts_with( $name, '_post_' ) ) {
|
||||
return $output;
|
||||
}
|
||||
|
||||
$submission = WPCF7_Submission::get_instance();
|
||||
|
||||
if ( ! $submission ) {
|
||||
return $output;
|
||||
}
|
||||
|
||||
$post_id = (int) $submission->get_meta( 'container_post_id' );
|
||||
|
||||
if ( ! $post_id or ! $post = get_post( $post_id ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if ( '_post_id' === $name ) {
|
||||
return (string) $post->ID;
|
||||
}
|
||||
|
||||
if ( '_post_name' === $name ) {
|
||||
return $post->post_name;
|
||||
}
|
||||
|
||||
if ( '_post_title' === $name ) {
|
||||
return $html ? esc_html( $post->post_title ) : $post->post_title;
|
||||
}
|
||||
|
||||
if ( '_post_url' === $name ) {
|
||||
return get_permalink( $post->ID );
|
||||
}
|
||||
|
||||
$user = new WP_User( $post->post_author );
|
||||
|
||||
if ( '_post_author' === $name ) {
|
||||
return $user->display_name;
|
||||
}
|
||||
|
||||
if ( '_post_author_email' === $name ) {
|
||||
return $user->user_email;
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
|
||||
add_filter( 'wpcf7_special_mail_tags', 'wpcf7_site_related_smt', 10, 4 );
|
||||
|
||||
/**
|
||||
* Returns output string of a special mail-tag.
|
||||
*
|
||||
* @param string $output The string to be output.
|
||||
* @param string $name The tag name of the special mail-tag.
|
||||
* @param bool $html Whether the mail-tag is used in an HTML content.
|
||||
* @param WPCF7_MailTag $mail_tag An object representation of the mail-tag.
|
||||
* @return string Output of the given special mail-tag.
|
||||
*/
|
||||
function wpcf7_site_related_smt( $output, $name, $html, $mail_tag = null ) {
|
||||
if ( ! $mail_tag instanceof WPCF7_MailTag ) {
|
||||
wpcf7_doing_it_wrong(
|
||||
sprintf( '%s()', __FUNCTION__ ),
|
||||
__( 'The fourth parameter ($mail_tag) must be an instance of the WPCF7_MailTag class.', 'contact-form-7' ),
|
||||
'5.2.2'
|
||||
);
|
||||
}
|
||||
|
||||
$filter = $html ? 'display' : 'raw';
|
||||
|
||||
if ( '_site_title' === $name ) {
|
||||
$output = get_bloginfo( 'name', $filter );
|
||||
|
||||
if ( ! $html ) {
|
||||
$output = wp_specialchars_decode( $output, ENT_QUOTES );
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
if ( '_site_description' === $name ) {
|
||||
$output = get_bloginfo( 'description', $filter );
|
||||
|
||||
if ( ! $html ) {
|
||||
$output = wp_specialchars_decode( $output, ENT_QUOTES );
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
if ( '_site_url' === $name ) {
|
||||
return get_bloginfo( 'url', $filter );
|
||||
}
|
||||
|
||||
if ( '_site_domain' === $name ) {
|
||||
$url = get_bloginfo( 'url', $filter );
|
||||
$host = wp_parse_url( $url, PHP_URL_HOST );
|
||||
|
||||
if ( null === $host ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if ( str_starts_with( $host, 'www.' ) ) {
|
||||
$host = substr( $host, 4 );
|
||||
}
|
||||
|
||||
return $host;
|
||||
}
|
||||
|
||||
if ( '_site_admin_email' === $name ) {
|
||||
return get_bloginfo( 'admin_email', $filter );
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
|
||||
add_filter( 'wpcf7_special_mail_tags', 'wpcf7_user_related_smt', 10, 4 );
|
||||
|
||||
/**
|
||||
* Returns output string of a special mail-tag.
|
||||
*
|
||||
* @param string $output The string to be output.
|
||||
* @param string $name The tag name of the special mail-tag.
|
||||
* @param bool $html Whether the mail-tag is used in an HTML content.
|
||||
* @param WPCF7_MailTag $mail_tag An object representation of the mail-tag.
|
||||
* @return string Output of the given special mail-tag.
|
||||
*/
|
||||
function wpcf7_user_related_smt( $output, $name, $html, $mail_tag = null ) {
|
||||
if ( ! $mail_tag instanceof WPCF7_MailTag ) {
|
||||
wpcf7_doing_it_wrong(
|
||||
sprintf( '%s()', __FUNCTION__ ),
|
||||
__( 'The fourth parameter ($mail_tag) must be an instance of the WPCF7_MailTag class.', 'contact-form-7' ),
|
||||
'5.2.2'
|
||||
);
|
||||
}
|
||||
|
||||
if ( ! str_starts_with( $name, '_user_' ) or '_user_agent' === $name ) {
|
||||
return $output;
|
||||
}
|
||||
|
||||
$submission = WPCF7_Submission::get_instance();
|
||||
|
||||
if ( ! $submission ) {
|
||||
return $output;
|
||||
}
|
||||
|
||||
$user_id = (int) $submission->get_meta( 'current_user_id' );
|
||||
|
||||
if ( ! $user_id ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$primary_props = array( 'user_login', 'user_email', 'user_url' );
|
||||
$opt = ltrim( $name, '_' );
|
||||
$opt = in_array( $opt, $primary_props, true ) ? $opt : substr( $opt, 5 );
|
||||
|
||||
$user = new WP_User( $user_id );
|
||||
|
||||
if ( $user->has_prop( $opt ) ) {
|
||||
return (string) $user->get( $opt );
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
927
wp-content/plugins/contact-form-7/includes/submission.php
Normal file
@ -0,0 +1,927 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class representing contact form submission.
|
||||
*/
|
||||
class WPCF7_Submission {
|
||||
|
||||
use WPCF7_PocketHolder;
|
||||
|
||||
private static $instance;
|
||||
|
||||
private $contact_form;
|
||||
private $status = 'init';
|
||||
private $posted_data = array();
|
||||
private $posted_data_hash = null;
|
||||
private $skip_spam_check = false;
|
||||
private $uploaded_files = array();
|
||||
private $extra_attachments = array();
|
||||
private $skip_mail = false;
|
||||
private $response = '';
|
||||
private $invalid_fields = array();
|
||||
private $meta = array();
|
||||
private $consent = array();
|
||||
private $spam_log = array();
|
||||
private $result_props = array();
|
||||
|
||||
|
||||
/**
|
||||
* Returns the singleton instance of this class.
|
||||
*/
|
||||
public static function get_instance( $contact_form = null, $options = '' ) {
|
||||
if ( $contact_form instanceof WPCF7_ContactForm ) {
|
||||
if ( empty( self::$instance ) ) {
|
||||
self::$instance = new self( $contact_form, $options );
|
||||
self::$instance->proceed();
|
||||
return self::$instance;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
if ( empty( self::$instance ) ) {
|
||||
return null;
|
||||
} else {
|
||||
return self::$instance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if this submission is created via WP REST API.
|
||||
*/
|
||||
public static function is_restful() {
|
||||
return wp_is_serving_rest_request();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
private function __construct( WPCF7_ContactForm $contact_form, $options = '' ) {
|
||||
$options = wp_parse_args( $options, array(
|
||||
'skip_mail' => false,
|
||||
) );
|
||||
|
||||
$this->contact_form = $contact_form;
|
||||
$this->skip_mail = (bool) $options['skip_mail'];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
public function __destruct() {
|
||||
$this->remove_uploaded_files();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The main logic of submission.
|
||||
*/
|
||||
private function proceed() {
|
||||
|
||||
$callback = function () {
|
||||
$contact_form = $this->contact_form;
|
||||
|
||||
$this->setup_meta_data();
|
||||
$this->setup_posted_data();
|
||||
|
||||
if ( $this->is( 'init' ) and ! $this->validate() ) {
|
||||
$this->set_status( 'validation_failed' );
|
||||
$this->set_response( $contact_form->message( 'validation_error' ) );
|
||||
}
|
||||
|
||||
if ( $this->is( 'init' ) and ! $this->accepted() ) {
|
||||
$this->set_status( 'acceptance_missing' );
|
||||
$this->set_response( $contact_form->message( 'accept_terms' ) );
|
||||
}
|
||||
|
||||
if ( $this->is( 'init' ) and $this->spam() ) {
|
||||
$this->set_status( 'spam' );
|
||||
$this->set_response( $contact_form->message( 'spam' ) );
|
||||
}
|
||||
|
||||
if ( $this->is( 'init' ) and ! $this->unship_uploaded_files() ) {
|
||||
$this->set_status( 'validation_failed' );
|
||||
$this->set_response( $contact_form->message( 'validation_error' ) );
|
||||
}
|
||||
|
||||
if ( $this->is( 'init' ) ) {
|
||||
$abort = ! $this->before_send_mail();
|
||||
|
||||
if ( $abort ) {
|
||||
if ( $this->is( 'init' ) ) {
|
||||
$this->set_status( 'aborted' );
|
||||
}
|
||||
|
||||
if ( '' === $this->get_response() ) {
|
||||
$this->set_response( $contact_form->filter_message(
|
||||
__( 'Sending mail has been aborted.', 'contact-form-7' ) )
|
||||
);
|
||||
}
|
||||
} elseif ( $this->mail() ) {
|
||||
$this->set_status( 'mail_sent' );
|
||||
$this->set_response( $contact_form->message( 'mail_sent_ok' ) );
|
||||
|
||||
do_action( 'wpcf7_mail_sent', $contact_form );
|
||||
} else {
|
||||
$this->set_status( 'mail_failed' );
|
||||
$this->set_response( $contact_form->message( 'mail_sent_ng' ) );
|
||||
|
||||
do_action( 'wpcf7_mail_failed', $contact_form );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
wpcf7_switch_locale( $this->contact_form->locale(), $callback );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the current status property.
|
||||
*/
|
||||
public function get_status() {
|
||||
return $this->status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the status property.
|
||||
*
|
||||
* @param string $status The status.
|
||||
*/
|
||||
public function set_status( $status ) {
|
||||
if ( preg_match( '/^[a-z][0-9a-z_]+$/', $status ) ) {
|
||||
$this->status = $status;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the specified status is identical to the current
|
||||
* status property.
|
||||
*
|
||||
* @param string $status The status to compare.
|
||||
*/
|
||||
public function is( $status ) {
|
||||
return $this->status === $status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns an associative array of submission result properties.
|
||||
*
|
||||
* @return array Submission result properties.
|
||||
*/
|
||||
public function get_result() {
|
||||
$result = array_merge( $this->result_props, array(
|
||||
'status' => $this->get_status(),
|
||||
'message' => $this->get_response(),
|
||||
) );
|
||||
|
||||
if ( $this->is( 'validation_failed' ) ) {
|
||||
$result['invalid_fields'] = $this->get_invalid_fields();
|
||||
}
|
||||
|
||||
switch ( $this->get_status() ) {
|
||||
case 'init':
|
||||
case 'validation_failed':
|
||||
case 'acceptance_missing':
|
||||
case 'spam':
|
||||
$result['posted_data_hash'] = '';
|
||||
break;
|
||||
default:
|
||||
$result['posted_data_hash'] = $this->get_posted_data_hash();
|
||||
break;
|
||||
}
|
||||
|
||||
$result = apply_filters( 'wpcf7_submission_result', $result, $this );
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds items to the array of submission result properties.
|
||||
*
|
||||
* @param string|array|object $data Value to add to result properties.
|
||||
* @return array Added result properties.
|
||||
*/
|
||||
public function add_result_props( $data = '' ) {
|
||||
$data = wp_parse_args( $data, array() );
|
||||
|
||||
$this->result_props = array_merge( $this->result_props, $data );
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the response property.
|
||||
*
|
||||
* @return string The current response property value.
|
||||
*/
|
||||
public function get_response() {
|
||||
return $this->response;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the response property.
|
||||
*
|
||||
* @param string $response New response property value.
|
||||
*/
|
||||
public function set_response( $response ) {
|
||||
$this->response = $response;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the contact form property.
|
||||
*
|
||||
* @return WPCF7_ContactForm A contact form object.
|
||||
*/
|
||||
public function get_contact_form() {
|
||||
return $this->contact_form;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Search an invalid field by field name.
|
||||
*
|
||||
* @param string $name The field name.
|
||||
* @return array|bool An associative array of validation error
|
||||
* or false when no invalid field.
|
||||
*/
|
||||
public function get_invalid_field( $name ) {
|
||||
return $this->invalid_fields[$name] ?? false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves all invalid fields.
|
||||
*
|
||||
* @return array Invalid fields.
|
||||
*/
|
||||
public function get_invalid_fields() {
|
||||
return $this->invalid_fields;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves meta information.
|
||||
*
|
||||
* @param string $name Name of the meta information.
|
||||
* @return string|null The meta information of the given name if it exists,
|
||||
* null otherwise.
|
||||
*/
|
||||
public function get_meta( $name ) {
|
||||
return $this->meta[$name] ?? null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Collects meta information about this submission.
|
||||
*/
|
||||
private function setup_meta_data() {
|
||||
$this->meta = array(
|
||||
'timestamp' => time(),
|
||||
'remote_ip' => $this->get_remote_ip_addr(),
|
||||
'remote_port' => wpcf7_superglobal_server( 'REMOTE_PORT' ),
|
||||
'user_agent' => wpcf7_superglobal_server( 'HTTP_USER_AGENT' ),
|
||||
'url' => $this->get_request_url(),
|
||||
'unit_tag' => wpcf7_sanitize_unit_tag(
|
||||
wpcf7_superglobal_post( '_wpcf7_unit_tag' )
|
||||
),
|
||||
'container_post_id' => absint(
|
||||
wpcf7_superglobal_post( '_wpcf7_container_post' )
|
||||
),
|
||||
'current_user_id' => get_current_user_id(),
|
||||
'do_not_store' => $this->contact_form->is_true( 'do_not_store' ),
|
||||
);
|
||||
|
||||
return $this->meta;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves user input data through this submission.
|
||||
*
|
||||
* @param string $name Optional field name.
|
||||
* @return string|array|null The user input of the field, or array of all
|
||||
* fields values if no field name specified.
|
||||
*/
|
||||
public function get_posted_data( $name = '' ) {
|
||||
if ( ! empty( $name ) ) {
|
||||
return $this->posted_data[$name] ?? null;
|
||||
}
|
||||
|
||||
return $this->posted_data;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves a user input string value through the specified field.
|
||||
*
|
||||
* @param string $name Field name.
|
||||
* @return string The user input. If the input is an array,
|
||||
* the first item in the array.
|
||||
*/
|
||||
public function get_posted_string( $name ) {
|
||||
$data = $this->get_posted_data( $name );
|
||||
$data = wpcf7_array_flatten( $data );
|
||||
|
||||
if ( empty( $data ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Returns the first array item.
|
||||
return trim( reset( $data ) );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs posted data property based on user input values.
|
||||
*/
|
||||
private function setup_posted_data() {
|
||||
$posted_data = array_filter(
|
||||
(array) $_POST,
|
||||
static function ( $key ) {
|
||||
return ! str_starts_with( $key, '_' );
|
||||
},
|
||||
ARRAY_FILTER_USE_KEY
|
||||
);
|
||||
|
||||
$posted_data = wp_unslash( $posted_data );
|
||||
$posted_data = $this->sanitize_posted_data( $posted_data );
|
||||
|
||||
$tags = $this->contact_form->scan_form_tags( array(
|
||||
'feature' => array(
|
||||
'name-attr',
|
||||
'! not-for-mail',
|
||||
),
|
||||
) );
|
||||
|
||||
$tags = array_reduce( $tags, static function ( $carry, $tag ) {
|
||||
if ( $tag->name and ! isset( $carry[$tag->name] ) ) {
|
||||
$carry[$tag->name] = $tag;
|
||||
}
|
||||
|
||||
return $carry;
|
||||
}, array() );
|
||||
|
||||
foreach ( $tags as $tag ) {
|
||||
$value_orig = $value = $posted_data[$tag->name] ?? '';
|
||||
|
||||
if ( wpcf7_form_tag_supports( $tag->type, 'selectable-values' ) ) {
|
||||
$value = ( '' === $value ) ? array() : (array) $value;
|
||||
|
||||
if ( WPCF7_USE_PIPE ) {
|
||||
$pipes = $this->contact_form->get_pipes( $tag->name );
|
||||
|
||||
$value = array_map( static function ( $value ) use ( $pipes ) {
|
||||
return $pipes->do_pipe( $value );
|
||||
}, $value );
|
||||
}
|
||||
}
|
||||
|
||||
$value = apply_filters( "wpcf7_posted_data_{$tag->type}",
|
||||
$value,
|
||||
$value_orig,
|
||||
$tag
|
||||
);
|
||||
|
||||
$posted_data[$tag->name] = $value;
|
||||
|
||||
if ( $tag->has_option( 'consent_for:storage' ) and empty( $value ) ) {
|
||||
$this->meta['do_not_store'] = true;
|
||||
}
|
||||
}
|
||||
|
||||
$this->posted_data = apply_filters( 'wpcf7_posted_data', $posted_data );
|
||||
|
||||
$this->posted_data_hash = $this->create_posted_data_hash();
|
||||
|
||||
return $this->posted_data;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sanitizes user input data.
|
||||
*/
|
||||
private function sanitize_posted_data( $value ) {
|
||||
return map_deep( $value, static function ( $val ) {
|
||||
$val = (string) $val;
|
||||
$val = wp_check_invalid_utf8( $val );
|
||||
$val = wp_kses_no_null( $val );
|
||||
$val = wpcf7_strip_whitespaces( $val );
|
||||
return $val;
|
||||
} );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the time-dependent variable for hash creation.
|
||||
*
|
||||
* @return float Float value rounded up to the next highest integer.
|
||||
*/
|
||||
private function posted_data_hash_tick() {
|
||||
return ceil( time() / ( HOUR_IN_SECONDS / 2 ) );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a hash string based on posted data, the remote IP address,
|
||||
* contact form location, and window of time.
|
||||
*
|
||||
* @param string $tick Optional. If not specified, result of
|
||||
* posted_data_hash_tick() will be used.
|
||||
* @return string The hash.
|
||||
*/
|
||||
private function create_posted_data_hash( $tick = '' ) {
|
||||
if ( '' === $tick ) {
|
||||
$tick = $this->posted_data_hash_tick();
|
||||
}
|
||||
|
||||
$hash = wp_hash(
|
||||
wpcf7_flat_join( array_merge(
|
||||
array(
|
||||
$tick,
|
||||
$this->get_meta( 'remote_ip' ),
|
||||
$this->get_meta( 'unit_tag' ),
|
||||
),
|
||||
$this->posted_data
|
||||
) ),
|
||||
'wpcf7_submission'
|
||||
);
|
||||
|
||||
return $hash;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the hash string created for this submission.
|
||||
*
|
||||
* @return string The current hash for the submission.
|
||||
*/
|
||||
public function get_posted_data_hash() {
|
||||
return $this->posted_data_hash;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Verifies that the given string is equivalent to the posted data hash.
|
||||
*
|
||||
* @param string $hash Optional. This value will be compared to the
|
||||
* current posted data hash for the submission. If not
|
||||
* specified, the value of $_POST['_wpcf7_posted_data_hash']
|
||||
* will be used.
|
||||
* @return int|bool 1 if $hash is created 0-30 minutes ago,
|
||||
* 2 if $hash is created 30-60 minutes ago,
|
||||
* false if $hash is invalid.
|
||||
*/
|
||||
public function verify_posted_data_hash( $hash = '' ) {
|
||||
if ( '' === $hash ) {
|
||||
$hash = wpcf7_superglobal_post( '_wpcf7_posted_data_hash' );
|
||||
}
|
||||
|
||||
if ( '' === $hash ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$tick = $this->posted_data_hash_tick();
|
||||
|
||||
// Hash created 0-30 minutes ago.
|
||||
$expected_1 = $this->create_posted_data_hash( $tick );
|
||||
|
||||
if ( hash_equals( $expected_1, $hash ) ) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Hash created 30-60 minutes ago.
|
||||
$expected_2 = $this->create_posted_data_hash( $tick - 1 );
|
||||
|
||||
if ( hash_equals( $expected_2, $hash ) ) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the remote IP address of this submission.
|
||||
*/
|
||||
private function get_remote_ip_addr() {
|
||||
$ip_addr = wpcf7_superglobal_server( 'REMOTE_ADDR' );
|
||||
|
||||
if ( ! WP_Http::is_ip_address( $ip_addr ) ) {
|
||||
$ip_addr = '';
|
||||
}
|
||||
|
||||
return apply_filters( 'wpcf7_remote_ip_addr', $ip_addr );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the request URL of this submission.
|
||||
*/
|
||||
private function get_request_url() {
|
||||
$home_url = untrailingslashit( home_url() );
|
||||
|
||||
if ( self::is_restful() ) {
|
||||
$referer = wpcf7_superglobal_server( 'HTTP_REFERER' );
|
||||
|
||||
if ( $referer and str_starts_with( $referer, $home_url ) ) {
|
||||
return sanitize_url( $referer );
|
||||
}
|
||||
}
|
||||
|
||||
$url = preg_replace( '%(?<!:|/)/.*$%', '', $home_url )
|
||||
. wpcf7_get_request_uri();
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Runs user input validation.
|
||||
*
|
||||
* @return bool True if no invalid field is found.
|
||||
*/
|
||||
private function validate() {
|
||||
if ( $this->invalid_fields ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$result = new WPCF7_Validation();
|
||||
|
||||
$this->contact_form->validate_schema(
|
||||
array(
|
||||
'text' => true,
|
||||
'file' => false,
|
||||
'field' => array(),
|
||||
),
|
||||
$result
|
||||
);
|
||||
|
||||
$tags = $this->contact_form->scan_form_tags( array(
|
||||
'feature' => '! file-uploading',
|
||||
) );
|
||||
|
||||
foreach ( $tags as $tag ) {
|
||||
$type = $tag->type;
|
||||
$result = apply_filters( "wpcf7_validate_{$type}", $result, $tag );
|
||||
}
|
||||
|
||||
$result = apply_filters( 'wpcf7_validate', $result, $tags );
|
||||
|
||||
$this->invalid_fields = $result->get_invalid_fields();
|
||||
|
||||
return $result->is_valid();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if user consent is obtained.
|
||||
*/
|
||||
private function accepted() {
|
||||
return apply_filters( 'wpcf7_acceptance', true, $this );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds user consent data to this submission.
|
||||
*
|
||||
* @param string $name Field name.
|
||||
* @param string $conditions Conditions of consent.
|
||||
*/
|
||||
public function add_consent( $name, $conditions ) {
|
||||
$this->consent[$name] = $conditions;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Collects user consent data.
|
||||
*
|
||||
* @return array User consent data.
|
||||
*/
|
||||
public function collect_consent() {
|
||||
return (array) $this->consent;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Executes spam protections.
|
||||
*
|
||||
* @return bool True if spam captured.
|
||||
*/
|
||||
private function spam() {
|
||||
$spam = false;
|
||||
|
||||
$skip_spam_check = apply_filters( 'wpcf7_skip_spam_check',
|
||||
$this->skip_spam_check,
|
||||
$this
|
||||
);
|
||||
|
||||
if ( $skip_spam_check ) {
|
||||
return $spam;
|
||||
}
|
||||
|
||||
if (
|
||||
$this->contact_form->is_true( 'subscribers_only' ) and
|
||||
current_user_can( 'wpcf7_submit', $this->contact_form->id() )
|
||||
) {
|
||||
return $spam;
|
||||
}
|
||||
|
||||
$user_agent = (string) $this->get_meta( 'user_agent' );
|
||||
|
||||
if ( strlen( $user_agent ) < 2 ) {
|
||||
$spam = true;
|
||||
|
||||
$this->add_spam_log( array(
|
||||
'agent' => 'wpcf7',
|
||||
'reason' => __( 'User-Agent string is unnaturally short.', 'contact-form-7' ),
|
||||
) );
|
||||
}
|
||||
|
||||
if ( ! $this->verify_nonce() ) {
|
||||
$spam = true;
|
||||
|
||||
$this->add_spam_log( array(
|
||||
'agent' => 'wpcf7',
|
||||
'reason' => __( 'Submitted nonce is invalid.', 'contact-form-7' ),
|
||||
) );
|
||||
}
|
||||
|
||||
return apply_filters( 'wpcf7_spam', $spam, $this );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds a spam log.
|
||||
*
|
||||
* @link https://contactform7.com/2019/05/31/why-is-this-message-marked-spam/
|
||||
*/
|
||||
public function add_spam_log( $data = '' ) {
|
||||
$data = wp_parse_args( $data, array(
|
||||
'agent' => '',
|
||||
'reason' => '',
|
||||
) );
|
||||
|
||||
$this->spam_log[] = $data;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the spam logging data.
|
||||
*
|
||||
* @return array Spam logging data.
|
||||
*/
|
||||
public function get_spam_log() {
|
||||
return $this->spam_log;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Verifies that a correct security nonce was used.
|
||||
*/
|
||||
private function verify_nonce() {
|
||||
if ( ! $this->contact_form->nonce_is_active() or ! is_user_logged_in() ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$nonce = wpcf7_superglobal_post( '_wpnonce' );
|
||||
|
||||
return wpcf7_verify_nonce( $nonce );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function called just before sending email.
|
||||
*/
|
||||
private function before_send_mail() {
|
||||
$abort = false;
|
||||
|
||||
do_action_ref_array( 'wpcf7_before_send_mail', array(
|
||||
$this->contact_form,
|
||||
&$abort,
|
||||
$this,
|
||||
) );
|
||||
|
||||
return ! $abort;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sends emails based on user input values and contact form email templates.
|
||||
*/
|
||||
private function mail() {
|
||||
$contact_form = $this->contact_form;
|
||||
|
||||
$skip_mail = apply_filters( 'wpcf7_skip_mail',
|
||||
$this->skip_mail, $contact_form
|
||||
);
|
||||
|
||||
if ( $skip_mail ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$result = WPCF7_Mail::send( $contact_form->prop( 'mail' ), 'mail' );
|
||||
|
||||
if ( $result ) {
|
||||
$additional_mail = array();
|
||||
|
||||
if (
|
||||
$mail_2 = $contact_form->prop( 'mail_2' ) and
|
||||
$mail_2['active']
|
||||
) {
|
||||
$additional_mail['mail_2'] = $mail_2;
|
||||
}
|
||||
|
||||
$additional_mail = apply_filters( 'wpcf7_additional_mail',
|
||||
$additional_mail, $contact_form
|
||||
);
|
||||
|
||||
foreach ( $additional_mail as $name => $template ) {
|
||||
WPCF7_Mail::send( $template, $name );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves files uploaded through this submission.
|
||||
*/
|
||||
public function uploaded_files() {
|
||||
return $this->uploaded_files;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds a file to the uploaded files array.
|
||||
*
|
||||
* @param string $name Field name.
|
||||
* @param string|array $file_path File path or array of file paths.
|
||||
*/
|
||||
private function add_uploaded_file( $name, $file_path ) {
|
||||
if ( ! wpcf7_is_name( $name ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$paths = (array) $file_path;
|
||||
$uploaded_files = array();
|
||||
$hash_strings = array();
|
||||
|
||||
foreach ( $paths as $path ) {
|
||||
if ( @is_file( $path ) and @is_readable( $path ) ) {
|
||||
$uploaded_files[] = $path;
|
||||
$hash_strings[] = hash_file( 'sha256', $path );
|
||||
}
|
||||
}
|
||||
|
||||
$this->uploaded_files[$name] = $uploaded_files;
|
||||
|
||||
if ( empty( $this->posted_data[$name] ) ) {
|
||||
$this->posted_data[$name] = implode( ' ', $hash_strings );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Removes uploaded files.
|
||||
*/
|
||||
private function remove_uploaded_files() {
|
||||
$filesystem = WPCF7_Filesystem::get_instance();
|
||||
|
||||
foreach ( (array) $this->uploaded_files as $file_path ) {
|
||||
foreach ( (array) $file_path as $path ) {
|
||||
if ( wpcf7_is_file_path_in_content_dir( $path ) ) {
|
||||
wpcf7_rmdir_p( $path );
|
||||
|
||||
// Remove parent dir if empty.
|
||||
$filesystem->delete( dirname( $path ), false );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Moves uploaded files to the tmp directory and validates them.
|
||||
*
|
||||
* @return bool True if no invalid file is found.
|
||||
*/
|
||||
private function unship_uploaded_files() {
|
||||
$result = new WPCF7_Validation();
|
||||
|
||||
$tags = $this->contact_form->scan_form_tags( array(
|
||||
'feature' => 'file-uploading',
|
||||
) );
|
||||
|
||||
foreach ( $tags as $tag ) {
|
||||
if ( empty( $_FILES[$tag->name] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$file = $_FILES[$tag->name];
|
||||
|
||||
$options = array(
|
||||
'tag' => $tag,
|
||||
'name' => $tag->name,
|
||||
'required' => $tag->is_required(),
|
||||
'filetypes' => $tag->get_option( 'filetypes' ),
|
||||
'limit' => $tag->get_limit_option(),
|
||||
'schema' => $this->contact_form->get_schema(),
|
||||
);
|
||||
|
||||
$new_files = wpcf7_unship_uploaded_file( $file, $options );
|
||||
|
||||
if ( is_wp_error( $new_files ) ) {
|
||||
$result->invalidate( $tag, $new_files );
|
||||
} else {
|
||||
$this->add_uploaded_file( $tag->name, $new_files );
|
||||
}
|
||||
|
||||
$result = apply_filters(
|
||||
"wpcf7_validate_{$tag->type}",
|
||||
$result, $tag,
|
||||
array(
|
||||
'uploaded_files' => $new_files,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$this->invalid_fields = $result->get_invalid_fields();
|
||||
|
||||
return $result->is_valid();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds extra email attachment files that are independent from form fields.
|
||||
*
|
||||
* @param string|array $file_path A file path or an array of file paths.
|
||||
* @param string $template Optional. The name of the template to which
|
||||
* the files are attached.
|
||||
* @return bool True if it succeeds to attach a file at least,
|
||||
* or false otherwise.
|
||||
*/
|
||||
public function add_extra_attachments( $file_path, $template = 'mail' ) {
|
||||
if ( ! did_action( 'wpcf7_before_send_mail' ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$extra_attachments = array();
|
||||
|
||||
foreach ( (array) $file_path as $path ) {
|
||||
$path = path_join( WP_CONTENT_DIR, $path );
|
||||
|
||||
if ( file_exists( $path ) ) {
|
||||
$extra_attachments[] = $path;
|
||||
}
|
||||
}
|
||||
|
||||
if ( empty( $extra_attachments ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! isset( $this->extra_attachments[$template] ) ) {
|
||||
$this->extra_attachments[$template] = array();
|
||||
}
|
||||
|
||||
$this->extra_attachments[$template] = array_merge(
|
||||
$this->extra_attachments[$template],
|
||||
$extra_attachments
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns extra email attachment files.
|
||||
*
|
||||
* @param string $template An email template name.
|
||||
* @return array Array of file paths.
|
||||
*/
|
||||
public function extra_attachments( $template ) {
|
||||
if ( isset( $this->extra_attachments[$template] ) ) {
|
||||
return (array) $this->extra_attachments[$template];
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,6 @@
|
||||
<?php
|
||||
|
||||
return array(
|
||||
'dependencies' => array(),
|
||||
'version' => WPCF7_VERSION,
|
||||
);
|
||||
@ -0,0 +1,207 @@
|
||||
<?php
|
||||
|
||||
namespace Contactable\SWV;
|
||||
|
||||
use WP_Error;
|
||||
|
||||
/**
|
||||
* The base class of SWV rules.
|
||||
*/
|
||||
abstract class Rule {
|
||||
|
||||
protected $properties = array();
|
||||
|
||||
public function __construct( $properties = '' ) {
|
||||
$this->properties = wp_parse_args( $properties, array() );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if this rule matches the given context.
|
||||
*
|
||||
* @param array $context Context.
|
||||
*/
|
||||
public function matches( $context ) {
|
||||
$field = $this->get_property( 'field' );
|
||||
|
||||
if ( ! empty( $context['field'] ) ) {
|
||||
if ( $field and ! in_array( $field, (array) $context['field'], true ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Validates with this rule's logic.
|
||||
*
|
||||
* @param array $context Context.
|
||||
*/
|
||||
public function validate( $context ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Converts the properties to an array.
|
||||
*
|
||||
* @return array Array of properties.
|
||||
*/
|
||||
public function to_array() {
|
||||
$properties = (array) $this->properties;
|
||||
|
||||
if ( defined( 'static::rule_name' ) and static::rule_name ) {
|
||||
$properties = array( 'rule' => static::rule_name ) + $properties;
|
||||
}
|
||||
|
||||
return $properties;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the property value specified by the given property name.
|
||||
*
|
||||
* @param string $name Property name.
|
||||
* @return mixed Property value.
|
||||
*/
|
||||
public function get_property( $name ) {
|
||||
if ( isset( $this->properties[$name] ) ) {
|
||||
return $this->properties[$name];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the default user input value from $_POST.
|
||||
*
|
||||
* @return mixed Default user input value.
|
||||
*/
|
||||
public function get_default_input() {
|
||||
$field = $this->get_property( 'field' );
|
||||
|
||||
if ( isset( $_POST[$field] ) ) {
|
||||
return wp_unslash( $_POST[$field] );
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the default user upload file from $_FILES.
|
||||
*
|
||||
* @return object Default user upload file.
|
||||
*/
|
||||
public function get_default_upload() {
|
||||
$field = $this->get_property( 'field' );
|
||||
|
||||
if ( isset( $_FILES[$field] ) ) {
|
||||
return (object) wp_unslash( $_FILES[$field] );
|
||||
}
|
||||
|
||||
return (object) array();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates an error object. Returns false if the error property is omitted.
|
||||
*/
|
||||
protected function create_error() {
|
||||
$error_code = defined( 'static::rule_name' )
|
||||
? sprintf( 'swv_%s', static::rule_name )
|
||||
: 'swv';
|
||||
|
||||
return new WP_Error(
|
||||
$error_code,
|
||||
(string) $this->get_property( 'error' ),
|
||||
$this
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The base class of SWV composite rules.
|
||||
*/
|
||||
abstract class CompositeRule extends Rule {
|
||||
|
||||
protected $rules = array();
|
||||
|
||||
|
||||
/**
|
||||
* Adds a sub-rule to this composite rule.
|
||||
*
|
||||
* @param Rule $rule Sub-rule to be added.
|
||||
*/
|
||||
public function add_rule( $rule ) {
|
||||
if ( $rule instanceof Rule ) {
|
||||
$this->rules[] = $rule;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns an iterator of sub-rules.
|
||||
*/
|
||||
public function rules() {
|
||||
foreach ( $this->rules as $rule ) {
|
||||
yield $rule;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if this rule matches the given context.
|
||||
*
|
||||
* @param array $context Context.
|
||||
*/
|
||||
public function matches( $context ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Validates with this rule's logic.
|
||||
*
|
||||
* @param array $context Context.
|
||||
*/
|
||||
public function validate( $context ) {
|
||||
foreach ( $this->rules() as $rule ) {
|
||||
if ( $rule->matches( $context ) ) {
|
||||
$result = $rule->validate( $context );
|
||||
|
||||
if ( is_wp_error( $result ) ) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Converts the properties to an array.
|
||||
*
|
||||
* @return array Array of properties.
|
||||
*/
|
||||
public function to_array() {
|
||||
$rules_arrays = array_map(
|
||||
static function ( $rule ) {
|
||||
return $rule->to_array();
|
||||
},
|
||||
$this->rules
|
||||
);
|
||||
|
||||
return array_merge(
|
||||
parent::to_array(),
|
||||
array(
|
||||
'rules' => $rules_arrays,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace Contactable\SWV;
|
||||
|
||||
class AllRule extends CompositeRule {
|
||||
|
||||
const rule_name = 'all';
|
||||
|
||||
public function matches( $context ) {
|
||||
if ( false === parent::matches( $context ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function validate( $context ) {
|
||||
foreach ( $this->rules() as $rule ) {
|
||||
if ( $rule->matches( $context ) ) {
|
||||
$result = $rule->validate( $context );
|
||||
|
||||
if ( is_wp_error( $result ) ) {
|
||||
if ( $result->get_error_message() ) {
|
||||
return $result;
|
||||
} else {
|
||||
return $this->create_error();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace Contactable\SWV;
|
||||
|
||||
class AnyRule extends CompositeRule {
|
||||
|
||||
const rule_name = 'any';
|
||||
|
||||
public function matches( $context ) {
|
||||
if ( false === parent::matches( $context ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function validate( $context ) {
|
||||
foreach ( $this->rules() as $rule ) {
|
||||
if ( $rule->matches( $context ) ) {
|
||||
$result = $rule->validate( $context );
|
||||
|
||||
if ( ! is_wp_error( $result ) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->create_error();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace Contactable\SWV;
|
||||
|
||||
class DateRule extends Rule {
|
||||
|
||||
const rule_name = 'date';
|
||||
|
||||
public function matches( $context ) {
|
||||
if ( false === parent::matches( $context ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( empty( $context['text'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function validate( $context ) {
|
||||
$input = $this->get_default_input();
|
||||
$input = wpcf7_array_flatten( $input );
|
||||
$input = wpcf7_strip_whitespaces( $input );
|
||||
$input = wpcf7_exclude_blank( $input );
|
||||
|
||||
foreach ( $input as $i ) {
|
||||
if ( ! wpcf7_is_date( $i ) ) {
|
||||
return $this->create_error();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
namespace Contactable\SWV;
|
||||
|
||||
class DayofweekRule extends Rule {
|
||||
|
||||
const rule_name = 'dayofweek';
|
||||
|
||||
public function matches( $context ) {
|
||||
if ( false === parent::matches( $context ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( empty( $context['text'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function validate( $context ) {
|
||||
$input = $this->get_default_input();
|
||||
$input = wpcf7_array_flatten( $input );
|
||||
$input = wpcf7_strip_whitespaces( $input );
|
||||
$input = wpcf7_exclude_blank( $input );
|
||||
|
||||
$acceptable_values = (array) $this->get_property( 'accept' );
|
||||
$acceptable_values = array_map( 'intval', $acceptable_values );
|
||||
$acceptable_values = array_filter( $acceptable_values );
|
||||
$acceptable_values = array_unique( $acceptable_values );
|
||||
|
||||
foreach ( $input as $i ) {
|
||||
if ( wpcf7_is_date( $i ) ) {
|
||||
$datetime = date_create_immutable( $i, wp_timezone() );
|
||||
$dow = (int) $datetime->format( 'N' );
|
||||
|
||||
if ( ! in_array( $dow, $acceptable_values, true ) ) {
|
||||
return $this->create_error();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace Contactable\SWV;
|
||||
|
||||
class EmailRule extends Rule {
|
||||
|
||||
const rule_name = 'email';
|
||||
|
||||
public function matches( $context ) {
|
||||
if ( false === parent::matches( $context ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( empty( $context['text'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function validate( $context ) {
|
||||
$input = $this->get_default_input();
|
||||
$input = wpcf7_array_flatten( $input );
|
||||
$input = wpcf7_strip_whitespaces( $input );
|
||||
$input = wpcf7_exclude_blank( $input );
|
||||
|
||||
foreach ( $input as $i ) {
|
||||
if ( ! wpcf7_is_email( $i ) ) {
|
||||
return $this->create_error();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
namespace Contactable\SWV;
|
||||
|
||||
class EnumRule extends Rule {
|
||||
|
||||
const rule_name = 'enum';
|
||||
|
||||
public function matches( $context ) {
|
||||
if ( false === parent::matches( $context ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( empty( $context['text'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function validate( $context ) {
|
||||
$input = $this->get_default_input();
|
||||
$input = wpcf7_array_flatten( $input );
|
||||
$input = wpcf7_strip_whitespaces( $input );
|
||||
$input = wpcf7_exclude_blank( $input );
|
||||
|
||||
$acceptable_values = (array) $this->get_property( 'accept' );
|
||||
|
||||
$acceptable_values = array_map(
|
||||
static function ( $val ) {
|
||||
$val = strval( $val );
|
||||
$val = wpcf7_normalize_newline( $val );
|
||||
return $val;
|
||||
},
|
||||
$acceptable_values
|
||||
);
|
||||
|
||||
$acceptable_values = array_unique( $acceptable_values );
|
||||
|
||||
$acceptable_values = array_filter( $acceptable_values,
|
||||
static function ( $val ) {
|
||||
return '' !== $val;
|
||||
}
|
||||
);
|
||||
|
||||
foreach ( $input as $i ) {
|
||||
$i = wpcf7_normalize_newline( $i );
|
||||
|
||||
if ( ! in_array( $i, $acceptable_values, true ) ) {
|
||||
return $this->create_error();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
namespace Contactable\SWV;
|
||||
|
||||
class FileRule extends Rule {
|
||||
|
||||
const rule_name = 'file';
|
||||
|
||||
public function matches( $context ) {
|
||||
if ( false === parent::matches( $context ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( empty( $context['file'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function validate( $context ) {
|
||||
$input = $this->get_default_upload()->name ?? '';
|
||||
$input = wpcf7_array_flatten( $input );
|
||||
$input = wpcf7_exclude_blank( $input );
|
||||
|
||||
$acceptable_filetypes = array();
|
||||
|
||||
foreach ( (array) $this->get_property( 'accept' ) as $accept ) {
|
||||
if ( preg_match( '/^\.[a-z0-9]+$/i', $accept ) ) {
|
||||
$acceptable_filetypes[] = strtolower( $accept );
|
||||
} else {
|
||||
foreach ( wpcf7_convert_mime_to_ext( $accept ) as $ext ) {
|
||||
$acceptable_filetypes[] = sprintf(
|
||||
'.%s',
|
||||
strtolower( trim( $ext, ' .' ) )
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$acceptable_filetypes = array_unique( $acceptable_filetypes );
|
||||
|
||||
foreach ( $input as $i ) {
|
||||
$last_period_pos = strrpos( $i, '.' );
|
||||
|
||||
if ( false === $last_period_pos ) { // no period
|
||||
return $this->create_error();
|
||||
}
|
||||
|
||||
$suffix = strtolower( substr( $i, $last_period_pos ) );
|
||||
|
||||
if ( ! in_array( $suffix, $acceptable_filetypes, true ) ) {
|
||||
return $this->create_error();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace Contactable\SWV;
|
||||
|
||||
class MaxDateRule extends Rule {
|
||||
|
||||
const rule_name = 'maxdate';
|
||||
|
||||
public function matches( $context ) {
|
||||
if ( false === parent::matches( $context ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( empty( $context['text'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function validate( $context ) {
|
||||
$input = $this->get_default_input();
|
||||
$input = wpcf7_array_flatten( $input );
|
||||
$input = wpcf7_strip_whitespaces( $input );
|
||||
$input = wpcf7_exclude_blank( $input );
|
||||
|
||||
$threshold = $this->get_property( 'threshold' );
|
||||
|
||||
if ( ! wpcf7_is_date( $threshold ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
foreach ( $input as $i ) {
|
||||
if ( wpcf7_is_date( $i ) and $threshold < $i ) {
|
||||
return $this->create_error();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace Contactable\SWV;
|
||||
|
||||
class MaxFileSizeRule extends Rule {
|
||||
|
||||
const rule_name = 'maxfilesize';
|
||||
|
||||
public function matches( $context ) {
|
||||
if ( false === parent::matches( $context ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( empty( $context['file'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function validate( $context ) {
|
||||
$input = $this->get_default_upload()->size ?? '';
|
||||
$input = wpcf7_array_flatten( $input );
|
||||
$input = wpcf7_exclude_blank( $input );
|
||||
|
||||
if ( empty( $input ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$threshold = $this->get_property( 'threshold' );
|
||||
|
||||
if ( $threshold < array_sum( $input ) ) {
|
||||
return $this->create_error();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace Contactable\SWV;
|
||||
|
||||
class MaxItemsRule extends Rule {
|
||||
|
||||
const rule_name = 'maxitems';
|
||||
|
||||
public function matches( $context ) {
|
||||
if ( false === parent::matches( $context ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( empty( $context['text'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function validate( $context ) {
|
||||
$input = $this->get_default_input();
|
||||
$input = wpcf7_array_flatten( $input );
|
||||
$input = wpcf7_strip_whitespaces( $input );
|
||||
$input = wpcf7_exclude_blank( $input );
|
||||
|
||||
$threshold = $this->get_property( 'threshold' );
|
||||
|
||||
if ( ! wpcf7_is_number( $threshold ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( (int) $threshold < count( $input ) ) {
|
||||
return $this->create_error();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
namespace Contactable\SWV;
|
||||
|
||||
class MaxLengthRule extends Rule {
|
||||
|
||||
const rule_name = 'maxlength';
|
||||
|
||||
public function matches( $context ) {
|
||||
if ( false === parent::matches( $context ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( empty( $context['text'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function validate( $context ) {
|
||||
$input = $this->get_default_input();
|
||||
$input = wpcf7_array_flatten( $input );
|
||||
$input = wpcf7_strip_whitespaces( $input );
|
||||
$input = wpcf7_exclude_blank( $input );
|
||||
|
||||
if ( empty( $input ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$total = 0;
|
||||
|
||||
foreach ( $input as $i ) {
|
||||
$total += wpcf7_count_code_units( $i );
|
||||
}
|
||||
|
||||
$threshold = (int) $this->get_property( 'threshold' );
|
||||
|
||||
if ( $total <= $threshold ) {
|
||||
return true;
|
||||
} else {
|
||||
return $this->create_error();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace Contactable\SWV;
|
||||
|
||||
class MaxNumberRule extends Rule {
|
||||
|
||||
const rule_name = 'maxnumber';
|
||||
|
||||
public function matches( $context ) {
|
||||
if ( false === parent::matches( $context ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( empty( $context['text'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function validate( $context ) {
|
||||
$input = $this->get_default_input();
|
||||
$input = wpcf7_array_flatten( $input );
|
||||
$input = wpcf7_strip_whitespaces( $input );
|
||||
$input = wpcf7_exclude_blank( $input );
|
||||
|
||||
$threshold = $this->get_property( 'threshold' );
|
||||
|
||||
if ( ! wpcf7_is_number( $threshold ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
foreach ( $input as $i ) {
|
||||
if ( wpcf7_is_number( $i ) and (float) $threshold < (float) $i ) {
|
||||
return $this->create_error();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace Contactable\SWV;
|
||||
|
||||
class MinDateRule extends Rule {
|
||||
|
||||
const rule_name = 'mindate';
|
||||
|
||||
public function matches( $context ) {
|
||||
if ( false === parent::matches( $context ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( empty( $context['text'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function validate( $context ) {
|
||||
$input = $this->get_default_input();
|
||||
$input = wpcf7_array_flatten( $input );
|
||||
$input = wpcf7_strip_whitespaces( $input );
|
||||
$input = wpcf7_exclude_blank( $input );
|
||||
|
||||
$threshold = $this->get_property( 'threshold' );
|
||||
|
||||
if ( ! wpcf7_is_date( $threshold ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
foreach ( $input as $i ) {
|
||||
if ( wpcf7_is_date( $i ) and $i < $threshold ) {
|
||||
return $this->create_error();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace Contactable\SWV;
|
||||
|
||||
class MinFileSizeRule extends Rule {
|
||||
|
||||
const rule_name = 'minfilesize';
|
||||
|
||||
public function matches( $context ) {
|
||||
if ( false === parent::matches( $context ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( empty( $context['file'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function validate( $context ) {
|
||||
$input = $this->get_default_upload()->size ?? '';
|
||||
$input = wpcf7_array_flatten( $input );
|
||||
$input = wpcf7_exclude_blank( $input );
|
||||
|
||||
if ( empty( $input ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$threshold = $this->get_property( 'threshold' );
|
||||
|
||||
if ( array_sum( $input ) < $threshold ) {
|
||||
return $this->create_error();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace Contactable\SWV;
|
||||
|
||||
class MinItemsRule extends Rule {
|
||||
|
||||
const rule_name = 'minitems';
|
||||
|
||||
public function matches( $context ) {
|
||||
if ( false === parent::matches( $context ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( empty( $context['text'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function validate( $context ) {
|
||||
$input = $this->get_default_input();
|
||||
$input = wpcf7_array_flatten( $input );
|
||||
$input = wpcf7_strip_whitespaces( $input );
|
||||
$input = wpcf7_exclude_blank( $input );
|
||||
|
||||
$threshold = $this->get_property( 'threshold' );
|
||||
|
||||
if ( ! wpcf7_is_number( $threshold ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( count( $input ) < (int) $threshold ) {
|
||||
return $this->create_error();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
namespace Contactable\SWV;
|
||||
|
||||
class MinLengthRule extends Rule {
|
||||
|
||||
const rule_name = 'minlength';
|
||||
|
||||
public function matches( $context ) {
|
||||
if ( false === parent::matches( $context ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( empty( $context['text'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function validate( $context ) {
|
||||
$input = $this->get_default_input();
|
||||
$input = wpcf7_array_flatten( $input );
|
||||
$input = wpcf7_strip_whitespaces( $input );
|
||||
$input = wpcf7_exclude_blank( $input );
|
||||
|
||||
if ( empty( $input ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$total = 0;
|
||||
|
||||
foreach ( $input as $i ) {
|
||||
$total += wpcf7_count_code_units( $i );
|
||||
}
|
||||
|
||||
$threshold = (int) $this->get_property( 'threshold' );
|
||||
|
||||
if ( $threshold <= $total ) {
|
||||
return true;
|
||||
} else {
|
||||
return $this->create_error();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace Contactable\SWV;
|
||||
|
||||
class MinNumberRule extends Rule {
|
||||
|
||||
const rule_name = 'minnumber';
|
||||
|
||||
public function matches( $context ) {
|
||||
if ( false === parent::matches( $context ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( empty( $context['text'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function validate( $context ) {
|
||||
$input = $this->get_default_input();
|
||||
$input = wpcf7_array_flatten( $input );
|
||||
$input = wpcf7_strip_whitespaces( $input );
|
||||
$input = wpcf7_exclude_blank( $input );
|
||||
|
||||
$threshold = $this->get_property( 'threshold' );
|
||||
|
||||
if ( ! wpcf7_is_number( $threshold ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
foreach ( $input as $i ) {
|
||||
if ( wpcf7_is_number( $i ) and (float) $i < (float) $threshold ) {
|
||||
return $this->create_error();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace Contactable\SWV;
|
||||
|
||||
class NumberRule extends Rule {
|
||||
|
||||
const rule_name = 'number';
|
||||
|
||||
public function matches( $context ) {
|
||||
if ( false === parent::matches( $context ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( empty( $context['text'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function validate( $context ) {
|
||||
$input = $this->get_default_input();
|
||||
$input = wpcf7_array_flatten( $input );
|
||||
$input = wpcf7_strip_whitespaces( $input );
|
||||
$input = wpcf7_exclude_blank( $input );
|
||||
|
||||
foreach ( $input as $i ) {
|
||||
if ( ! wpcf7_is_number( $i ) ) {
|
||||
return $this->create_error();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace Contactable\SWV;
|
||||
|
||||
class RequiredRule extends Rule {
|
||||
|
||||
const rule_name = 'required';
|
||||
|
||||
public function matches( $context ) {
|
||||
if ( false === parent::matches( $context ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( empty( $context['text'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function validate( $context ) {
|
||||
$input = $this->get_default_input();
|
||||
$input = wpcf7_array_flatten( $input );
|
||||
$input = wpcf7_strip_whitespaces( $input );
|
||||
$input = wpcf7_exclude_blank( $input );
|
||||
|
||||
if ( empty( $input ) ) {
|
||||
return $this->create_error();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace Contactable\SWV;
|
||||
|
||||
class RequiredFileRule extends Rule {
|
||||
|
||||
const rule_name = 'requiredfile';
|
||||
|
||||
public function matches( $context ) {
|
||||
if ( false === parent::matches( $context ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( empty( $context['file'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function validate( $context ) {
|
||||
$input = $this->get_default_upload()->tmp_name ?? '';
|
||||
$input = wpcf7_array_flatten( $input );
|
||||
$input = wpcf7_exclude_blank( $input );
|
||||
|
||||
if ( empty( $input ) ) {
|
||||
return $this->create_error();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
namespace Contactable\SWV;
|
||||
|
||||
class StepNumberRule extends Rule {
|
||||
|
||||
const rule_name = 'stepnumber';
|
||||
|
||||
public function matches( $context ) {
|
||||
if ( false === parent::matches( $context ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( empty( $context['text'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function validate( $context ) {
|
||||
$input = $this->get_default_input();
|
||||
$input = wpcf7_array_flatten( $input );
|
||||
$input = wpcf7_strip_whitespaces( $input );
|
||||
$input = wpcf7_exclude_blank( $input );
|
||||
|
||||
$base = floatval( $this->get_property( 'base' ) );
|
||||
$interval = floatval( $this->get_property( 'interval' ) );
|
||||
|
||||
if ( ! ( 0 < $interval ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
foreach ( $input as $i ) {
|
||||
$remainder = fmod( floatval( $i ) - $base, $interval );
|
||||
|
||||
if (
|
||||
0.0 === round( abs( $remainder ), 6 ) or
|
||||
0.0 === round( abs( $remainder - $interval ), 6 )
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return $this->create_error();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace Contactable\SWV;
|
||||
|
||||
class TelRule extends Rule {
|
||||
|
||||
const rule_name = 'tel';
|
||||
|
||||
public function matches( $context ) {
|
||||
if ( false === parent::matches( $context ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( empty( $context['text'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function validate( $context ) {
|
||||
$input = $this->get_default_input();
|
||||
$input = wpcf7_array_flatten( $input );
|
||||
$input = wpcf7_strip_whitespaces( $input );
|
||||
$input = wpcf7_exclude_blank( $input );
|
||||
|
||||
foreach ( $input as $i ) {
|
||||
if ( ! wpcf7_is_tel( $i ) ) {
|
||||
return $this->create_error();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace Contactable\SWV;
|
||||
|
||||
class TimeRule extends Rule {
|
||||
|
||||
const rule_name = 'time';
|
||||
|
||||
public function matches( $context ) {
|
||||
if ( false === parent::matches( $context ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( empty( $context['text'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function validate( $context ) {
|
||||
$input = $this->get_default_input();
|
||||
$input = wpcf7_array_flatten( $input );
|
||||
$input = wpcf7_strip_whitespaces( $input );
|
||||
$input = wpcf7_exclude_blank( $input );
|
||||
|
||||
foreach ( $input as $i ) {
|
||||
if ( ! wpcf7_is_time( $i ) ) {
|
||||
return $this->create_error();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace Contactable\SWV;
|
||||
|
||||
class URLRule extends Rule {
|
||||
|
||||
const rule_name = 'url';
|
||||
|
||||
public function matches( $context ) {
|
||||
if ( false === parent::matches( $context ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( empty( $context['text'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function validate( $context ) {
|
||||
$input = $this->get_default_input();
|
||||
$input = wpcf7_array_flatten( $input );
|
||||
$input = wpcf7_strip_whitespaces( $input );
|
||||
$input = wpcf7_exclude_blank( $input );
|
||||
|
||||
foreach ( $input as $i ) {
|
||||
if ( ! wpcf7_is_url( $i ) ) {
|
||||
return $this->create_error();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
trait WPCF7_SWV_SchemaHolder {
|
||||
|
||||
protected $schema;
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves SWV schema for this holder object (contact form).
|
||||
*
|
||||
* @return WPCF7_SWV_Schema The schema object.
|
||||
*/
|
||||
public function get_schema() {
|
||||
if ( isset( $this->schema ) ) {
|
||||
return $this->schema;
|
||||
}
|
||||
|
||||
$schema = new WPCF7_SWV_Schema( array(
|
||||
'locale' => isset( $this->locale ) ? $this->locale : '',
|
||||
) );
|
||||
|
||||
do_action( 'wpcf7_swv_create_schema', $schema, $this );
|
||||
|
||||
return $this->schema = $schema;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Validates form inputs based on the schema and given context.
|
||||
*/
|
||||
public function validate_schema( $context, WPCF7_Validation $validity ) {
|
||||
$schema = $this->get_schema();
|
||||
|
||||
foreach ( $schema->validate( $context ) as $result ) {
|
||||
if ( is_wp_error( $result ) ) {
|
||||
$rule = $result->get_error_data();
|
||||
$field = $rule->get_property( 'field' );
|
||||
|
||||
if ( isset( $field ) and $validity->is_valid( $field ) ) {
|
||||
$validity->invalidate( $field, $result );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
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'],
|
||||
array( 'in_footer' => true )
|
||||
);
|
||||
},
|
||||
10, 0
|
||||
);
|
||||
172
wp-content/plugins/contact-form-7/includes/swv/swv.php
Normal file
@ -0,0 +1,172 @@
|
||||
<?php
|
||||
/**
|
||||
* Schema-Woven Validation API
|
||||
*/
|
||||
|
||||
require_once WPCF7_PLUGIN_DIR . '/includes/swv/schema-holder.php';
|
||||
require_once WPCF7_PLUGIN_DIR . '/includes/swv/script-loader.php';
|
||||
require_once WPCF7_PLUGIN_DIR . '/includes/swv/php/abstract-rules.php';
|
||||
|
||||
|
||||
/**
|
||||
* Returns an associative array of SWV rules.
|
||||
*/
|
||||
function wpcf7_swv_available_rules() {
|
||||
$rules = array(
|
||||
'required' => 'Contactable\SWV\RequiredRule',
|
||||
'requiredfile' => 'Contactable\SWV\RequiredFileRule',
|
||||
'email' => 'Contactable\SWV\EmailRule',
|
||||
'url' => 'Contactable\SWV\URLRule',
|
||||
'tel' => 'Contactable\SWV\TelRule',
|
||||
'number' => 'Contactable\SWV\NumberRule',
|
||||
'date' => 'Contactable\SWV\DateRule',
|
||||
'time' => 'Contactable\SWV\TimeRule',
|
||||
'file' => 'Contactable\SWV\FileRule',
|
||||
'enum' => 'Contactable\SWV\EnumRule',
|
||||
'dayofweek' => 'Contactable\SWV\DayofweekRule',
|
||||
'minitems' => 'Contactable\SWV\MinItemsRule',
|
||||
'maxitems' => 'Contactable\SWV\MaxItemsRule',
|
||||
'minlength' => 'Contactable\SWV\MinLengthRule',
|
||||
'maxlength' => 'Contactable\SWV\MaxLengthRule',
|
||||
'minnumber' => 'Contactable\SWV\MinNumberRule',
|
||||
'maxnumber' => 'Contactable\SWV\MaxNumberRule',
|
||||
'mindate' => 'Contactable\SWV\MinDateRule',
|
||||
'maxdate' => 'Contactable\SWV\MaxDateRule',
|
||||
'minfilesize' => 'Contactable\SWV\MinFileSizeRule',
|
||||
'maxfilesize' => 'Contactable\SWV\MaxFileSizeRule',
|
||||
'stepnumber' => 'Contactable\SWV\StepNumberRule',
|
||||
'all' => 'Contactable\SWV\AllRule',
|
||||
'any' => 'Contactable\SWV\AnyRule',
|
||||
);
|
||||
|
||||
return apply_filters( 'wpcf7_swv_available_rules', $rules );
|
||||
}
|
||||
|
||||
|
||||
add_action( 'wpcf7_init', 'wpcf7_swv_load_rules', 10, 0 );
|
||||
|
||||
/**
|
||||
* Loads SWV fules.
|
||||
*/
|
||||
function wpcf7_swv_load_rules() {
|
||||
$rules = wpcf7_swv_available_rules();
|
||||
|
||||
foreach ( array_keys( $rules ) as $rule ) {
|
||||
$file = sprintf( '%s.php', $rule );
|
||||
$path = path_join( WPCF7_PLUGIN_DIR . '/includes/swv/php/rules', $file );
|
||||
|
||||
if ( file_exists( $path ) ) {
|
||||
include_once $path;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates an SWV rule object.
|
||||
*
|
||||
* @param string $rule_name Rule name.
|
||||
* @param string|array $properties Optional. Rule properties.
|
||||
* @return \Contactable\SWV\Rule|null The rule object, or null if it failed.
|
||||
*/
|
||||
function wpcf7_swv_create_rule( $rule_name, $properties = '' ) {
|
||||
$rules = wpcf7_swv_available_rules();
|
||||
|
||||
if ( isset( $rules[$rule_name] ) ) {
|
||||
return new $rules[$rule_name]( $properties );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns an associative array of JSON Schema for Contact Form 7 SWV.
|
||||
*/
|
||||
function wpcf7_swv_get_meta_schema() {
|
||||
return array(
|
||||
'$schema' => 'https://json-schema.org/draft/2020-12/schema',
|
||||
'title' => 'Contact Form 7 SWV',
|
||||
'description' => 'Contact Form 7 SWV meta-schema',
|
||||
'type' => 'object',
|
||||
'properties' => array(
|
||||
'version' => array(
|
||||
'type' => 'string',
|
||||
),
|
||||
'locale' => array(
|
||||
'type' => 'string',
|
||||
),
|
||||
'rules' => array(
|
||||
'type' => 'array',
|
||||
'items' => array(
|
||||
'type' => 'object',
|
||||
'properties' => array(
|
||||
'rule' => array(
|
||||
'type' => 'string',
|
||||
'enum' => array_keys( wpcf7_swv_available_rules() ),
|
||||
),
|
||||
'field' => array(
|
||||
'type' => 'string',
|
||||
'pattern' => '^[A-Za-z][-A-Za-z0-9_:]*$',
|
||||
),
|
||||
'error' => array(
|
||||
'type' => 'string',
|
||||
),
|
||||
'accept' => array(
|
||||
'type' => 'array',
|
||||
'items' => array(
|
||||
'type' => 'string',
|
||||
),
|
||||
),
|
||||
'base' => array(
|
||||
'type' => 'string',
|
||||
),
|
||||
'interval' => array(
|
||||
'type' => 'number',
|
||||
'minimum' => 0,
|
||||
),
|
||||
'threshold' => array(
|
||||
'type' => 'string',
|
||||
),
|
||||
),
|
||||
'required' => array( 'rule' ),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The schema class as a composite rule.
|
||||
*/
|
||||
class WPCF7_SWV_Schema extends \Contactable\SWV\CompositeRule {
|
||||
|
||||
/**
|
||||
* The human-readable version of the schema.
|
||||
*/
|
||||
const version = 'Contact Form 7 SWV Schema 2024-10';
|
||||
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct( $properties = '' ) {
|
||||
$this->properties = wp_parse_args( $properties, array(
|
||||
'version' => self::version,
|
||||
) );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Validates with this schema.
|
||||
*
|
||||
* @param array $context Context.
|
||||
*/
|
||||
public function validate( $context ) {
|
||||
foreach ( $this->rules() as $rule ) {
|
||||
if ( $rule->matches( $context ) ) {
|
||||
yield $rule->validate( $context );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||