plugin updates

This commit is contained in:
Tony Volpe
2024-02-21 16:19:46 +00:00
parent c72f206574
commit 21d4c85c00
1214 changed files with 102269 additions and 179257 deletions

View File

@@ -1,8 +1,8 @@
<?php
// Include the Settings Page & Update Check
include_once( 'admin/settings.php' );
include_once( 'admin/update-check.php' );
include_once('admin/settings.php');
include_once('admin/update-check.php');
/**
* Admin Scripts and Styles

View File

@@ -1,97 +1,140 @@
<?php
add_action( 'plugins_loaded', 'wpcf7dtx_update_check' );
function wpcf7dtx_update_check(){
if( WPCF7DTX_VERSION !== get_option( 'cf7dtx_version', '' ) ){
// Update the database version with the current plugin version
update_option( 'cf7dtx_version', WPCF7DTX_VERSION );
// Run the update handler
add_action('admin_init', 'wpcf7dtx_update');
}
}
function wpcf7dtx_update(){
// v4.2.0 will scan for meta and user keys that should be allow-listed and display an admin alert
wpcf7dtx_v4_2_0_access_scan_check();
// Future update processes would go here
}
/*** 4.2.0 - Security Access ***/
function wpcf7dtx_v4_2_0_access_scan_check(){
$op = 'cf7dtx_v4_2_0_access_scan_check_status';
$status = get_option( $op, '' );
// Status values:
// intervention_required - show a notice to the admin
// intervention_not_required - we can ignore
// intervention_completed - no need to show notice any longer
// notice_dismissed - alert was dismissed by user
// If we've never checked before
if( $status === '' ){
// Run a scan - 20 by default. If they have more than 20 forms, we'll alert regardless.
// For less than 20 forms, we'll only alert if we detect an issue
$num_to_scan = 20;
$r = wpcf7dtx_scan_forms_for_access_keys( $num_to_scan );
$found = count($r['forms']);
$scanned = $r['forms_scanned'];
// If keys were found, or if we scanned the max number (so there are likely more to be scanned)
if( $found || $scanned === $num_to_scan ){
// We'll show a notice to the user
$status = 'intervention_required';
}
else{
// No keys need to be allow-listed, no need to show the user a list
$status = 'intervention_not_required';
}
wpcf7dtx_set_update_access_scan_check_status( $status );
}
}
add_action('admin_notices', 'wpcf7dtx_access_keys_notice');
/**
* Display an admin notice if there are unresolved issues with accessing disallowed keys via DTX shortcodes
*/
function wpcf7dtx_access_keys_notice(){
// Don't show this notice on the Scan Results screen to avoid confusion
if( isset($_GET['page']) && $_GET['page'] === 'cf7dtx_settings' && ( isset( $_GET['scan-meta-keys']) || isset($_GET['dismiss-access-keys-notice']))) return;
// If this user is not an administrator, don't do anything. Only admins should see this.
$user = wp_get_current_user();
if ( !in_array( 'administrator', (array) $user->roles ) ) return;
// If the status doesn't require intervention, don't do anything
$status = get_option( 'cf7dtx_v4_2_0_access_scan_check_status', '' );
if( $status !== 'intervention_required' ){
return;
}
?>
<div class="notice notice-error">
<p>
<?php _e('CF7 DTX: Shortcode data access requires allow-listing.', 'contact-form-7-dynamic-text-extension'); ?>
<a href="<?php echo wpcf7dtx_get_admin_settings_screen_url(); ?>"><?php _e('Edit Settings', 'contact-form-7-dynamic-text-extension' ); ?></a>
|
<a href="<?php echo wpcf7dtx_get_admin_scan_screen_url(); ?>"><?php _e('Scan &amp; Resolve', 'contact-form-7-dynamic-text-extension' ); ?></a>
|
<a href="<?php echo WPCF7DTX_DATA_ACCESS_KB_URL; ?>" target="_blank"><?php _e('More Information', 'contact-form-7-dynamic-text-extension' ); ?></a>
<?php if( isset($_GET['page']) && $_GET['page'] === 'cf7dtx_settings' ): ?>
| <a href="<?php echo admin_url('admin.php?page=cf7dtx_settings&dismiss-access-keys-notice'); ?>"><?php _e('Dismiss', 'contact-form-7-dynamic-text-extension' ); ?></a>
<?php endif; ?>
</p>
</div>
<?php
}
function wpcf7dtx_set_update_access_scan_check_status( $status ){
update_option( 'cf7dtx_v4_2_0_access_scan_check_status', $status );
}
<?php
/**
* Check for Updates
*
* Hooked to `plugins_loaded` to compare source code version with database version.
*
* @since 4.2.0
*
* @return void
*/
function wpcf7dtx_update_check()
{
if (WPCF7DTX_VERSION !== get_option('cf7dtx_version', '')) {
// Update the database version with the current plugin version
update_option('cf7dtx_version', WPCF7DTX_VERSION);
// Run the update handler
add_action('admin_init', 'wpcf7dtx_update');
}
}
add_action('plugins_loaded', 'wpcf7dtx_update_check');
/**
* Maybe Update DTX
*
* Optionally hooked to `admin_init` when source code version is newer than database version.
*
* @since 4.2.0
*
* @return void
*/
function wpcf7dtx_update()
{
// v4.2.0 will scan for meta and user keys that should be allow-listed and display an admin alert
wpcf7dtx_v4_2_0_access_scan_check();
// Future update processes would go here
}
/**
* DTX Form Scan
*
* Scan for meta and user keys that should be allowlisted and display an admin alert.
*
* @since 4.2.0
*
* @return void
*/
function wpcf7dtx_v4_2_0_access_scan_check()
{
$op = 'cf7dtx_v4_2_0_access_scan_check_status';
$status = get_option($op, '');
// Status values:
// intervention_required - show a notice to the admin
// intervention_not_required - we can ignore
// intervention_completed - no need to show notice any longer
// notice_dismissed - alert was dismissed by user
// If we've never checked before
if ($status === '') {
// Run a scan - 20 by default. If they have more than 20 forms, we'll alert regardless.
// For less than 20 forms, we'll only alert if we detect an issue
$num_to_scan = 20;
$r = wpcf7dtx_scan_forms_for_access_keys($num_to_scan);
$found = count($r['forms']);
$scanned = $r['forms_scanned'];
// If keys were found, or if we scanned the max number (so there are likely more to be scanned)
if ($found || $scanned === $num_to_scan) {
// We'll show a notice to the user
$status = 'intervention_required';
} else {
// No keys need to be allow-listed, no need to show the user a list
$status = 'intervention_not_required';
}
wpcf7dtx_set_update_access_scan_check_status($status);
}
}
/**
* DTX Admin Notice
*
* Display an admin notice if there are unresolved issues with accessing disallowed keys via DTX shortcodes
*
* @since 4.2.0
*
* @return void
*/
function wpcf7dtx_access_keys_notice()
{
// Don't show this notice on the Scan Results screen to avoid confusion
if (isset($_GET['page']) && $_GET['page'] === 'cf7dtx_settings' && (isset($_GET['scan-meta-keys']) || isset($_GET['dismiss-access-keys-notice']))) return;
// If this user is not an administrator, don't do anything. Only admins should see this.
$user = wp_get_current_user();
if (!in_array('administrator', (array) $user->roles)) return;
// If the status doesn't require intervention, don't do anything
$status = get_option('cf7dtx_v4_2_0_access_scan_check_status', '');
if ($status !== 'intervention_required') {
return;
}
?>
<div class="notice notice-error">
<p>
<?php _e('CF7 DTX: Shortcode data access requires allow-listing.', 'contact-form-7-dynamic-text-extension'); ?>
<a href="<?php echo wpcf7dtx_get_admin_settings_screen_url(); ?>"><?php _e('Edit Settings', 'contact-form-7-dynamic-text-extension'); ?></a>
|
<a href="<?php echo wpcf7dtx_get_admin_scan_screen_url(); ?>"><?php _e('Scan &amp; Resolve', 'contact-form-7-dynamic-text-extension'); ?></a>
|
<a href="<?php echo WPCF7DTX_DATA_ACCESS_KB_URL; ?>" target="_blank"><?php _e('More Information', 'contact-form-7-dynamic-text-extension'); ?></a>
<?php if (isset($_GET['page']) && $_GET['page'] === 'cf7dtx_settings') : ?>
| <a href="<?php echo admin_url('admin.php?page=cf7dtx_settings&dismiss-access-keys-notice'); ?>"><?php _e('Dismiss', 'contact-form-7-dynamic-text-extension'); ?></a>
<?php endif; ?>
</p>
</div>
<?php
}
add_action('admin_notices', 'wpcf7dtx_access_keys_notice');
/**
* Set Scan Status
*
* @since 4.2.0
*
* @param string $status
*
* @return void
*/
function wpcf7dtx_set_update_access_scan_check_status($status)
{
update_option('cf7dtx_v4_2_0_access_scan_check_status', $status);
}

View File

@@ -216,9 +216,9 @@ function wpcf7dtx_get_custom_field($atts = array())
), array_change_key_case((array)$atts, CASE_LOWER)));
// If this key can't be accessed
if( !wpcf7dtx_post_meta_key_access_is_allowed( $key ) ){
if (!wpcf7dtx_post_meta_key_access_is_allowed($key)) {
// Trigger a warning if a denied key is in use
wpcf7dtx_access_denied_alert( $key, 'post_meta' );
wpcf7dtx_access_denied_alert($key, 'post_meta');
return '';
}
@@ -353,9 +353,9 @@ function wpcf7dtx_get_current_user($atts = array())
if (is_user_logged_in()) {
// If this key can't be accessed
if( !wpcf7dtx_user_data_access_is_allowed( $key ) ){
if (!wpcf7dtx_user_data_access_is_allowed($key)) {
// Trigger a warning if a denied key is in use
wpcf7dtx_access_denied_alert( $key, 'user_data' );
wpcf7dtx_access_denied_alert($key, 'user_data');
return '';
}

View File

@@ -226,6 +226,12 @@ function wpcf7dtx_get_dynamic($value, $tag = false, $sanitize = 'auto')
/**
* Get Allowed HTML for Form Field Properties
*
* @see https://www.w3schools.com/tags/tag_input.asp
* @see https://www.w3schools.com/tags/tag_optgroup.asp
* @see https://www.w3schools.com/tags/tag_option.asp
* @see https://www.w3schools.com/tags/tag_select.asp
* @see https://www.w3schools.com/tags/tag_textarea.asp
*
* @since 4.0.0
*
* @param string $type Optional. The type of input for unique properties. Default is `text`.
@@ -256,52 +262,61 @@ function wpcf7dtx_get_allowed_field_properties($type = 'text', $extra = array())
'id' => array(),
'name' => array(),
'value' => array(),
'required' => array(),
'class' => array(),
'disabled' => array(),
'readonly' => array(),
'tabindex' => array(),
'size' => array(),
'title' => array(),
'autofocus' => array(),
// ARIA properties
'aria-invalid' => array(),
'aria-describedby' => array(),
// DTX properties
'data-dtx-value' => array(),
);
if ($type != 'hidden') {
$allowed_properties['autofocus'] = array();
$allowed_properties['readonly'] = array();
$allowed_properties['required'] = array();
}
if (in_array($type, array('checkbox', 'radio', 'acceptance'))) {
// Properties exclusive to checkboxes and radio buttons
$allowed_properties['checked'] = array();
$allowed_properties['dtx-default'] = array();
} elseif (in_array($type, array('number', 'range'))) {
// Properties exclusive to number inputs
$allowed_properties['step'] = array();
} elseif ($type == 'select') {
// Properties exclusive to select fields
$allowed_properties['size'] = array();
$allowed_properties['multiple'] = array();
$allowed_properties['dtx-default'] = array();
unset($allowed_properties['type'], $allowed_properties['value'], $allowed_properties['placeholder'], $allowed_properties['size']); // Remove invalid select attributes
}
if (!in_array($type, array('checkbox', 'radio', 'select', 'acceptance'))) {
// Allowed properties for all text-based inputs
$allowed_properties['placeholder'] = array();
unset($allowed_properties['type'], $allowed_properties['value']); // Remove invalid select attributes
} else {
// Properties exclusive to text-based inputs
$allowed_properties['autocomplete'] = array();
$allowed_properties['minlength'] = array();
$allowed_properties['maxlength'] = array();
if (in_array($type, array('number', 'range', 'date', 'datetime-local', 'time'))) {
// Additional properties for number and date inputs
$allowed_properties['min'] = array();
$allowed_properties['max'] = array();
$allowed_properties['list'] = array();
// Placeholder
if (in_array($type, array('text', 'search', 'url', 'tel', 'email', 'password', 'number'))) {
$allowed_properties['placeholder'] = array();
}
// Textarea
if ($type == 'textarea') {
// Additional properties exclusive to textarea fields
$allowed_properties['cols'] = array();
$allowed_properties['rows'] = array();
$allowed_properties['minlength'] = array();
$allowed_properties['maxlength'] = array();
$allowed_properties['wrap'] = array();
unset($allowed_properties['type'], $allowed_properties['value']); // Remove invalid textarea attributes
} elseif (in_array($type, array('text', 'date', 'url', 'tel', 'email', 'password'))) {
// Additional properties exclusive to specific text fields
} elseif (in_array($type, array('text', 'search', 'url', 'tel', 'email', 'password'))) {
// Additional properties exclusive to these text-based fields
$allowed_properties['size'] = array();
$allowed_properties['minlength'] = array();
$allowed_properties['maxlength'] = array();
$allowed_properties['pattern'] = array();
} elseif (in_array($type, array('number', 'range', 'date', 'datetime-local', 'time'))) {
// Number and date inputs
$allowed_properties['min'] = array();
$allowed_properties['max'] = array();
$allowed_properties['step'] = array();
}
}
if (is_array($extra) && count($extra)) {
@@ -554,8 +569,10 @@ function wpcf7dtx_textarea_html($atts)
* group's options. It also accepts a string value of HTML already formatted as options or
* option groups. It also accepts a string value of a self-closing shortcode that is
* evaluated and its output is either options or option groups.
* @param bool $hide_blank Optional. If true, the first blank placeholder option will have the `hidden` attribute added to it. Default is false.
* @param bool $disable_blank Optional. If true, the first blank placeholder option will have the `disabled` attribute added to it. Default is false.
* @param bool $hide_blank Optional. If true, the first blank placeholder option will have the
* `hidden` attribute added to it. Default is false.
* @param bool $disable_blank Optional. If true, the first blank placeholder option will have
* the `disabled` attribute added to it. Default is false.
*
* @return string HTML output of select field
*/
@@ -644,9 +661,11 @@ function wpcf7dtx_select_html($atts, $options, $hide_blank = false, $disable_bla
*
* @param string|int $key The key to search for in the array.
* @param array $array The array to search.
* @param mixed $default The default value to return if not found or is empty. Default is an empty string.
* @param mixed $default The default value to return if not found or is empty. Default is
* an empty string.
*
* @return mixed The value of the key found in the array if it exists or the value of `$default` if not found or is empty.
* @return mixed The value of the key found in the array if it exists or the value of
* `$default` if not found or is empty.
*/
function wpcf7dtx_array_has_key($key, $array = array(), $default = '')
{
@@ -665,163 +684,163 @@ function wpcf7dtx_array_has_key($key, $array = array(), $default = '')
/**
* Check if admin has allowed access to a specific post meta key
*
*
* @since 4.2.0
*
*
* @param string $meta_key The post meta key to test
*
*
* @return bool True if this key can be accessed, false otherwise
*/
function wpcf7dtx_post_meta_key_access_is_allowed($meta_key)
{
// Get the DTX Settings
$settings = wpcf7dtx_get_settings();get_option('cf7dtx_settings', []);
$settings = wpcf7dtx_get_settings();
// Has access to all metadata been enabled?
if( isset($settings['post_meta_allow_all']) && $settings['post_meta_allow_all'] === 'enabled' ){
if (isset($settings['post_meta_allow_all']) && $settings['post_meta_allow_all'] === 'enabled') {
return true;
}
// If not, check the Allow List
$allowed_keys;
$allowed_keys = array();
// No key list from settings
if( !isset($settings['post_meta_allow_keys'] ) || !is_string($settings['post_meta_allow_keys'])){
$allowed_keys = [];
}
// Extract allowed keys from setting text area
else{
// $allowed_keys = preg_split('/\r\n|\r|\n/', $settings['post_meta_allow_keys']);
$allowed_keys = wpcf7dtx_parse_allowed_keys( $settings['post_meta_allow_keys'] );
if (isset($settings['post_meta_allow_keys']) && is_string($settings['post_meta_allow_keys'])) {
// Extract allowed keys from setting text area
$allowed_keys = wpcf7dtx_parse_allowed_keys($settings['post_meta_allow_keys']);
}
// Allow custom filters
$allowed_keys = apply_filters( 'wpcf7dtx_post_meta_key_allow_list', $allowed_keys );
$allowed_keys = apply_filters('wpcf7dtx_post_meta_key_allow_list', $allowed_keys);
// Check if the key is in the allow list
if( in_array( $meta_key, $allowed_keys ) ){
if (in_array($meta_key, $allowed_keys)) {
return true; // The key is allowed
}
// Everything is disallowed by default
return false;
}
/**
* Check if admin has allowed access to a specific user data
*
*
* @since 4.2.0
*
*
* @param string $key The user data key to test
*
*
* @return bool True if this key can be accessed, false otherwise
*/
function wpcf7dtx_user_data_access_is_allowed( $key )
function wpcf7dtx_user_data_access_is_allowed($key)
{
// Get the DTX Settings
$settings = wpcf7dtx_get_settings(); //get_option('cf7dtx_settings', []);
// Has access to all metadata been enabled?
if( isset($settings['user_data_allow_all']) && $settings['user_data_allow_all'] === 'enabled' ){
if (isset($settings['user_data_allow_all']) && $settings['user_data_allow_all'] === 'enabled') {
return true;
}
// If not, check the Allow List
$allowed_keys;
$allowed_keys = array();
// No key list from settings
if( !isset($settings['user_data_allow_keys'] ) || !is_string($settings['user_data_allow_keys'])){
$allowed_keys = [];
}
// Extract allowed keys from setting text area
else{
// $allowed_keys = preg_split('/\r\n|\r|\n/', $settings['user_data_allow_keys']);
if (isset($settings['user_data_allow_keys']) && is_string($settings['user_data_allow_keys'])) {
// Extract allowed keys from setting text area
$allowed_keys = wpcf7dtx_parse_allowed_keys($settings['user_data_allow_keys']);
}
// Allow custom filters
$allowed_keys = apply_filters( 'wpcf7dtx_user_data_key_allow_list', $allowed_keys );
$allowed_keys = apply_filters('wpcf7dtx_user_data_key_allow_list', $allowed_keys);
// Check if the key is in the allow list
if( in_array( $key, $allowed_keys ) ){
if (in_array($key, $allowed_keys)) {
return true; // The key is allowed
}
// Everything is disallowed by default
return false;
}
/**
* Take the string saved in the options array from the allow list textarea and parse it into an array by newlines.
* Also strip whitespace
*
*
* @since 4.2.0
*
* @param string $allowlist The string of allowed keys stored in the DB
*
*
* @return array Array of allowed keys
*/
function wpcf7dtx_parse_allowed_keys( $allowlist ){
function wpcf7dtx_parse_allowed_keys($allowlist)
{
// Split by newlines
$keys = wpcf7dtx_split_newlines( $allowlist );
$keys = wpcf7dtx_split_newlines($allowlist);
// Trim whitespace
$keys = array_map( 'trim' , $keys );
$keys = array_map('trim', $keys);
return $keys;
}
/**
/**
* Used to parse strings stored in the database that are from text areas with one element per line into an array of strings
*
*
* @since 4.2.0
*
* @param string $str The multi-line string to be parsed into an array
*
*
* @return array Array of parsed strings
*/
function wpcf7dtx_split_newlines( $str ){
function wpcf7dtx_split_newlines($str)
{
return preg_split('/\r\n|\r|\n/', $str);
}
/**
* Gets the CF7 DTX settings field from the WP options table. Returns an empty array if option has not previously been set
*
*
* @since 4.2.0
*
* @return array The settings array
*/
function wpcf7dtx_get_settings(){
return get_option('cf7dtx_settings', []);
function wpcf7dtx_get_settings()
{
return get_option('cf7dtx_settings', array());
}
/**
* Updates the CF7 DTX settings in the WP options table
*
*
* @since 4.2.0
*
* @param array $settings The settings array
*
*
* @return void
*
*/
function wpcf7dtx_update_settings($settings){
update_option( 'cf7dtx_settings', $settings );
function wpcf7dtx_update_settings($settings)
{
update_option('cf7dtx_settings', $settings);
}
/**
* Outputs a useful PHP Warning message to users on how to allow-list denied meta and user keys
*
*
* @since 4.2.0
*
* @param string $key The post meta or user key to which access is currently denied
* @param string $type Either 'post_meta' or 'user_data', used to display an appropriate message to the user
*
* @return void
*/
function wpcf7dtx_access_denied_alert( $key, $type ){
function wpcf7dtx_access_denied_alert($key, $type)
{
// Only check on the front end
if( is_admin() || wp_doing_ajax() || wp_is_json_request() ) return;
if (is_admin() || wp_doing_ajax() || wp_is_json_request()) return;
$shortcode = '';
$list_name = '';
switch( $type ){
switch ($type) {
case 'post_meta':
$shortcode = 'CF7_get_custom_field';
$list_name = __('Meta Key Allow List', 'contact-form-7-dynamic-text-extension');
@@ -830,47 +849,21 @@ function wpcf7dtx_access_denied_alert( $key, $type ){
$shortcode = 'CF7_get_current_user';
$list_name = __('User Data Key Allow List', 'contact-form-7-dynamic-text-extension');
break;
default:
default:
$shortcode = '';
$list_name = '';
break;
}
$settings_page_url = admin_url('admin.php?page=cf7dtx_settings');
$msg = sprintf(
__('CF7 DTX: Access denied to key: "%1$s" in dynamic contact form shortcode: [%2$s]. Please add this key to the %3$s at %4$s','contact-form-7-dynamic-text-extension'),
__('CF7 DTX: Access denied to key: "%1$s" in dynamic contact form shortcode: [%2$s]. Please add this key to the %3$s at %4$s', 'contact-form-7-dynamic-text-extension'),
$key,
$shortcode,
$list_name,
$settings_page_url
);
trigger_error( $msg, E_USER_WARNING );
trigger_error($msg, E_USER_WARNING);
}
/**
* Helper function to output array and object data
*/
/*
function dtxpretty ($var, $print=true, $privobj=false) {
$type = gettype($var);
if( $privobj && $type === 'object' ){
$p = '<pre>'.print_r($var, true).'</pre>';
}
else {
$p = '<pre>'.$type . ' ' . json_encode(
$var,
JSON_UNESCAPED_SLASHES |
JSON_UNESCAPED_UNICODE |
JSON_PRETTY_PRINT |
JSON_PARTIAL_OUTPUT_ON_ERROR |
JSON_INVALID_UTF8_SUBSTITUTE
).'</pre>';
}
if( $print ) {
echo $p;
}
return $p;
}
*/

View File

@@ -1,369 +1,373 @@
<?php
/**
* Add Frontend Validation Messages
*
* @since 4.0.0
*
* @param array An associative array of messages
*
* @return array A modified associative array of messages
*/
function wpcf7dtx_messages($messages)
{
return array_merge($messages, array(
'dtx_invalid_email' => array(
'description' => __('There is a field with an invalid email address', 'contact-form-7-dynamic-text-extension'),
'default' => __('Please enter a valid email address.', 'contact-form-7-dynamic-text-extension')
),
'dtx_invalid_tel' => array(
'description' => __('There is a field with an invalid phone number', 'contact-form-7-dynamic-text-extension'),
'default' => __('Please enter a valid phone number.', 'contact-form-7-dynamic-text-extension')
),
'dtx_invalid_number' => array(
'description' => __('There is a field with an invalid number', 'contact-form-7-dynamic-text-extension'),
'default' => __('Please enter a valid number.', 'contact-form-7-dynamic-text-extension')
),
'dtx_invalid_date' => array(
'description' => __('There is a field with an invalid date', 'contact-form-7-dynamic-text-extension'),
'default' => __('Please enter a valid date.', 'contact-form-7-dynamic-text-extension')
),
));
}
add_filter('wpcf7_messages', 'wpcf7dtx_messages');
/**
* Add DTX Error Code to Config Validator
*
* @since 5.0.0
*
* @param array $error_codes A sequential array of available error codes in Contact Form 7.
*
* @return array A modified sequential array of available error codes in Contact Form 7.
*/
function wpcf7dtx_config_validator_available_error_codes($error_codes)
{
$dtx_errors = array('dtx_disallowed');
return array_merge($error_codes, $dtx_errors);
}
add_filter('wpcf7_config_validator_available_error_codes', 'wpcf7dtx_config_validator_available_error_codes');
/**
* Validate DTX Form Fields
*
* Frontend validation for DTX form tags
*
* @param WPCF7_Validation $result the current validation result object
* @param WPCF7_FormTag $tag the current form tag being filtered for validation
*
* @return WPCF7_Validation a possibly modified validation result object
*/
function wpcf7dtx_validation_filter($result, $tag)
{
$type = str_replace(array('dynamic_', 'dynamic'), '', $tag->basetype);
if (empty($tag->name) || in_array($type, array('hidden', 'submit', 'reset'))) {
return $result; // Bail early for tags without names or if a specific type
}
// Get the value
$user_value = wpcf7dtx_array_has_key($tag->name, $_POST);
if (is_array($user_value)) {
$selection_count = count($user_value);
if (!wpcf7_form_tag_supports($tag->type, 'selectable-values')) {
// Field passed selectable values when it's doesn't support them
$result->invalidate($tag, wpcf7_get_message('validation_error'));
return $result;
} elseif ($selection_count > 1) {
if (!wpcf7_form_tag_supports($tag->type, 'multiple-controls-container')) {
// Field passed multiple values when it's doesn't support them
$result->invalidate($tag, wpcf7_get_message('validation_error'));
return $result;
}
foreach ($user_value as $selection) {
// Validate each selected choice
$result = wpcf7dtx_validate_value($result, sanitize_textarea_field(strval($selection)), $tag, $type);
if (!$result->is_valid($tag->name)) {
return $result; // Return early if any are invalid
}
}
return $result;
}
$user_value = sanitize_text_field(strval(implode(' ', $user_value)));
} elseif ($type == 'textarea') {
$user_value = sanitize_textarea_field(strval($user_value));
} else {
$user_value = sanitize_text_field(strval($user_value));
}
// Validate and return
return wpcf7dtx_validate_value($result, $user_value, $tag, $type);
}
/**
* Validate Single Value
*
* @param WPCF7_Validation $result the current validation result object
* @param string $value the current value being validated, sanitized
* @param WPCF7_FormTag $tag the current form tag being filtered for validation
* @param string $type Optional. The type of the current form tag. Default is blank for lookup.
*
* @return WPCF7_Validation a possibly modified validation result object
*/
function wpcf7dtx_validate_value($result, $value, $tag, $type = '')
{
$type = $type ? $type : str_replace(array('dynamic_', 'dynamic'), '', $tag->basetype);
// Validate required fields for value
if ($tag->is_required() && empty($value)) {
$result->invalidate($tag, wpcf7_get_message('invalid_required'));
return $result;
}
// Validate value by type
if (!empty($value)) {
switch ($type) {
case 'email':
if (!wpcf7_is_email($value)) {
$result->invalidate($tag, wpcf7_get_message('dtx_invalid_email'));
return $result;
}
break;
case 'tel':
if (!wpcf7_is_tel($value)) {
$result->invalidate($tag, wpcf7_get_message('dtx_invalid_tel'));
return $result;
}
break;
case 'number':
case 'range':
if (!wpcf7_is_number($value)) {
$result->invalidate($tag, wpcf7_get_message('dtx_invalid_number'));
return $result;
}
break;
case 'date':
if (!wpcf7_is_date($value)) {
$result->invalidate($tag, wpcf7_get_message('dtx_invalid_date'));
return $result;
}
break;
}
// Finish validating text-based inputs
$maxlength = $tag->get_maxlength_option();
$minlength = $tag->get_minlength_option();
if ($maxlength && $minlength && $maxlength < $minlength) {
$maxlength = $minlength = null;
}
$code_units = wpcf7_count_code_units($value);
if (false !== $code_units) {
if ($maxlength && $maxlength < $code_units) {
$result->invalidate($tag, wpcf7_get_message('invalid_too_long'));
return $result;
} elseif ($minlength && $code_units < $minlength) {
$result->invalidate($tag, wpcf7_get_message('invalid_too_short'));
return $result;
}
}
}
return $result;
}
/**
* Backend Mail Configuration Validation
*
* Validate dynamic form tags used in mail configuration.
*
* @since 4.0.0
*
* @param WPCF7_ConfigValidator
*
* @return void
*/
function wpcf7dtx_validate($validator)
{
// Check for sensitive form tags
$manager = WPCF7_FormTagsManager::get_instance();
$contact_form = $validator->contact_form();
$form = $contact_form->prop('form');
if (wpcf7_autop_or_not()) {
$form = $manager->replace_with_placeholders($form);
$form = wpcf7_autop($form);
$form = $manager->restore_from_placeholders($form);
}
$form = $manager->replace_all($form);
$tags = $manager->get_scanned_tags();
foreach ($tags as $tag) {
/** @var WPCF7_FormTag $tag */
// Only validate DTX formtags
if (in_array($tag->basetype, array_merge(
array('dynamictext', 'dynamichidden'), // Deprecated DTX form tags
array_keys(wpcf7dtx_config()) // DTX form tags
))) {
// Check value for sensitive data
$default = $tag->get_option('defaultvalue', '', true);
if (!$default) {
$default = $tag->get_default_option(strval(reset($tag->values)));
}
if (
!empty($value = trim(wpcf7_get_hangover($tag->name, $default))) && // Has value
($result = wpcf7dtx_validate_sensitive_value($value))['status'] // Has sensitive data
) {
$validator->add_error('form.body', 'dtx_disallowed', array(
'message' => sprintf(
__('[%1$s %2$s]: Access to key "%3$s" in shortcode "%4$s" is disallowed by default. To allow access, add "%3$s" to the %5$s Allow List.', 'contact-form-7-dynamic-text-extension'),
esc_html($tag->basetype),
esc_html($tag->name),
esc_html($result['key']),
esc_html($result['shortcode']),
esc_html($result['shortcode'] == 'CF7_get_current_user' ? __('User Data Key', 'contact-form-7-dynamic-text-extension') : __('Meta Key', 'contact-form-7-dynamic-text-extension'))
),
'link' => wpcf7dtx_get_admin_settings_screen_url()
));
}
// Check placeholder for sensitive data
if (
($tag->has_option('placeholder') || $tag->has_option('watermark')) && // Using placeholder
!empty($placeholder = trim(html_entity_decode(urldecode($tag->get_option('placeholder', '', true)), ENT_QUOTES))) && // Has value
($result = wpcf7dtx_validate_sensitive_value($placeholder))['status'] // Has sensitive data
) {
$validator->add_error('form.body', 'dtx_disallowed', array(
'message' => sprintf(
__('[%1$s %2$s]: Access to key "%3$s" in shortcode "%4$s" is disallowed by default. To allow access, add "%3$s" to the %5$s Allow List.', 'contact-form-7-dynamic-text-extension'),
esc_html($tag->basetype),
esc_html($tag->name),
esc_html($result['key']),
esc_html($result['shortcode']),
esc_html($result['shortcode'] == 'CF7_get_current_user' ? __('User Data Key', 'contact-form-7-dynamic-text-extension') : __('Meta Key', 'contact-form-7-dynamic-text-extension'))
),
'link' => wpcf7dtx_get_admin_settings_screen_url()
));
}
}
}
// Validate email address
if (!$validator->is_valid()) {
$contact_form = null;
$form_tags = null;
foreach ($validator->collect_error_messages() as $component => $errors) {
$components = explode('.', $component);
if (count($components) === 2 && strpos($components[0], 'mail') === 0 && in_array($components[1], array('sender', 'recipient', 'additional_headers'))) {
foreach ($errors as $error) {
// Focus on email fields that flag the invalid mailbox syntax warning, have to test link because code isn't sent and message could be in any language
if (strpos(wpcf7dtx_array_has_key('link', $error), 'invalid-mailbox-syntax') !== false) {
if (is_null($contact_form)) {
$contact_form = $validator->contact_form();
}
if (is_null($form_tags)) {
$form_tags = wpcf7_scan_form_tags();
}
$raw_value = $contact_form->prop($components[0])[$components[1]];
foreach ($form_tags as $tag) {
if (!empty($tag->name)) {
// Check if this form tag is in the raw value
$form_tag = '[' . $tag->name . ']';
if (strpos($raw_value, $form_tag) !== false && in_array($tag->basetype, array_keys(wpcf7dtx_config()))) {
$validator->remove_error($component, 'invalid_mailbox_syntax'); // Remove error, this is ours to handle now
$utm_source = urlencode(home_url());
if (!in_array($tag->basetype, array('dynamic_hidden', 'dynamic_email'))) {
$validator->add_error($component, 'invalid_mailbox_syntax', array(
'message' => __('Only email, dynamic email, hidden, or dynamic hidden form tags can be used for email addresses.', 'contact-form-7-dynamic-text-extension'),
'link' => esc_url(sprintf('https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/configuration-errors/?utm_source=%s&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=config-error-invalid_mailbox_syntax#valid-form-tags', $utm_source))
));
} else {
$dynamic_value = wpcf7dtx_get_dynamic(false, $tag); // Get the dynamic value of this tag
if (empty($dynamic_value) && $tag->basetype == 'dynamic_hidden') {
$validator->add_error($component, 'maybe_empty', array(
'message' => __('The dynamic hidden form tag must have a default value.', 'contact-form-7-dynamic-text-extension'),
'link' => esc_url(sprintf('https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/configuration-errors/?utm_source=%s&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=config-error-maybe_empty#maybe-empty', $utm_source))
));
} elseif (empty($dynamic_value) && !$tag->is_required()) {
$validator->add_error($component, 'maybe_empty', array(
'message' => __('The dynamic form tag must be required or have a default value.', 'contact-form-7-dynamic-text-extension'),
'link' => esc_url(sprintf('https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/configuration-errors/?utm_source=%s&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=config-error-maybe_empty#maybe-empty', $utm_source))
));
} elseif (!empty($dynamic_value)) {
if (!wpcf7_is_email($dynamic_value)) {
$validator->add_error($component, 'invalid_mailbox_syntax', array(
'message' => __('The default dynamic value does not result in a valid email address.', 'contact-form-7-dynamic-text-extension'),
'link' => esc_url(sprintf('https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/configuration-errors/?utm_source=%s&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=config-error-invalid_mailbox_syntax#invalid-email-address', $utm_source))
));
} elseif ($component[1] == 'sender' && !wpcf7_is_email_in_site_domain($dynamic_value)) {
$validator->add_error($component, 'email_not_in_site_domain', array(
'message' => __('The dynamic email address for the sender does not belong to the site domain.', 'contact-form-7-dynamic-text-extension'),
'link' => esc_url(sprintf('https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/configuration-errors/?utm_source=%s&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=config-error-email_not_in_site_domain#invalid-site-domain', $utm_source))
));
}
}
}
}
}
}
}
}
}
}
}
}
add_action('wpcf7_config_validator_validate', 'wpcf7dtx_validate');
/**
* Validate Field Value for Sensitive Data
*
* @since 5.0.0
*
* @see https://developer.wordpress.org/reference/functions/get_bloginfo/#description
*
* @param string $content The string to validate.
*
* @return array An associative array with keys `status` (bool), `shortcode` (string), and `key` (string).
* The value of `status` is true if the content is a shortcode that is attempting to access sensitive data. False
* otherwise. The value of `shortcode` is the the shortcode that is making the attempt if `status` is true. The
* value of `key` is the shortcode's `key` attribute of the attempt being made if `status` is true.
*/
function wpcf7dtx_validate_sensitive_value($content)
{
$r = array(
'status' => false,
'shortcode' => '',
'key' => ''
);
// Parse the attributes. [0] is the shortcode name. ['key'] is the key attribute
$atts = shortcode_parse_atts($content);
// If we can't extract the atts, or the shortcode or `key` is not an att, don't validate
if( !is_array($atts) || !array_key_exists('key', $atts) || !array_key_exists('0', $atts) ) return $r;
// Find the key and shortcode in question
$key = sanitize_text_field($atts['key']);
$shortcode = sanitize_text_field($atts['0']);
// If the shortcode or key value does not exist, don't validate
if( empty($shortcode) || empty($key) ) return $r;
$allowed = true;
switch( $shortcode ){
case 'CF7_get_custom_field':
$allowed = wpcf7dtx_post_meta_key_access_is_allowed( $key );
break;
case 'CF7_get_current_user':
$allowed = wpcf7dtx_user_data_access_is_allowed( $key );
break;
default:
}
if( !$allowed ){
$r['status'] = true;
$r['shortcode'] = $shortcode;
$r['key'] = $key;
}
return $r;
}
<?php
/**
* Add Frontend Validation Messages
*
* @since 4.0.0
*
* @param array An associative array of messages
*
* @return array A modified associative array of messages
*/
function wpcf7dtx_messages($messages)
{
return array_merge($messages, array(
'dtx_invalid_email' => array(
'description' => __('There is a field with an invalid email address', 'contact-form-7-dynamic-text-extension'),
'default' => __('Please enter a valid email address.', 'contact-form-7-dynamic-text-extension')
),
'dtx_invalid_tel' => array(
'description' => __('There is a field with an invalid phone number', 'contact-form-7-dynamic-text-extension'),
'default' => __('Please enter a valid phone number.', 'contact-form-7-dynamic-text-extension')
),
'dtx_invalid_number' => array(
'description' => __('There is a field with an invalid number', 'contact-form-7-dynamic-text-extension'),
'default' => __('Please enter a valid number.', 'contact-form-7-dynamic-text-extension')
),
'dtx_invalid_date' => array(
'description' => __('There is a field with an invalid date', 'contact-form-7-dynamic-text-extension'),
'default' => __('Please enter a valid date.', 'contact-form-7-dynamic-text-extension')
),
));
}
add_filter('wpcf7_messages', 'wpcf7dtx_messages');
/**
* Add DTX Error Code to Config Validator
*
* @since 5.0.0
*
* @param array $error_codes A sequential array of available error codes in Contact Form 7.
*
* @return array A modified sequential array of available error codes in Contact Form 7.
*/
function wpcf7dtx_config_validator_available_error_codes($error_codes)
{
$dtx_errors = array('dtx_disallowed');
return array_merge($error_codes, $dtx_errors);
}
add_filter('wpcf7_config_validator_available_error_codes', 'wpcf7dtx_config_validator_available_error_codes');
/**
* Validate DTX Form Fields
*
* Frontend validation for DTX form tags
*
* @param WPCF7_Validation $result the current validation result object
* @param WPCF7_FormTag $tag the current form tag being filtered for validation
*
* @return WPCF7_Validation a possibly modified validation result object
*/
function wpcf7dtx_validation_filter($result, $tag)
{
$type = str_replace(array('dynamic_', 'dynamic'), '', $tag->basetype);
if (empty($tag->name) || in_array($type, array('hidden', 'submit', 'reset'))) {
return $result; // Bail early for tags without names or if a specific type
}
// Get the value
$user_value = wpcf7dtx_array_has_key($tag->name, $_POST);
if (is_array($user_value)) {
$selection_count = count($user_value);
if (!wpcf7_form_tag_supports($tag->type, 'selectable-values')) {
// Field passed selectable values when it's doesn't support them
$result->invalidate($tag, wpcf7_get_message('validation_error'));
return $result;
} elseif ($selection_count > 1) {
if (!wpcf7_form_tag_supports($tag->type, 'multiple-controls-container')) {
// Field passed multiple values when it's doesn't support them
$result->invalidate($tag, wpcf7_get_message('validation_error'));
return $result;
}
foreach ($user_value as $selection) {
// Validate each selected choice
$result = wpcf7dtx_validate_value($result, sanitize_textarea_field(strval($selection)), $tag, $type);
if (!$result->is_valid($tag->name)) {
return $result; // Return early if any are invalid
}
}
return $result;
}
$user_value = sanitize_text_field(strval(implode(' ', $user_value)));
} elseif ($type == 'textarea') {
$user_value = sanitize_textarea_field(strval($user_value));
} else {
$user_value = sanitize_text_field(strval($user_value));
}
// Validate and return
return wpcf7dtx_validate_value($result, $user_value, $tag, $type);
}
/**
* Validate Single Value
*
* @param WPCF7_Validation $result the current validation result object
* @param string $value the current value being validated, sanitized
* @param WPCF7_FormTag $tag the current form tag being filtered for validation
* @param string $type Optional. The type of the current form tag. Default is blank for lookup.
*
* @return WPCF7_Validation a possibly modified validation result object
*/
function wpcf7dtx_validate_value($result, $value, $tag, $type = '')
{
$type = $type ? $type : str_replace(array('dynamic_', 'dynamic'), '', $tag->basetype);
// Validate required fields for value
if ($tag->is_required() && empty($value)) {
$result->invalidate($tag, wpcf7_get_message('invalid_required'));
return $result;
}
// Validate value by type
if (!empty($value)) {
switch ($type) {
case 'email':
if (!wpcf7_is_email($value)) {
$result->invalidate($tag, wpcf7_get_message('dtx_invalid_email'));
return $result;
}
break;
case 'tel':
if (!wpcf7_is_tel($value)) {
$result->invalidate($tag, wpcf7_get_message('dtx_invalid_tel'));
return $result;
}
break;
case 'number':
case 'range':
if (!wpcf7_is_number($value)) {
$result->invalidate($tag, wpcf7_get_message('dtx_invalid_number'));
return $result;
}
break;
case 'date':
if (!wpcf7_is_date($value)) {
$result->invalidate($tag, wpcf7_get_message('dtx_invalid_date'));
return $result;
}
break;
}
// Finish validating text-based inputs
$maxlength = $tag->get_maxlength_option();
$minlength = $tag->get_minlength_option();
if ($maxlength && $minlength && $maxlength < $minlength) {
$maxlength = $minlength = null;
}
$code_units = wpcf7_count_code_units($value);
if (false !== $code_units) {
if ($maxlength && $maxlength < $code_units) {
$result->invalidate($tag, wpcf7_get_message('invalid_too_long'));
return $result;
} elseif ($minlength && $code_units < $minlength) {
$result->invalidate($tag, wpcf7_get_message('invalid_too_short'));
return $result;
}
}
}
return $result;
}
/**
* Validator Requires Contact Form 7 Minimum Version
*/
if (wpcf7dtx_dependencies()) {
/**
* Backend Mail Configuration Validation
*
* Validate dynamic form tags used in mail configuration.
*
* @since 4.0.0
*
* @param WPCF7_ConfigValidator
*
* @return void
*/
function wpcf7dtx_validate($validator)
{
// Check for sensitive form tags
$manager = WPCF7_FormTagsManager::get_instance();
$contact_form = $validator->contact_form();
$form = $contact_form->prop('form');
if (wpcf7_autop_or_not()) {
$form = $manager->replace_with_placeholders($form);
$form = wpcf7_autop($form);
$form = $manager->restore_from_placeholders($form);
}
$form = $manager->replace_all($form);
$tags = $manager->get_scanned_tags();
foreach ($tags as $tag) {
/** @var WPCF7_FormTag $tag */
// Only validate DTX formtags
if (in_array($tag->basetype, array_merge(
array('dynamictext', 'dynamichidden'), // Deprecated DTX form tags
array_keys(wpcf7dtx_config()) // DTX form tags
))) {
// Check value for sensitive data
$default = $tag->get_option('defaultvalue', '', true);
if (!$default) {
$default = $tag->get_default_option(strval(reset($tag->values)));
}
if (
!empty($value = trim(wpcf7_get_hangover($tag->name, $default))) && // Has value
($result = wpcf7dtx_validate_sensitive_value($value))['status'] // Has sensitive data
) {
$validator->add_error('form.body', 'dtx_disallowed', array(
'message' => sprintf(
__('[%1$s %2$s]: Access to key "%3$s" in shortcode "%4$s" is disallowed by default. To allow access, add "%3$s" to the %5$s Allow List.', 'contact-form-7-dynamic-text-extension'),
esc_html($tag->basetype),
esc_html($tag->name),
esc_html($result['key']),
esc_html($result['shortcode']),
esc_html($result['shortcode'] == 'CF7_get_current_user' ? __('User Data Key', 'contact-form-7-dynamic-text-extension') : __('Meta Key', 'contact-form-7-dynamic-text-extension'))
),
'link' => wpcf7dtx_get_admin_settings_screen_url()
));
}
// Check placeholder for sensitive data
if (
($tag->has_option('placeholder') || $tag->has_option('watermark')) && // Using placeholder
!empty($placeholder = trim(html_entity_decode(urldecode($tag->get_option('placeholder', '', true)), ENT_QUOTES))) && // Has value
($result = wpcf7dtx_validate_sensitive_value($placeholder))['status'] // Has sensitive data
) {
$validator->add_error('form.body', 'dtx_disallowed', array(
'message' => sprintf(
__('[%1$s %2$s]: Access to key "%3$s" in shortcode "%4$s" is disallowed by default. To allow access, add "%3$s" to the %5$s Allow List.', 'contact-form-7-dynamic-text-extension'),
esc_html($tag->basetype),
esc_html($tag->name),
esc_html($result['key']),
esc_html($result['shortcode']),
esc_html($result['shortcode'] == 'CF7_get_current_user' ? __('User Data Key', 'contact-form-7-dynamic-text-extension') : __('Meta Key', 'contact-form-7-dynamic-text-extension'))
),
'link' => wpcf7dtx_get_admin_settings_screen_url()
));
}
}
}
// Validate email address
if (!$validator->is_valid()) {
$contact_form = null;
$form_tags = null;
foreach ($validator->collect_error_messages() as $component => $errors) {
$components = explode('.', $component);
if (count($components) === 2 && strpos($components[0], 'mail') === 0 && in_array($components[1], array('sender', 'recipient', 'additional_headers'))) {
foreach ($errors as $error) {
// Focus on email fields that flag the invalid mailbox syntax warning, have to test link because code isn't sent and message could be in any language
if (strpos(wpcf7dtx_array_has_key('link', $error), 'invalid-mailbox-syntax') !== false) {
if (is_null($contact_form)) {
$contact_form = $validator->contact_form();
}
if (is_null($form_tags)) {
$form_tags = wpcf7_scan_form_tags();
}
$raw_value = $contact_form->prop($components[0])[$components[1]];
foreach ($form_tags as $tag) {
if (!empty($tag->name)) {
// Check if this form tag is in the raw value
$form_tag = '[' . $tag->name . ']';
if (strpos($raw_value, $form_tag) !== false && in_array($tag->basetype, array_keys(wpcf7dtx_config()))) {
$validator->remove_error($component, 'invalid_mailbox_syntax'); // Remove error, this is ours to handle now
$utm_source = urlencode(home_url());
if (!in_array($tag->basetype, array('dynamic_hidden', 'dynamic_email'))) {
$validator->add_error($component, 'invalid_mailbox_syntax', array(
'message' => __('Only email, dynamic email, hidden, or dynamic hidden form tags can be used for email addresses.', 'contact-form-7-dynamic-text-extension'),
'link' => esc_url(sprintf('https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/configuration-errors/?utm_source=%s&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=config-error-invalid_mailbox_syntax#valid-form-tags', $utm_source))
));
} else {
$dynamic_value = wpcf7dtx_get_dynamic(false, $tag); // Get the dynamic value of this tag
if (empty($dynamic_value) && $tag->basetype == 'dynamic_hidden') {
$validator->add_error($component, 'maybe_empty', array(
'message' => __('The dynamic hidden form tag must have a default value.', 'contact-form-7-dynamic-text-extension'),
'link' => esc_url(sprintf('https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/configuration-errors/?utm_source=%s&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=config-error-maybe_empty#maybe-empty', $utm_source))
));
} elseif (empty($dynamic_value) && !$tag->is_required()) {
$validator->add_error($component, 'maybe_empty', array(
'message' => __('The dynamic form tag must be required or have a default value.', 'contact-form-7-dynamic-text-extension'),
'link' => esc_url(sprintf('https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/configuration-errors/?utm_source=%s&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=config-error-maybe_empty#maybe-empty', $utm_source))
));
} elseif (!empty($dynamic_value)) {
if (!wpcf7_is_email($dynamic_value)) {
$validator->add_error($component, 'invalid_mailbox_syntax', array(
'message' => __('The default dynamic value does not result in a valid email address.', 'contact-form-7-dynamic-text-extension'),
'link' => esc_url(sprintf('https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/configuration-errors/?utm_source=%s&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=config-error-invalid_mailbox_syntax#invalid-email-address', $utm_source))
));
} elseif ($component[1] == 'sender' && !wpcf7_is_email_in_site_domain($dynamic_value)) {
$validator->add_error($component, 'email_not_in_site_domain', array(
'message' => __('The dynamic email address for the sender does not belong to the site domain.', 'contact-form-7-dynamic-text-extension'),
'link' => esc_url(sprintf('https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/configuration-errors/?utm_source=%s&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=config-error-email_not_in_site_domain#invalid-site-domain', $utm_source))
));
}
}
}
}
}
}
}
}
}
}
}
}
add_action('wpcf7_config_validator_validate', 'wpcf7dtx_validate');
}
/**
* Validate Field Value for Sensitive Data
*
* @since 5.0.0
*
* @see https://developer.wordpress.org/reference/functions/get_bloginfo/#description
*
* @param string $content The string to validate.
*
* @return array An associative array with keys `status` (bool), `shortcode` (string), and `key` (string).
* The value of `status` is true if the content is a shortcode that is attempting to access sensitive data. False
* otherwise. The value of `shortcode` is the the shortcode that is making the attempt if `status` is true. The
* value of `key` is the shortcode's `key` attribute of the attempt being made if `status` is true.
*/
function wpcf7dtx_validate_sensitive_value($content)
{
$r = array(
'status' => false,
'shortcode' => '',
'key' => ''
);
// Parse the attributes. [0] is the shortcode name. ['key'] is the key attribute
$atts = shortcode_parse_atts($content);
// If we can't extract the atts, or the shortcode or `key` is not an att, don't validate
if (!is_array($atts) || !array_key_exists('key', $atts) || !array_key_exists('0', $atts)) return $r;
// Find the key and shortcode in question
$key = sanitize_text_field($atts['key']);
$shortcode = sanitize_text_field($atts['0']);
// If the shortcode or key value does not exist, don't validate
if (empty($shortcode) || empty($key)) return $r;
$allowed = true;
switch ($shortcode) {
case 'CF7_get_custom_field':
$allowed = wpcf7dtx_post_meta_key_access_is_allowed($key);
break;
case 'CF7_get_current_user':
$allowed = wpcf7dtx_user_data_access_is_allowed($key);
break;
default:
}
if (!$allowed) {
$r['status'] = true;
$r['shortcode'] = $shortcode;
$r['key'] = $key;
}
return $r;
}