rebase on oct-10-2023
This commit is contained in:
@@ -1,286 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Plugin Name: Contact Form 7 - Show Page
|
||||
* Description: An add-on for Contact Form 7 that shows the all the post types where the contact form is being used.
|
||||
* Version: 1.0.3
|
||||
* Author: Sachyya, Ugene
|
||||
* Author URI:
|
||||
* License: GPLv3
|
||||
*/
|
||||
|
||||
/**
|
||||
* Show admin notice on CF7 dependency.
|
||||
* @return string Notice about the plugin dependency.
|
||||
*/
|
||||
function wpcf7sp_admin_notice() {
|
||||
// Verify that CF7 is active and updated to the required version (currently 3.9.0)
|
||||
if ( ! is_plugin_active( 'contact-form-7/wp-contact-form-7.php' ) ) {
|
||||
echo __( '<div class="error"><p><strong>Contact Form 7</strong> is not activated. The Contact Form 7 plugin must be installed and activated before you can use <strong>Contact Form 7 - Show Page</strong> plugin.</p></div>', 'wpcf7sp' );
|
||||
}
|
||||
}
|
||||
|
||||
// add_action( 'admin_notices', 'wpcf7sp_admin_notice' );
|
||||
|
||||
require_once untrailingslashit( dirname( __FILE__ ) ) . '/tgmpa/call.php';
|
||||
|
||||
/**
|
||||
* Load style file
|
||||
*/
|
||||
function wpcf7sp_load_style() {
|
||||
wp_enqueue_style( 'wpcf7sp_style', plugins_url( '/css/show-page.css', __FILE__ ), '', time(), 'all' );
|
||||
}
|
||||
|
||||
add_action( 'admin_footer', 'wpcf7sp_load_style' );
|
||||
|
||||
|
||||
/**
|
||||
* Add extra panel to form editor.
|
||||
*
|
||||
* @param Array $panels Array form editro panel args.
|
||||
*
|
||||
* @return Array $panels Array form editro panel args.
|
||||
*/
|
||||
function wpcf7sp_add_panel( $panels ) {
|
||||
$post = wpcf7_get_current_contact_form();
|
||||
if ( current_user_can( 'wpcf7_edit_contact_form', $post->id() ) ) {
|
||||
$panels['cf7-show-page-panel'] = array(
|
||||
'title' => __( 'CF7 Show Pages', 'wpcf7sp' ),
|
||||
'callback' => 'wpcf7sp_editor_panel_cf7_show_page'
|
||||
);
|
||||
}
|
||||
|
||||
return $panels;
|
||||
}
|
||||
|
||||
add_filter( 'wpcf7_editor_panels', 'wpcf7sp_add_panel' );
|
||||
|
||||
|
||||
// Get search string
|
||||
function wpcf7sp_search_string( $form_id ) {
|
||||
$wpcf7sp_form_id = $form_id->id();
|
||||
|
||||
$wpcf7sp_search_string = 'contact-form-7 id="' . $wpcf7sp_form_id . '"';
|
||||
return $wpcf7sp_search_string;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Search on postypes.
|
||||
|
||||
*/
|
||||
function wpcf7sp_search_on_posttypes( $form_id ) {
|
||||
$wpcf7sp_search_string = wpcf7sp_search_string( $form_id );
|
||||
$wpcf7sp_posttypes = apply_filters( 'wpcf7sp_support_posttypes', get_post_types( array( 'public' => true ) ) );
|
||||
|
||||
if ( ! ( is_array( $wpcf7sp_posttypes ) || is_string( $wpcf7sp_posttypes ) ) ) {
|
||||
$wpcf7sp_posttypes = get_post_types( array( 'public' => true ) );
|
||||
}
|
||||
|
||||
$post_query = new WP_Query( array(
|
||||
's' => $wpcf7sp_search_string,
|
||||
'post_type' => $wpcf7sp_posttypes,
|
||||
'posts_per_page' => -1
|
||||
) );
|
||||
|
||||
if ( $post_query->have_posts() ) { ?>
|
||||
<h4><?php _e( 'Lists of post types using this form.', 'wpcf7sp' ); ?></h4>
|
||||
<table class="wpcf7sp">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th width="55%"><?php _e( 'Title', 'wpcf7sp' ); ?></th>
|
||||
<th width="25%"><?php _e( 'Post Type', 'wpcf7sp' ); ?></th>
|
||||
<th width="20%"></th>
|
||||
</tr>
|
||||
<?php
|
||||
while ( $post_query->have_posts() ) {
|
||||
$post_query->the_post();
|
||||
$post_type = get_post_type();
|
||||
|
||||
?>
|
||||
<tr>
|
||||
<td width="50%"><?php the_title(); ?></td>
|
||||
<td width="25%"><?php echo esc_html( $post_type ); ?></td>
|
||||
<td width="25%" class="wpcf7sp-opt">
|
||||
<a href="<?php the_permalink(); ?>" class="wpcf7sp-alink" target="_blank">View</a>
|
||||
<a href="<?php echo esc_url( get_edit_post_link( get_the_ID() ) ); ?>" class="wpcf7sp-alink"
|
||||
target="_blank"><?php _e( 'Edit', 'wpcf7sp' ); ?></a>
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php
|
||||
} else { ?>
|
||||
<h4><?php _e( 'No "Posts" or "Pages" use this form right now.', 'wpcf7sp' ); ?></h4>
|
||||
<?php }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Search on text widget.
|
||||
|
||||
*/
|
||||
function wpcf7sp_search_on_text_widget( $form_id ) {
|
||||
$wpcf7sp_search_string = wpcf7sp_search_string( $form_id );
|
||||
// Query for the text widgets with the contact form.
|
||||
global $wpdb;
|
||||
// Get prefixed table name.
|
||||
$wpcf7sp_table = $wpdb->prefix . 'options';
|
||||
// Prepare query which searches for option name with widget_text and also verify for the empty and no form used condition.
|
||||
$wpcf7sp_widget_query = $wpdb->prepare( "SELECT * FROM `$wpcf7sp_table` WHERE `option_name` LIKE '%%widget_text%%' AND `option_value` LIKE '%%%s%%'", $wpcf7sp_search_string );
|
||||
$wpcf7sp_widget_results = $wpdb->get_results( $wpcf7sp_widget_query );
|
||||
if ( isset( $wpcf7sp_widget_results[0] )) {
|
||||
$wpcf7sp_widget_results = $wpcf7sp_widget_results[0];
|
||||
// Unserialize data which contains all the text widgets found.
|
||||
$wpcf7sp_text_widgets = maybe_unserialize( $wpcf7sp_widget_results->option_value );
|
||||
|
||||
// Prepare search string to be searched in result.
|
||||
$serach_expression = '/\[' . $wpcf7sp_search_string . '/';
|
||||
$widget_ids = [];
|
||||
foreach ( $wpcf7sp_text_widgets as $key => $value ) {
|
||||
if ( is_array( $value ) ) {
|
||||
// Check if the value is set and not empty and match with the search expression.
|
||||
if ( isset( $value['text'] ) && ! empty( $value['text'] ) && preg_match( $serach_expression, $value['text'] ) ) {
|
||||
// Append 'text-' to make it comparable in later in_array condition.
|
||||
$widget_ids[] = 'text-' . $key;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Query for the sidebars with the above found text widgets.
|
||||
$widget_resp_sidebar_query = "SELECT * FROM `$wpcf7sp_table` WHERE `option_name` = 'sidebars_widgets'";
|
||||
$widget_resp_sidebar_res = $wpdb->get_results( $widget_resp_sidebar_query );
|
||||
// Unserialize data which contains all the sidebars.
|
||||
$widget_resp_sidebar_res = maybe_unserialize( $widget_resp_sidebar_res[0]->option_value );
|
||||
|
||||
$side_bar_ids = [];
|
||||
foreach ( $widget_resp_sidebar_res as $key => $value ) {
|
||||
if ( ! empty( $value ) && is_array( $value ) ) {
|
||||
for ( $i = 0; $i < count( $value ); $i ++ ) {
|
||||
// Check if the above widget_ids is in the recently found array.
|
||||
if ( in_array( $value[ $i ], $widget_ids ) ) {
|
||||
$side_bar_ids[] = $key;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Removing any repeating sidebar id.
|
||||
$side_bar_ids = array_unique( $side_bar_ids );
|
||||
?>
|
||||
|
||||
<h4><?php _e( 'Lists of widgets using this form.', 'wpcf7sp' ); ?></h4>
|
||||
<?php if ( ! is_null( $wpcf7sp_text_widgets ) ): ?>
|
||||
<table class="wpcf7sp" style="width: 50%;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th><?php _e( 'Widget: Text', 'wpcf7sp' ); ?></th>
|
||||
</tr>
|
||||
<?php
|
||||
foreach ( $side_bar_ids as $value ) {
|
||||
global $wp_registered_sidebars;
|
||||
if ( isset( $wp_registered_sidebars[ $value ] ) ) {
|
||||
echo '<tr><td>' . esc_html( $wp_registered_sidebars[ $value ]['name'] ) . '</td></tr>';
|
||||
}
|
||||
}
|
||||
?>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php endif; ?>
|
||||
<?php } else { ?>
|
||||
<h4><?php _e( 'No "Text widgets" uses this form right now.', 'wpcf7sp' ); ?></h4>
|
||||
<?php }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Search on text widget.
|
||||
|
||||
*/
|
||||
function wpcf7sp_search_on_custom_html_widget( $form_id ) {
|
||||
$wpcf7sp_search_string = wpcf7sp_search_string( $form_id );
|
||||
// Query for the text widgets with the contact form.
|
||||
global $wpdb;
|
||||
// Get prefixed table name.
|
||||
$wpcf7sp_table = $wpdb->prefix . 'options';
|
||||
// Prepare query which searches for option name with widget_text and also verify for the empty and no form used condition.
|
||||
$wpcf7sp_widget_query = $wpdb->prepare( "SELECT * FROM `$wpcf7sp_table` WHERE `option_name` LIKE '%%widget_custom_html%%' AND `option_value` LIKE '%%%s%%'", $wpcf7sp_search_string );
|
||||
$wpcf7sp_widget_results = $wpdb->get_results( $wpcf7sp_widget_query );
|
||||
if ( isset( $wpcf7sp_widget_results[0] )) {
|
||||
$wpcf7sp_widget_results = $wpcf7sp_widget_results[0];
|
||||
// Unserialize data which contains all the text widgets found.
|
||||
$wpcf7sp_text_widgets = maybe_unserialize( $wpcf7sp_widget_results->option_value );
|
||||
|
||||
// Prepare search string to be searched in result.
|
||||
$serach_expression = '/\[' . $wpcf7sp_search_string . '/';
|
||||
$widget_ids = [];
|
||||
foreach ( $wpcf7sp_text_widgets as $key => $value ) {
|
||||
if ( is_array( $value ) ) {
|
||||
// Check if the value is set and not empty and match with the search expression.
|
||||
if ( isset( $value['content'] ) && ! empty( $value['content'] ) && preg_match( $serach_expression, $value['content'] ) ) {
|
||||
// Append 'text-' to make it comparable in later in_array condition.
|
||||
$widget_ids[] = 'custom_html-' . $key;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Query for the sidebars with the above found text widgets.
|
||||
$widget_resp_sidebar_query = "SELECT * FROM `$wpcf7sp_table` WHERE `option_name` = 'sidebars_widgets'";
|
||||
$widget_resp_sidebar_res = $wpdb->get_results( $widget_resp_sidebar_query );
|
||||
// Unserialize data which contains all the sidebars.
|
||||
$widget_resp_sidebar_res = maybe_unserialize( $widget_resp_sidebar_res[0]->option_value );
|
||||
|
||||
$side_bar_ids = [];
|
||||
foreach ( $widget_resp_sidebar_res as $key => $value ) {
|
||||
if ( ! empty( $value ) && is_array( $value ) ) {
|
||||
for ( $i = 0; $i < count( $value ); $i ++ ) {
|
||||
// Check if the above widget_ids is in the recently found array.
|
||||
if ( in_array( $value[ $i ], $widget_ids ) ) {
|
||||
$side_bar_ids[] = $key;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Removing any repeating sidebar id.
|
||||
$side_bar_ids = array_unique( $side_bar_ids );
|
||||
?>
|
||||
|
||||
<?php if ( ! is_null( $wpcf7sp_text_widgets ) ): ?>
|
||||
<table class="wpcf7sp" style="width: 50%;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th><?php _e( 'Widget: Custom HTML', 'wpcf7sp' ); ?></th>
|
||||
</tr>
|
||||
<?php
|
||||
foreach ( $side_bar_ids as $value ) {
|
||||
global $wp_registered_sidebars;
|
||||
if ( isset( $wp_registered_sidebars[ $value ] ) ) {
|
||||
echo '<tr><td>' . esc_html( $wp_registered_sidebars[ $value ]['name'] ) . '</td></tr>';
|
||||
}
|
||||
}
|
||||
?>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php endif; ?>
|
||||
<?php } else { ?>
|
||||
<h4><?php _e( 'No "Custom HTML" widgets uses this form right now.', 'wpcf7sp' ); ?></h4>
|
||||
<?php }
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the panel itself
|
||||
*
|
||||
*/
|
||||
function wpcf7sp_editor_panel_cf7_show_page( $form_id ) {
|
||||
|
||||
?>
|
||||
<h2><?php echo esc_html( __( 'Contact Form 7 - Show Page', 'wpcf7sp' ) ); ?></h2>
|
||||
|
||||
<?php
|
||||
|
||||
wpcf7sp_search_on_posttypes( $form_id );
|
||||
|
||||
wpcf7sp_search_on_text_widget( $form_id );
|
||||
|
||||
wpcf7sp_search_on_custom_html_widget( $form_id );
|
||||
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
.wpcf7sp_panel h4 {
|
||||
margin: 1.33em 0 .5em 0;
|
||||
}
|
||||
table.wpcf7sp {
|
||||
width: 100%;
|
||||
border: 1px inset #fff;
|
||||
padding: 10px;
|
||||
margin-top: 5px;
|
||||
font-size: small;
|
||||
}
|
||||
table.wpcf7sp tr {
|
||||
|
||||
}
|
||||
table.wpcf7sp th {
|
||||
text-align: left;
|
||||
padding: 10px 5px;
|
||||
background: #e5e5e5;
|
||||
border: 1px solid #dedede;
|
||||
}
|
||||
table.wpcf7sp td {
|
||||
text-align: left;
|
||||
padding: 10px;
|
||||
}
|
||||
.wpcf7sp-opt {
|
||||
text-align: right !important;
|
||||
}
|
||||
a.wpcf7sp-alink {
|
||||
background: #0085ba ;
|
||||
color: #fff;
|
||||
padding: 5px 10px;
|
||||
border-radius: 3px;
|
||||
text-decoration: none;
|
||||
font-size: small;
|
||||
}
|
||||
table.wpcf7sp tr:nth-child( odd ) {
|
||||
background: #f0f0f0;
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
=== Contact Form 7 - Show Page ===
|
||||
Contributors: ugene, sachyya-sachet
|
||||
Donate link: #
|
||||
Tags: Contact Form 7, form, forms, contactform7, contact form, find contact form, show page contact form 7, where contact form
|
||||
Requires at least: 4.5
|
||||
Tested up to: 4.9
|
||||
Stable tag: 1.0.3
|
||||
License: GPLv3
|
||||
License URI: https://www.gnu.org/licenses/gpl-3.0.en.html
|
||||
|
||||
A simple WordPress plugin that helps you to know which contact forms are used in the site.
|
||||
|
||||
|
||||
== Description ==
|
||||
|
||||
You don't need this plugin but hey, you might need this to quickly check where the contact forms are used. If you have good memory then you will good without it. But there is chance to forget it right?
|
||||
|
||||
So here below are the scenarios where you will find this plugin helpful:
|
||||
1. You have multiple contact forms used in various pages and posts or may be used in widgets. To edit the one you like meaning find it first. This plugin will help you showing the post/page name with a link to view or edit that post or page. For the widget case, it will tell you whether the current form is used in the widget or not.
|
||||
2. This is quite useful in this condition. Lets say you are a developer and you've come across the site where there are multiple contact forms. You might have to clean it up. This plugin will help you find and know if the contact form is used or not, meaning you are on your own far from the fear of mistakenly deleting the used one forms.
|
||||
|
||||
By default this plugin only supports the search in default post types (post/page). But you can extend the search in custom post types of your own further by using a quick filter hook like below:
|
||||
|
||||
`function extend_posttype_support ( $support ) {
|
||||
return array( 'book', 'movie' );
|
||||
}
|
||||
add_filter( 'wpcf7sp_support_posttypes', 'extend_posttype_support' );`
|
||||
|
||||
|
||||
== Usages ==
|
||||
|
||||
Backend
|
||||
|
||||
1. After installing the plugin, you will find a CF7 Show pages menu under each contact form edit page.
|
||||
2. No settings, just view where the form is used. It wil list the name of post, pages in the table with a link to view and edit.
|
||||
3. For other custom post types, filter is provided.
|
||||
|
||||
|
||||
== Notes ==
|
||||
|
||||
1. [Contact Form 7](https://wordpress.org/plugins/contact-form-7/) must be activated.
|
||||
|
||||
|
||||
== Installation ==
|
||||
|
||||
1. In your admin panel, go to Appearance > Plugins and click the Add New button.
|
||||
2. Click Upload Theme and Choose File, then select the theme's .zip file. Click Install Now.
|
||||
3. Click Activate to use your new theme right away.
|
||||
|
||||
|
||||
== Frequently Asked Questions ==
|
||||
|
||||
= Do I have to activate contact form 7 plugin? =
|
||||
|
||||
Yes, this plugin is the extension to the famous Contact Form 7 plugin and thus Contact Form 7 is must.
|
||||
|
||||
|
||||
== Screenshots ==
|
||||
|
||||
1. Overview
|
||||
|
||||
|
||||
== Changelog ==
|
||||
|
||||
= 1.0.3 Dec 4 2018 =
|
||||
* Upgrade: Search on **Custom HTML** widget too.
|
||||
* Refactor code
|
||||
* Add TGM Plugin Activation PHP library
|
||||
|
||||
= 1.0.2 =
|
||||
* Add message when post types or widgets do not use the Contact Form.
|
||||
|
||||
= 1.0.1 =
|
||||
* Extend plugin to search in widgets too but works only on **Text Widget** for now.
|
||||
* Remove default private post types.
|
||||
* Improve filter by checking for string and array only.
|
||||
|
||||
= 1.0 =
|
||||
* Initial Release
|
||||
@@ -1,166 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* This file represents an example of the code that themes would use to register
|
||||
* the required plugins.
|
||||
*
|
||||
* It is expected that theme authors would copy and paste this code into their
|
||||
* functions.php file, and amend to suit.
|
||||
*
|
||||
* @see http://tgmpluginactivation.com/configuration/ for detailed documentation.
|
||||
*
|
||||
* @package TGM-Plugin-Activation
|
||||
* @subpackage Example
|
||||
* @version 2.6.1 for plugin Wpcf7sp
|
||||
* @author Thomas Griffin, Gary Jones, Juliette Reinders Folmer
|
||||
* @copyright Copyright (c) 2011, Thomas Griffin
|
||||
* @license http://opensource.org/licenses/gpl-2.0.php GPL v2 or later
|
||||
* @link https://github.com/TGMPA/TGM-Plugin-Activation
|
||||
*/
|
||||
|
||||
/**
|
||||
* Include the TGM_Plugin_Activation class.
|
||||
*
|
||||
* Depending on your implementation, you may want to change the include call:
|
||||
*
|
||||
* Parent Theme:
|
||||
* require_once get_template_directory() . '/path/to/class-tgm-plugin-activation.php';
|
||||
*
|
||||
* Child Theme:
|
||||
* require_once get_stylesheet_directory() . '/path/to/class-tgm-plugin-activation.php';
|
||||
*
|
||||
* Plugin:
|
||||
* require_once dirname( __FILE__ ) . '/path/to/class-tgm-plugin-activation.php';
|
||||
*/
|
||||
require_once dirname( __FILE__ ) . '/class-tgm-plugin-activation.php';
|
||||
|
||||
add_action( 'tgmpa_register', 'wpcf7sp_register_required_plugins' );
|
||||
|
||||
/**
|
||||
* Register the required plugins for this theme.
|
||||
*
|
||||
* In this example, we register five plugins:
|
||||
* - one included with the TGMPA library
|
||||
* - two from an external source, one from an arbitrary source, one from a GitHub repository
|
||||
* - two from the .org repo, where one demonstrates the use of the `is_callable` argument
|
||||
*
|
||||
* The variables passed to the `tgmpa()` function should be:
|
||||
* - an array of plugin arrays;
|
||||
* - optionally a configuration array.
|
||||
* If you are not changing anything in the configuration array, you can remove the array and remove the
|
||||
* variable from the function call: `tgmpa( $plugins );`.
|
||||
* In that case, the TGMPA default settings will be used.
|
||||
*
|
||||
* This function is hooked into `tgmpa_register`, which is fired on the WP `init` action on priority 10.
|
||||
*/
|
||||
function wpcf7sp_register_required_plugins() {
|
||||
/*
|
||||
* Array of plugin arrays. Required keys are name and slug.
|
||||
* If the source is NOT from the .org repo, then source is also required.
|
||||
*/
|
||||
$plugins = array(
|
||||
// This is an example of how to include a plugin from the WordPress Plugin Repository.
|
||||
array(
|
||||
'name' => 'Contact Form 7',
|
||||
'slug' => 'contact-form-7',
|
||||
'required' => true,
|
||||
),
|
||||
);
|
||||
|
||||
/*
|
||||
* Array of configuration settings. Amend each line as needed.
|
||||
*
|
||||
* TGMPA will start providing localized text strings soon. If you already have translations of our standard
|
||||
* strings available, please help us make TGMPA even better by giving us access to these translations or by
|
||||
* sending in a pull-request with .po file(s) with the translations.
|
||||
*
|
||||
* Only uncomment the strings in the config array if you want to customize the strings.
|
||||
*/
|
||||
$config = array(
|
||||
'id' => 'wpcf7sp', // Unique ID for hashing notices for multiple instances of TGMPA.
|
||||
'default_path' => '', // Default absolute path to bundled plugins.
|
||||
'menu' => 'tgmpa-install-plugins', // Menu slug.
|
||||
'parent_slug' => 'plugins.php', // Parent menu slug.
|
||||
'capability' => 'manage_options', // Capability needed to view plugin install page, should be a capability associated with the parent menu used.
|
||||
'has_notices' => true, // Show admin notices or not.
|
||||
'dismissable' => true, // If false, a user cannot dismiss the nag message.
|
||||
'dismiss_msg' => '', // If 'dismissable' is false, this message will be output at top of nag.
|
||||
'is_automatic' => false, // Automatically activate plugins after installation or not.
|
||||
'message' => '', // Message to output right before the plugins table.
|
||||
|
||||
'strings' => array(
|
||||
'page_title' => __( 'Install Required Plugins', 'wpcf7sp' ),
|
||||
'menu_title' => __( 'Install Plugins', 'wpcf7sp' ),
|
||||
'installing' => __( 'Installing Plugin: %s', 'wpcf7sp' ),
|
||||
'notice_can_install_required' => _n_noop(
|
||||
'%1$s plugin is required for "Contact Form 7 - Show Page" to work.',
|
||||
'%1$s plugin is required "Contact Form 7 - Show Page" to work.',
|
||||
'wpcf7sp'
|
||||
),
|
||||
/* translators: %s: plugin name. * /
|
||||
'updating' => __( 'Updating Plugin: %s', 'wpcf7sp' ),
|
||||
'oops' => __( 'Something went wrong with the plugin API.', 'wpcf7sp' ),
|
||||
'notice_can_install_recommended' => _n_noop(
|
||||
/* translators: 1: plugin name(s). * /
|
||||
'This theme recommends the following plugin: %1$s.',
|
||||
'This theme recommends the following plugins: %1$s.',
|
||||
'wpcf7sp'
|
||||
),
|
||||
'notice_ask_to_update' => _n_noop(
|
||||
/* translators: 1: plugin name(s). * /
|
||||
'The following plugin needs to be updated to its latest version to ensure maximum compatibility with this theme: %1$s.',
|
||||
'The following plugins need to be updated to their latest version to ensure maximum compatibility with this theme: %1$s.',
|
||||
'wpcf7sp'
|
||||
),
|
||||
'notice_ask_to_update_maybe' => _n_noop(
|
||||
/* translators: 1: plugin name(s). * /
|
||||
'There is an update available for: %1$s.',
|
||||
'There are updates available for the following plugins: %1$s.',
|
||||
'wpcf7sp'
|
||||
),
|
||||
'notice_can_activate_required' => _n_noop(
|
||||
/* translators: 1: plugin name(s). * /
|
||||
'The following required plugin is currently inactive: %1$s.',
|
||||
'The following required plugins are currently inactive: %1$s.',
|
||||
'wpcf7sp'
|
||||
),
|
||||
'notice_can_activate_recommended' => _n_noop(
|
||||
/* translators: 1: plugin name(s). * /
|
||||
'The following recommended plugin is currently inactive: %1$s.',
|
||||
'The following recommended plugins are currently inactive: %1$s.',
|
||||
'wpcf7sp'
|
||||
),
|
||||
'install_link' => _n_noop(
|
||||
'Begin installing plugin',
|
||||
'Begin installing plugins',
|
||||
'wpcf7sp'
|
||||
),
|
||||
'update_link' => _n_noop(
|
||||
'Begin updating plugin',
|
||||
'Begin updating plugins',
|
||||
'wpcf7sp'
|
||||
),
|
||||
'activate_link' => _n_noop(
|
||||
'Begin activating plugin',
|
||||
'Begin activating plugins',
|
||||
'wpcf7sp'
|
||||
),
|
||||
'return' => __( 'Return to Required Plugins Installer', 'wpcf7sp' ),
|
||||
'plugin_activated' => __( 'Plugin activated successfully.', 'wpcf7sp' ),
|
||||
'activated_successfully' => __( 'The following plugin was activated successfully:', 'wpcf7sp' ),
|
||||
/* translators: 1: plugin name. * /
|
||||
'plugin_already_active' => __( 'No action taken. Plugin %1$s was already active.', 'wpcf7sp' ),
|
||||
/* translators: 1: plugin name. * /
|
||||
'plugin_needs_higher_version' => __( 'Plugin not activated. A higher version of %s is needed for this theme. Please update the plugin.', 'wpcf7sp' ),
|
||||
/* translators: 1: dashboard link. * /
|
||||
'complete' => __( 'All plugins installed and activated successfully. %1$s', 'wpcf7sp' ),
|
||||
'dismiss' => __( 'Dismiss this notice', 'wpcf7sp' ),
|
||||
'notice_cannot_install_activate' => __( 'There are one or more required or recommended plugins to install, update or activate.', 'wpcf7sp' ),
|
||||
'contact_admin' => __( 'Please contact the administrator of this site for help.', 'wpcf7sp' ),
|
||||
|
||||
'nag_type' => '', // Determines admin notice type - can only be one of the typical WP notice classes, such as 'updated', 'update-nag', 'notice-warning', 'notice-info' or 'error'. Some of which may not work as expected in older WP versions.
|
||||
*/
|
||||
),
|
||||
);
|
||||
|
||||
tgmpa( $plugins, $config );
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,226 @@
|
||||
var $ = jQuery.noConflict(),
|
||||
dtx = {
|
||||
queue: [],
|
||||
init: function() {
|
||||
var $inputs = $('input.dtx-pageload[data-dtx-value]');
|
||||
if ($inputs.length) {
|
||||
// If this is any of our built-in shortcodes, see if there's any that can be duplicated via client side
|
||||
$inputs.each(function(i, el) {
|
||||
var $input = $(el),
|
||||
raw_value = $input.attr('data-dtx-value'),
|
||||
v = decodeURIComponent(raw_value).split(' ');
|
||||
if (v.length) {
|
||||
var tag = v[0],
|
||||
atts = {};
|
||||
if (v.length > 1) {
|
||||
for (var x = 1; x < v.length; x++) {
|
||||
var att = v[x].split('=');
|
||||
if (att.length === 2) {
|
||||
var key = att[0];
|
||||
atts[key] = att[1].split("'").join('');
|
||||
}
|
||||
}
|
||||
}
|
||||
var value = '';
|
||||
switch (tag) {
|
||||
case 'CF7_GET':
|
||||
value = dtx.get(atts);
|
||||
break;
|
||||
case 'CF7_referrer':
|
||||
value = dtx.referrer(atts);
|
||||
break;
|
||||
case 'CF7_URL':
|
||||
value = dtx.current_url(atts);
|
||||
break;
|
||||
case 'CF7_get_cookie':
|
||||
value = dtx.get_cookie(atts);
|
||||
break;
|
||||
case 'CF7_guid':
|
||||
value = dtx.guid();
|
||||
break;
|
||||
case 'CF7_get_current_var':
|
||||
if (dtx.validKey(atts, 'key') && atts.key == 'url') {
|
||||
value = dtx.current_url(atts);
|
||||
} else {
|
||||
return; // Do nothing, current page variables are safe to cache, just use the value that was calculated by server
|
||||
}
|
||||
break;
|
||||
case 'CF7_get_post_var': // Current post variables are safe to cache
|
||||
case 'CF7_get_custom_field': // Meta data is safe to cache
|
||||
case 'CF7_get_taxonomy': // Terms are safe to cache
|
||||
case 'CF7_get_attachment': // Media attachment info is safe to cache
|
||||
case 'CF7_bloginfo': // Site info is safe to cache
|
||||
case 'CF7_get_theme_option': // Theme options are safe to cache
|
||||
return; // Do nothing, just use the value that was calculated by server
|
||||
default:
|
||||
if (tag) {
|
||||
// Queue the requests for an AJAX call at the end of init
|
||||
dtx.queue.push({ 'value': raw_value, 'multiline': $input.is('textarea') });
|
||||
}
|
||||
return; // Don't continue after queuing it for AJAX
|
||||
}
|
||||
dtx.set($input, value);
|
||||
}
|
||||
});
|
||||
if (dtx.queue.length) {
|
||||
setTimeout(function() { // Set timeout to force it async
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: dtx_obj.ajax_url,
|
||||
dataType: 'json', // only accept strict JSON objects
|
||||
data: {
|
||||
'action': 'wpcf7dtx',
|
||||
'shortcodes': dtx.queue
|
||||
},
|
||||
cache: false,
|
||||
error: function(xhr, status, error) {
|
||||
console.error('[CF7 DTX AJAX ERROR]', error, status, xhr);
|
||||
},
|
||||
success: function(data, status, xhr) {
|
||||
if (typeof(data) == 'object' && data.length) {
|
||||
$.each(data, function(i, obj) {
|
||||
var $inputs = $('.wpcf7 form input.dtx-pageload[data-dtx-value="' + obj.raw_value + '"]');
|
||||
if ($inputs.length) {
|
||||
dtx.set($inputs, obj.value);
|
||||
$inputs.addClass('dtx-ajax-loaded');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}, 10);
|
||||
}
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Check if Key Exists in Object
|
||||
*/
|
||||
validKey: function(obj, key) {
|
||||
return obj.hasOwnProperty(key) && typeof(obj[key]) == 'string' && obj[key].trim();
|
||||
},
|
||||
/**
|
||||
* Maybe Obfuscate Value
|
||||
*
|
||||
* @see https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/shortcodes/dtx-attribute-obfuscate/
|
||||
*/
|
||||
obfuscate: function(value, atts) {
|
||||
value = value.trim();
|
||||
if (dtx.validKey(atts, 'obfuscate') && atts.obfuscate) {
|
||||
var o = '';
|
||||
for (var i = 0; i < value.length; i++) {
|
||||
o += '&#' + value.codePointAt(i) + ';';
|
||||
}
|
||||
return o;
|
||||
}
|
||||
return value;
|
||||
},
|
||||
/**
|
||||
* Set Value for Form Field
|
||||
*/
|
||||
set: function($input, value) {
|
||||
$input.attr('value', value).addClass('dtx-loaded');
|
||||
},
|
||||
/**
|
||||
* Get Value form URL Query by Key
|
||||
*
|
||||
* @see @see https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/shortcodes/dtx-shortcode-php-get-variables/
|
||||
*/
|
||||
get: function(atts) {
|
||||
if (dtx.validKey(atts, 'key')) {
|
||||
var query = window.location.search;
|
||||
if (query) {
|
||||
query = new URLSearchParams(query);
|
||||
return dtx.obfuscate(query.get(atts.key).trim(), atts);
|
||||
}
|
||||
}
|
||||
return '';
|
||||
},
|
||||
/**
|
||||
* Get Referrering URL
|
||||
*
|
||||
* @see https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/shortcodes/dtx-shortcode-referrer-url/
|
||||
*/
|
||||
referrer: function(atts) {
|
||||
return dtx.obfuscate(document.referrer, atts);
|
||||
},
|
||||
/**
|
||||
* Get Current URL or Part
|
||||
*
|
||||
* @see https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/shortcodes/dtx-shortcode-current-url/
|
||||
*/
|
||||
current_url: function(atts) {
|
||||
if (atts.hasOwnProperty('part')) {
|
||||
var parts = [
|
||||
'scheme', // e.g. `http`
|
||||
'host',
|
||||
'port',
|
||||
'path',
|
||||
'query', // after the question mark ?
|
||||
'fragment' // after the pound sign #
|
||||
];
|
||||
if (parts.includes(atts.part)) {
|
||||
// return part of the url
|
||||
switch (atts.part) {
|
||||
case 'scheme':
|
||||
return dtx.obfuscate(window.location.protocol.replace(':', ''), atts);
|
||||
case 'host':
|
||||
return dtx.obfuscate(window.location.host, atts);
|
||||
case 'port':
|
||||
return dtx.obfuscate(window.location.port, atts);
|
||||
case 'path':
|
||||
return dtx.obfuscate(window.location.pathname, atts);
|
||||
case 'query':
|
||||
return dtx.obfuscate(window.location.search.replace('?', ''), atts);
|
||||
case 'fragment':
|
||||
return dtx.obfuscate(window.location.hash.replace('#', ''), atts);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return dtx.obfuscate(window.location.href, atts); // Return the full url
|
||||
}
|
||||
return '';
|
||||
},
|
||||
/**
|
||||
* Get Cookie Value
|
||||
*
|
||||
* @since 3.3.0
|
||||
*
|
||||
* @see https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/shortcodes/dtx-shortcode-cookie/
|
||||
*/
|
||||
get_cookie: function(atts) {
|
||||
if (atts.hasOwnProperty('key') && typeof(atts.key) == 'string' && atts.key.trim() != '') {
|
||||
var keyValue = document.cookie.match('(^|;) ?' + atts.key.trim() + '=([^;]*)(;|$)');
|
||||
return keyValue ? dtx.obfuscate(keyValue[2], atts) : '';
|
||||
}
|
||||
return '';
|
||||
},
|
||||
/**
|
||||
* Generate a random GUID (globally unique identifier)
|
||||
*
|
||||
* @see https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/shortcodes/dtx-shortcode-guid/
|
||||
*/
|
||||
guid: function() {
|
||||
if (typeof(window.crypto) != 'undefined' && typeof(window.crypto.getRandomValues) != 'undefined') {
|
||||
return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c =>
|
||||
(c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
|
||||
).toUpperCase();
|
||||
}
|
||||
console.warn('[CF7 DTX] Cryptographically secure PRNG is not available for generating GUID value');
|
||||
var d = new Date().getTime(), //Timestamp
|
||||
d2 = ((typeof performance !== 'undefined') && performance.now && (performance.now() * 1000)) || 0; //Time in microseconds since page-load or 0 if unsupported
|
||||
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
|
||||
var r = Math.random() * 16; //random number between 0 and 16
|
||||
if (d > 0) { //Use timestamp until depleted
|
||||
r = (d + r) % 16 | 0;
|
||||
d = Math.floor(d / 16);
|
||||
} else { //Use microseconds since page-load if supported
|
||||
r = (d2 + r) % 16 | 0;
|
||||
d2 = Math.floor(d2 / 16);
|
||||
}
|
||||
return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16).toUpperCase();
|
||||
}).toUpperCase();;
|
||||
}
|
||||
};
|
||||
$(document).ready(dtx.init);
|
||||
2
wp/wp-content/plugins/contact-form-7-dynamic-text-extension/assets/scripts/dtx.min.js
vendored
Normal file
2
wp/wp-content/plugins/contact-form-7-dynamic-text-extension/assets/scripts/dtx.min.js
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
/*! Do not edit, this file is generated automatically - 2023-09-18 14:09:50 EDT */
|
||||
var $=jQuery.noConflict(),dtx={queue:[],init:function(){var e=$("input.dtx-pageload[data-dtx-value]");e.length&&(e.each(function(e,t){var r=$(t),a=r.attr("data-dtx-value"),o=decodeURIComponent(a).split(" ");if(o.length){var n=o[0],c={};if(1<o.length)for(var u=1;u<o.length;u++){var i=o[u].split("="),d;2===i.length&&(c[i[0]]=i[1].split("'").join(""))}var s="";switch(n){case"CF7_GET":s=dtx.get(c);break;case"CF7_referrer":s=dtx.referrer(c);break;case"CF7_URL":s=dtx.current_url(c);break;case"CF7_get_cookie":s=dtx.get_cookie(c);break;case"CF7_guid":s=dtx.guid();break;case"CF7_get_current_var":if(!dtx.validKey(c,"key")||"url"!=c.key)return;s=dtx.current_url(c);break;case"CF7_get_post_var":case"CF7_get_custom_field":case"CF7_get_taxonomy":case"CF7_get_attachment":case"CF7_bloginfo":case"CF7_get_theme_option":return;default:return void(n&&dtx.queue.push({value:a,multiline:r.is("textarea")}))}dtx.set(r,s)}}),dtx.queue.length)&&setTimeout(function(){$.ajax({type:"POST",url:dtx_obj.ajax_url,dataType:"json",data:{action:"wpcf7dtx",shortcodes:dtx.queue},cache:!1,error:function(e,t,r){},success:function(e,t,r){"object"==typeof e&&e.length&&$.each(e,function(e,t){var r=$('.wpcf7 form input.dtx-pageload[data-dtx-value="'+t.raw_value+'"]');r.length&&(dtx.set(r,t.value),r.addClass("dtx-ajax-loaded"))})}})},10)},validKey:function(e,t){return e.hasOwnProperty(t)&&"string"==typeof e[t]&&e[t].trim()},obfuscate:function(e,t){if(e=e.trim(),dtx.validKey(t,"obfuscate")&&t.obfuscate){for(var r="",a=0;a<e.length;a++)r+="&#"+e.codePointAt(a)+";";return r}return e},set:function(e,t){e.attr("value",t).addClass("dtx-loaded")},get:function(e){if(dtx.validKey(e,"key")){var t=window.location.search;if(t)return t=new URLSearchParams(t),dtx.obfuscate(t.get(e.key).trim(),e)}return""},referrer:function(e){return dtx.obfuscate(document.referrer,e)},current_url:function(e){if(!e.hasOwnProperty("part"))return dtx.obfuscate(window.location.href,e);var t;if(["scheme","host","port","path","query","fragment"].includes(e.part))switch(e.part){case"scheme":return dtx.obfuscate(window.location.protocol.replace(":",""),e);case"host":return dtx.obfuscate(window.location.host,e);case"port":return dtx.obfuscate(window.location.port,e);case"path":return dtx.obfuscate(window.location.pathname,e);case"query":return dtx.obfuscate(window.location.search.replace("?",""),e);case"fragment":return dtx.obfuscate(window.location.hash.replace("#",""),e)}return""},get_cookie:function(e){var t;return e.hasOwnProperty("key")&&"string"==typeof e.key&&""!=e.key.trim()&&(t=document.cookie.match("(^|;) ?"+e.key.trim()+"=([^;]*)(;|$)"))?dtx.obfuscate(t[2],e):""},guid:function(){var r,a;return(void 0!==window.crypto&&void 0!==window.crypto.getRandomValues?([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g,e=>(e^crypto.getRandomValues(new Uint8Array(1))[0]&15>>e/4).toString(16)):(r=(new Date).getTime(),a="undefined"!=typeof performance&&performance.now&&1e3*performance.now()||0,"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(e){var t=16*Math.random();return 0<r?(t=(r+t)%16|0,r=Math.floor(r/16)):(t=(a+t)%16|0,a=Math.floor(a/16)),("x"===e?t:3&t|8).toString(16).toUpperCase()}))).toUpperCase()}};$(document).ready(dtx.init);
|
||||
@@ -26,6 +26,14 @@
|
||||
};
|
||||
|
||||
$(function() {
|
||||
$('form.tag-generator-panel input.dtx-option').on('change keyup', wpcf7dtx.taggen.updateOption);
|
||||
$('form.tag-generator-panel .dtx-option').on('change keyup click', wpcf7dtx.taggen.updateOption);
|
||||
$('.contact-form-editor-panel #tag-generator-list a.thickbox.button[href*="inlineId=tag-generator-panel-dynamic_"]').each(function() {
|
||||
var $btn = $(this),
|
||||
name = $btn.text();
|
||||
$btn.addClass('dtx-form-tag');
|
||||
if (name == 'dynamic drop-down menu' || name == 'dynamic checkboxes' || name == 'dynamic radio buttons') {
|
||||
$btn.attr('href', $btn.attr('href').replace('height=500', 'height=750'));
|
||||
}
|
||||
});
|
||||
});
|
||||
})(jQuery);
|
||||
@@ -0,0 +1,2 @@
|
||||
/*! Do not edit, this file is generated automatically - 2023-09-18 14:09:50 EDT */
|
||||
!function(n){"use strict";"undefined"!=typeof wpcf7&&null!==wpcf7&&(window.wpcf7dtx=window.wpcf7dtx||{},wpcf7dtx.taggen={},wpcf7dtx.taggen.escapeRegExp=function(e){return e.replace(/([.*+?^=!:${}()|\[\]\/\\])/g,"\\$1")},wpcf7dtx.taggen.replaceAll=function(e,t,n,a){var c;return null!=e&&"string"==typeof e&&""!==e.trim()&&-1<e.indexOf(t)?(c=new RegExp(wpcf7dtx.taggen.escapeRegExp(t),"g"),a&&(c=new RegExp(t,"g")),e.replace(c,n)):e},wpcf7dtx.taggen.updateOption=function(e){var e=n(e.currentTarget),t=encodeURIComponent(wpcf7dtx.taggen.replaceAll(e.val(),"'","'"));e.siblings('input[type="hidden"].option').val(t)},n(function(){n("form.tag-generator-panel .dtx-option").on("change keyup click",wpcf7dtx.taggen.updateOption),n('.contact-form-editor-panel #tag-generator-list a.thickbox.button[href*="inlineId=tag-generator-panel-dynamic_"]').each(function(){var e=n(this),t=e.text();e.addClass("dtx-form-tag"),"dynamic drop-down menu"!=t&&"dynamic checkboxes"!=t&&"dynamic radio buttons"!=t||e.attr("href",e.attr("href").replace("height=500","height=750"))})}))}(jQuery);
|
||||
@@ -1,7 +1,46 @@
|
||||
.tag-generator-panel[data-id^="dynamic_select"],
|
||||
.tag-generator-panel[data-id^="dynamic_checkbox"],
|
||||
.tag-generator-panel[data-id^="dynamic_radio"] {
|
||||
height: 740px;
|
||||
}
|
||||
|
||||
#tag-generator-list a.button.dtx-form-tag {
|
||||
border-color: #765cb9;
|
||||
color: #765cb9;
|
||||
}
|
||||
|
||||
.tag-generator-panel table.form-table th {
|
||||
width: 130px;
|
||||
}
|
||||
|
||||
.tag-generator-panel .control-box input.oneline {
|
||||
.tag-generator-panel table.form-table td small {
|
||||
display: block;
|
||||
margin-top: 0.25em;
|
||||
}
|
||||
|
||||
.tag-generator-panel .control-box input.oneline,
|
||||
.tag-generator-panel .control-box input.multiline,
|
||||
.tag-generator-panel .control-box textarea {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.tag-generator-panel .control-box input[list],
|
||||
.tag-generator-panel .control-box input.multiline,
|
||||
.tag-generator-panel .control-box textarea {
|
||||
height: 30px;
|
||||
min-height: 30px;
|
||||
}
|
||||
|
||||
.tag-generator-panel .control-box input.multiline {
|
||||
display: inline-block;
|
||||
/* -webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
appearance: none; */
|
||||
resize: vertical;
|
||||
overflow-x: hidden;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
.tag-generator-panel .control-box textarea {
|
||||
height: 3.5em;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
.tag-generator-panel[data-id^=dynamic_checkbox],.tag-generator-panel[data-id^=dynamic_radio],.tag-generator-panel[data-id^=dynamic_select]{height:740px}#tag-generator-list a.button.dtx-form-tag{border-color:#765cb9;color:#765cb9}.tag-generator-panel table.form-table th{width:130px}.tag-generator-panel table.form-table td small{display:block;margin-top:.25em}.tag-generator-panel .control-box input.multiline,.tag-generator-panel .control-box input.oneline,.tag-generator-panel .control-box textarea{width:100%}.tag-generator-panel .control-box input.multiline,.tag-generator-panel .control-box input[list],.tag-generator-panel .control-box textarea{height:30px;min-height:30px}.tag-generator-panel .control-box input.multiline{display:inline-block;resize:vertical;overflow-x:hidden;overflow-y:scroll}.tag-generator-panel .control-box textarea{height:3.5em}
|
||||
@@ -0,0 +1,211 @@
|
||||
== Changelog ==
|
||||
|
||||
= 4.1.0 =
|
||||
|
||||
* Feature: Looks for a `dtx.php` file in the `wp_content` directory to maybe load custom shortcodes, [see support thread](https://wordpress.org/support/topic/how-to-avoid-custom-shortcodes-being-overwritten-on-updates/)
|
||||
* Feature: Looks for a `dtx.php` file in the current active theme's directory to maybe load custom shortcodes, [see support thread](https://wordpress.org/support/topic/how-to-avoid-custom-shortcodes-being-overwritten-on-updates/)
|
||||
* Feature: Looks for a `dtx.php` file in the current active theme's parent directory to maybe load custom shortcodes, [see support thread](https://wordpress.org/support/topic/how-to-avoid-custom-shortcodes-being-overwritten-on-updates/)
|
||||
* Fix: addressed user reported bug, [see support thread](https://wordpress.org/support/topic/fatal-error-v4-0-3/)
|
||||
|
||||
= 4.0.3 =
|
||||
|
||||
* Feature: Added `exclusive` option to checkbox tag generator
|
||||
* Fix: addressed bug that put all dynamic checkbox/radio options into one
|
||||
* Fix: addressed bug in frontend validator for multiple selected values
|
||||
|
||||
= 4.0.2 =
|
||||
|
||||
* Fix: addressed bug that put all dynamic select options into one, [see support thread](https://wordpress.org/support/topic/dynamic-select-get-option-values-from-shortcode/)
|
||||
* Update: sanitizing and escaping filters now accept `none` as value for `$type` to bypass. Use with caution.
|
||||
|
||||
= 4.0.1 =
|
||||
|
||||
* Fix: addressed bug that prevented translation for cache compatibility description
|
||||
|
||||
= 4.0.0 =
|
||||
|
||||
* Major: modified function names
|
||||
* Major: deprecated `dynamictext` and `dynamichidden` form tags in favor of `dynamic_text` and `dynamic_hidden`. For more information, see the [knowledge base](https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/form-tags/?utm_source=wordpress.org&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=readme)
|
||||
* Feature: introduced `dynamic_email` form tag. For usage details, see the [knowledge base](https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/form-tags/dynamic-email/?utm_source=wordpress.org&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=readme)
|
||||
* Feature: introduced `dynamic_url` form tag. For usage details, see the [knowledge base](https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/form-tags/dynamic-url/?utm_source=wordpress.org&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=readme)
|
||||
* Feature: introduced `dynamic_tel` form tag. For usage details, see the [knowledge base](https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/form-tags/dynamic-tel/?utm_source=wordpress.org&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=readme)
|
||||
* Feature: introduced `dynamic_number` form tag. For usage details, see the [knowledge base](https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/form-tags/dynamic-number/?utm_source=wordpress.org&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=readme)
|
||||
* Feature: introduced `dynamic_range` form tag. For usage details, see the [knowledge base](https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/form-tags/dynamic-range/?utm_source=wordpress.org&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=readme)
|
||||
* Feature: introduced `dynamic_textarea` form tag. For usage details, see the [knowledge base](https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/form-tags/dynamic-textarea/?utm_source=wordpress.org&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=readme)
|
||||
* Feature: introduced `dynamic_select` form tag. For usage details, see the [knowledge base](https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/form-tags/dynamic-select/?utm_source=wordpress.org&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=readme)
|
||||
* Feature: introduced `dynamic_radio` form tag. For usage details, see the [knowledge base](https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/form-tags/dynamic-radio/?utm_source=wordpress.org&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=readme)
|
||||
* Feature: introduced `dynamic_date` form tag. For usage details, see the [knowledge base](https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/form-tags/dynamic-date/?utm_source=wordpress.org&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=readme)
|
||||
* Feature: introduced `dynamic_submit` form tag. For usage details, see the [knowledge base](https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/form-tags/dynamic-submit/?utm_source=wordpress.org&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=readme)
|
||||
* Feature: introduced `dtx_hide_blank` form tag attribute for `dynamic_select`. For usage details, see the [knowledge base](https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/form-tags/dynamic-select/?utm_source=wordpress.org&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=readme)
|
||||
* Feature: introduced `dtx_disable_blank` form tag attribute for `dynamic_select`. For usage details, see the [knowledge base](https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/form-tags/dynamic-select/?utm_source=wordpress.org&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=readme)
|
||||
* Feature: added mail validation for `dynamic_email` and `dynamic_hidden` for backend configuration. For more information, see the [FAQ](https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/frequently-asked-questions/?utm_source=wordpress.org&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=readme)
|
||||
* Feature: added the Akismet feature to DTX text, email, and URL form tags.
|
||||
* Update: adjusted how queued values were sent for cache compatibility mode to allow for multiline values in textareas
|
||||
* Removed unused utility functions
|
||||
|
||||
= 3.5.4 =
|
||||
|
||||
* Fix: Updated JavaScript to prevent cacheable fields from making unnecessary AJAX requests
|
||||
|
||||
= 3.5.3 =
|
||||
|
||||
* Update: removed the use of sessions, [see support thread](https://wordpress.org/support/topic/add-option-to-disable-session-data/)
|
||||
|
||||
= 3.5.2 =
|
||||
|
||||
* Fix: Updated the `CF7_URL` shortcode to only use `network_home_url()` for multisite installs that do not use subdomains, and use `home_url()` for all others to [maybe address this support thread](https://wordpress.org/support/topic/cf7_url-return-only-domain-and-not-subdomain/)
|
||||
* Fix: Removed a lingering debug call
|
||||
|
||||
= 3.5.1 =
|
||||
|
||||
* Fix: fixed bug so tag generator for dynamic fields work on "Add New Contact Form" page of Contact Form 7
|
||||
* Updated: Updated text in tag generator for cache compatible checkbox and added link to documentation
|
||||
|
||||
= 3.5.0 =
|
||||
|
||||
* Feature: Added the `dtx_pageload` form tag attribute for cache compatibility. For usage details, see the [knowledge base](https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/form-tag-attribute-after-page-load/?utm_source=wordpress.org&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=readme)
|
||||
* Fix: Updated to be compatible with WordPress version 6.3
|
||||
* Fix: Addressed a bug where `scheme` in `CF7_URL part='scheme'` was incorrectly sanitizing as URL instead of text
|
||||
* Fix: Fixed `wp_kses()` in tag generator that stripped out link opening in new tab
|
||||
* Update: `CF7_get_current_var` utilizes PHP session variables where appropriate
|
||||
* Update: All JavaScript assets will load with the `defer` strategy in the footer in [WordPress 6.3](https://make.wordpress.org/core/2023/07/14/registering-scripts-with-async-and-defer-attributes-in-wordpress-6-3/)
|
||||
|
||||
= 3.4.0 =
|
||||
|
||||
* Feature: Feature: Added the `CF7_get_current_var` shortcode, [see support thread for user request](https://wordpress.org/support/topic/wrong-page-title-7/). For usage details, see the [knowledge base](https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/shortcodes/dtx-shortcode-current-variables/?utm_source=wordpress.org&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=readme)
|
||||
* Fix: Updated the `CF7_URL` shortcode to no longer check for ports since that's handled in `network_home_url()` function, [see support thread](https://wordpress.org/support/topic/version-3-3-0-breaking/)
|
||||
|
||||
= 3.3.0 =
|
||||
|
||||
* Feature: Added the `CF7_get_cookie` shortcode. For usage details, see the [knowledge base](https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/shortcodes/dtx-shortcode-cookie/?utm_source=wordpress.org&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=readme)
|
||||
* Feature: Added the `CF7_get_taxonomy` shortcode. For usage details, see the [knowledge base](https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/shortcodes/dtx-shortcode-taxonomy/?utm_source=wordpress.org&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=readme)
|
||||
* Feature: Added the `CF7_get_theme_option` shortcode. For usage details, see the [knowledge base](https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/shortcodes/dtx-shortcode-theme-option/?utm_source=wordpress.org&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=readme)
|
||||
* Feature: Added `wpcf7dtx_sanitize` filter that sanitizes attribute values in built-in shortcodes
|
||||
* Feature: Added `wpcf7dtx_escape` filter that escapes values in built-in shortcodes
|
||||
* Feature: Added `wpcf7dtx_allow_protocols` filter to customize allowed protocols in escaping URLs in built-in shortcodes
|
||||
* Fix: Updated how plugin gets dynamic value in form tags, now uses `wpcf7dtx_get_dynamic()` function
|
||||
* Fix: Added case-insensitive ID in `CF7_get_post_var`
|
||||
* Fix: Sanitizes post variable keys as keys in `wpcf7dtx_get_post_var()`
|
||||
* Fix: Updated `wpcf7dtx_get_post_id()` to pull from "the loop" if `$post` is unavailable and now used consistently across built-in shortcodes
|
||||
* Fix: Updated tag markup to be compatible with Contact Form 7 version 5.6 Beta for successful form validation, [see support thread](https://wordpress.org/support/topic/required-field-no-error-is-output-when-validating-when-field-is-empty/)
|
||||
* Fix: Updated the `CF7_URL` shortcode to use `network_home_url()`, [see support thread](https://wordpress.org/support/topic/current-url-not-working/)
|
||||
* Fix: Updated GUID function to return appropriately escaped values
|
||||
* Fix: Updated all existing built-in shortcodes to use the the sanitizing, escaping, and obfuscating shortcodes, [see support thread](https://wordpress.org/support/topic/cant-get-obfuscate-to-work/)
|
||||
* Fix: Marked compatible with WordPress core version 6.2.
|
||||
|
||||
= 3.2 =
|
||||
|
||||
* Feature: Add optional 'part' parameter to CF7_URL shortcode to retrieve Host, Query, or Path from current URL
|
||||
* Updated minimum PHP requirement to 7.4 moving forward
|
||||
* Update branding assets
|
||||
* Update Tested Up To to 6.1.1
|
||||
* Plugin will now be jointly maintained by [SevenSpark](https://sevenspark.com/) and [AuRise Creative](https://aurisecreative.com)
|
||||
|
||||
= 3.1.3 =
|
||||
|
||||
* Fix: Fixed the syntax error that reappeared in 3.1.2.
|
||||
|
||||
= 3.1.2 =
|
||||
|
||||
**Release Date: January 27, 2023**
|
||||
|
||||
* Fix: updated the text domain to match the plugin slug
|
||||
* Fix: updated all of the translated strings to match
|
||||
|
||||
= 3.1.1 =
|
||||
|
||||
**Release Date: January 26, 2023**
|
||||
|
||||
* Fix: Fixed the syntax error: Parse error: syntax error, unexpected `)` in /wp-content/plugins/contact-form-7-dynamic-text extension/includes/admin.php on line 212
|
||||
|
||||
= 3.1.0 =
|
||||
|
||||
**Release Date: January 25, 2023**
|
||||
|
||||
* Feature: Added the `CF7_get_attachment` shortcode. For usage details, see the [knowledge base](https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/shortcodes/dtx-shortcode-media-attachment/?utm_source=wordpress.org&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=readme)
|
||||
* Feature: Added the `CF7_guid` shortcode. For usage details, see the [knowledge base](https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/shortcodes/dtx-shortcode-guid/?utm_source=wordpress.org&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=readme).
|
||||
* Feature: Added the dynamic placeholder option to the dynamic form tags that allows you to specify dynamic or static placeholder content while also setting dynamic values. For usage details, see the [knowledge base](https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/shortcodes/dtx-attribute-placeholder/?utm_source=wordpress.org&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=readme)
|
||||
* Feature: Added a "required" dynamic hidden tag (e.g., `[dynamichidden* ...]`). It is identical to the original dynamic hidden tag (as in the field is not actually validated as required because it is hidden); it just doesn't break your website if you use it. This feature was requested by a user.
|
||||
* Feature: Added the `obfuscate` attribute to all included shortcodes
|
||||
|
||||
= 3.0.0 =
|
||||
|
||||
**Release Date: January 17, 2023**
|
||||
|
||||
* Major: Plugin was adopted by AuRise Creative
|
||||
* Major: All functions use the `wpcf7dtx_` prefix
|
||||
* Feature: Added a `post_id` key for the `CF7_get_post_var` shortcode so you can specify a different post
|
||||
* Feature: Updated the `CF7_get_current_user` shortcode to be able to pull data from user metadata too
|
||||
* Feature: Added the "obfuscate" option to `CF7_get_custom_field` shortcode
|
||||
* Feature: Added the "placeholder" checkbox option to the `dynamictext` tag
|
||||
* Fix: Added additional validation for post ID input
|
||||
* Fix: Added additional validation for the `key` attribute in the `CF7_GET` and `CF7_POST` shortcodes
|
||||
* Fix: Shortcode keys are normalized into lowercase before processing
|
||||
* Security: Sanitizing URLs for the `CF7_URL` and `CF7_referrer` shortcode outputs
|
||||
* Feature/Security: Added a `allowed_protocols` attribute to the `CF7_URL` and `CF7_referrer` shortcodes that defaults to `http,https`
|
||||
|
||||
= 2.0.3 =
|
||||
|
||||
* Security: [Fix Reflected XSS](https://web.archive.org/web/20230121180428/https://sevenspark.com/docs/cf7-dtx-security-2019-07-24)
|
||||
|
||||
= 2.0.2.1 =
|
||||
|
||||
* Update changelog properly for 2.0.2 changes:
|
||||
|
||||
= 2.0.2 =
|
||||
|
||||
* Update deprecated `get_currentuserinfo()` function to `wp_get_current_user()`
|
||||
* Update deprecated functions from `WPCF7_add_shortcode` to `WPCF7_add_formtag` and class from `WPCF7_Shortcode` to `WPCF7_FormTag` to comply with CF7 4.6 changes
|
||||
|
||||
= 2.0.1 =
|
||||
|
||||
* Hook change to guarantee the plugin only runs when Contact Form 7 is present in the admin (avoids errors if Contact Form 7 is disabled, or if there is a plugin sequencing issue)
|
||||
|
||||
= 2.0 =
|
||||
|
||||
* Complete rewrite for Compatibility with Contact Form 7 v4
|
||||
|
||||
= 1.2 =
|
||||
|
||||
* Compatibility update for Contact Form 7 v3.9
|
||||
|
||||
= 1.1.0.2 =
|
||||
|
||||
* Updated to work with Contact Form 7 v3.7.x
|
||||
|
||||
= 1.1.0.1 =
|
||||
|
||||
* Removed undefined variable warning
|
||||
|
||||
= 1.1 =
|
||||
|
||||
* Updated for compatibility with Contact Form 7 v3.6
|
||||
* Added Referrer shortcode
|
||||
|
||||
= 1.0.4.2 =
|
||||
|
||||
* Fixed a bug that created repeating square brackets around dynamic text values in cases where the form doesn't validate and JavaScript is deactivated.
|
||||
|
||||
= 1.0.4.1 =
|
||||
|
||||
* Removed trailing whitespace to fix "Headers already sent" errors
|
||||
|
||||
= 1.0.4 =
|
||||
|
||||
* Added Current User Info shortcode
|
||||
* Added Post Custom Field shortcode (with obfuscation support)
|
||||
* Added Hidden Field capability
|
||||
|
||||
= 1.0.3 =
|
||||
|
||||
* Added $_POST shortcode
|
||||
* Added current post/page variable shortcode
|
||||
* Added current URL shortcode
|
||||
|
||||
= 1.0.2 =
|
||||
|
||||
* Fixed administrative control panel dependency issue
|
||||
|
||||
= 1.0.1 =
|
||||
|
||||
* Fixed dependency issue.
|
||||
@@ -4,7 +4,7 @@
|
||||
* Plugin Name: Contact Form 7 - Dynamic Text Extension
|
||||
* Plugin URI: https://sevenspark.com/goods/contact-form-7-dynamic-text-extension
|
||||
* Description: This plugin extends Contact Form 7 by adding dynamic form fields that accept any shortcode to generate default values and placeholder text. Requires Contact Form 7.
|
||||
* Version: 3.2
|
||||
* Version: 4.1.0
|
||||
* Author: SevenSpark, AuRise Creative
|
||||
* Author URI: https://sevenspark.com
|
||||
* License: GPL2
|
||||
@@ -32,7 +32,7 @@
|
||||
*/
|
||||
|
||||
// Define current version
|
||||
define('WPCF7DTX_VERSION', '3.2');
|
||||
define('WPCF7DTX_VERSION', '4.1.0');
|
||||
|
||||
// Define root directory
|
||||
defined('WPCF7DTX_DIR') || define('WPCF7DTX_DIR', __DIR__);
|
||||
@@ -47,99 +47,238 @@ defined('WPCF7DTX_FILE') || define('WPCF7DTX_FILE', __FILE__);
|
||||
*/
|
||||
function wpcf7dtx_init()
|
||||
{
|
||||
add_action('wpcf7_init', 'wpcf7dtx_add_shortcode_dynamictext'); // Add custom form tags to CF7
|
||||
add_filter('wpcf7_validate_dynamictext*', 'wpcf7dtx_dynamictext_validation_filter', 10, 2); // Validate custom form tags
|
||||
add_action('wpcf7_init', 'wpcf7dtx_add_shortcodes'); // Add custom form tags to CF7
|
||||
}
|
||||
add_action('plugins_loaded', 'wpcf7dtx_init', 20);
|
||||
|
||||
/**
|
||||
* DTX Formg Tag Configuration
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function wpcf7dtx_config()
|
||||
{
|
||||
global $wpcf7_dynamic_fields_config;
|
||||
if (!isset($wpcf7_dynamic_fields_config)) {
|
||||
$wpcf7_dynamic_fields_config = array(
|
||||
'dynamic_text' => array(
|
||||
'title' => __('dynamic text', 'contact-form-7-dynamic-text-extension'), //title
|
||||
'options' => array('placeholder', 'readonly', 'dtx_pageload'),
|
||||
'description' => __('a single-line plain text', 'contact-form-7-dynamic-text-extension')
|
||||
),
|
||||
'dynamic_hidden' => array(
|
||||
'title' => __('dynamic hidden', 'contact-form-7-dynamic-text-extension'), //title
|
||||
'options' => array('dtx_pageload'),
|
||||
'description' => __('a single-line plain text hidden input field', 'contact-form-7-dynamic-text-extension'),
|
||||
'features' => array(
|
||||
'display-hidden' => true // Generates an HTML element that is not visible
|
||||
)
|
||||
),
|
||||
'dynamic_email' => array(
|
||||
'title' => __('dynamic email', 'contact-form-7-dynamic-text-extension'), //title
|
||||
'options' => array('placeholder', 'readonly', 'dtx_pageload'),
|
||||
'description' => __('a single-line email address input field', 'contact-form-7-dynamic-text-extension')
|
||||
),
|
||||
'dynamic_url' => array(
|
||||
'title' => __('dynamic URL', 'contact-form-7-dynamic-text-extension'), //title
|
||||
'options' => array('placeholder', 'readonly', 'dtx_pageload'),
|
||||
'description' => __('a single-line URL input field', 'contact-form-7-dynamic-text-extension')
|
||||
),
|
||||
'dynamic_tel' => array(
|
||||
'title' => __('dynamic tel', 'contact-form-7-dynamic-text-extension'), //title
|
||||
'options' => array('placeholder', 'readonly', 'pattern'),
|
||||
'description' => __('a single-line telephone number input field', 'contact-form-7-dynamic-text-extension')
|
||||
),
|
||||
'dynamic_number' => array(
|
||||
'title' => __('dynamic number', 'contact-form-7-dynamic-text-extension'), //title
|
||||
'options' => array('placeholder', 'readonly', 'min', 'max', 'step', 'pattern'),
|
||||
'description' => __('a numeric input field displayed as a number spinbox', 'contact-form-7-dynamic-text-extension')
|
||||
),
|
||||
'dynamic_range' => array(
|
||||
'title' => __('dynamic range', 'contact-form-7-dynamic-text-extension'), //title
|
||||
'options' => array('placeholder', 'readonly', 'min', 'max', 'step', 'pattern'),
|
||||
'description' => __('a numeric input field displayed as a slider between a minimum and maximum range', 'contact-form-7-dynamic-text-extension')
|
||||
),
|
||||
'dynamic_textarea' => array(
|
||||
'title' => __('dynamic textarea', 'contact-form-7-dynamic-text-extension'), //title
|
||||
'options' => array('placeholder', 'readonly', 'dtx_pageload'),
|
||||
'description' => __('a multi-line plain text input field', 'contact-form-7-dynamic-text-extension')
|
||||
),
|
||||
'dynamic_select' => array(
|
||||
'title' => __('dynamic drop-down menu', 'contact-form-7-dynamic-text-extension'), //title
|
||||
'options' => array('placeholder', 'readonly', 'multiple', 'include_blank'),
|
||||
'description' => __('a drop-down menu (i.e select input field)', 'contact-form-7-dynamic-text-extension'),
|
||||
'features' => array(
|
||||
'selectable-values' => true // Generates an option (or group of options) from which you can select one or more options
|
||||
)
|
||||
),
|
||||
'dynamic_checkbox' => array(
|
||||
'title' => __('dynamic checkboxes', 'contact-form-7-dynamic-text-extension'), //title
|
||||
'options' => array('readonly', 'label_first', 'use_label_element', 'exclusive'),
|
||||
'description' => __('a group of checkboxes', 'contact-form-7-dynamic-text-extension'),
|
||||
'features' => array(
|
||||
'multiple-controls-container' => true, // Generates an HTML element that can contain multiple form controls
|
||||
'selectable-values' => true // Generates an option (or group of options) from which you can select one or more options
|
||||
)
|
||||
),
|
||||
'dynamic_radio' => array(
|
||||
'title' => __('dynamic radio buttons', 'contact-form-7-dynamic-text-extension'), //title
|
||||
'options' => array('readonly', 'label_first', 'use_label_element'),
|
||||
'description' => __('a group of radio buttons', 'contact-form-7-dynamic-text-extension'),
|
||||
'features' => array(
|
||||
'multiple-controls-container' => true, // Generates an HTML element that can contain multiple form controls
|
||||
'selectable-values' => true // Generates an option (or group of options) from which you can select one or more options
|
||||
)
|
||||
),
|
||||
'dynamic_date' => array(
|
||||
'title' => __('dynamic date', 'contact-form-7-dynamic-text-extension'), //title
|
||||
'options' => array('placeholder', 'readonly', 'min', 'max'),
|
||||
'description' => __('a date input field', 'contact-form-7-dynamic-text-extension')
|
||||
),
|
||||
'dynamic_submit' => array(
|
||||
'title' => __('dynamic submit', 'contact-form-7-dynamic-text-extension'), //title
|
||||
'options' => array('dtx_pageload'),
|
||||
'description' => __('a submit button', 'contact-form-7-dynamic-text-extension')
|
||||
)
|
||||
);
|
||||
}
|
||||
return $wpcf7_dynamic_fields_config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add Custom Shortcodes to Contact Form 7
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function wpcf7dtx_add_shortcode_dynamictext()
|
||||
function wpcf7dtx_add_shortcodes()
|
||||
{
|
||||
//Add the dynamic text and hidden form fields
|
||||
wpcf7_add_form_tag(
|
||||
array(
|
||||
'dynamictext', 'dynamictext*',
|
||||
'dynamichidden', 'dynamichidden*' //Required hidden fields do nothing
|
||||
),
|
||||
'wpcf7dtx_dynamictext_shortcode_handler', //Callback
|
||||
array('name-attr' => true) //Features
|
||||
//Add the dynamic form fields
|
||||
foreach (wpcf7dtx_config() as $form_tag => $field) {
|
||||
$input_type = str_replace('dynamic_', '', $form_tag);
|
||||
$tag_types = array($form_tag, "$form_tag*");
|
||||
$callback = 'wpcf7dtx_shortcode_handler';
|
||||
$features = array_merge(array('name-attr' => true), wpcf7dtx_array_has_key('features', $field, array()));
|
||||
switch ($input_type) {
|
||||
case 'text':
|
||||
case 'hidden':
|
||||
// Add deprecated tags
|
||||
$dep_tag = str_replace('_', '', $form_tag);
|
||||
$tag_types[] = $dep_tag;
|
||||
$tag_types[] = "$dep_tag*";
|
||||
add_filter("wpcf7_validate_$dep_tag*", 'wpcf7dtx_validation_filter', 20, 2); // Validate required deprecated form tags
|
||||
break;
|
||||
case 'submit':
|
||||
case 'reset':
|
||||
$callback = 'wpcf7dtx_button_shortcode_handler';
|
||||
$features['name-attr'] = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
add_filter("wpcf7_validate_$form_tag*", 'wpcf7dtx_validation_filter', 20, 2); // Validate required custom form tags
|
||||
wpcf7_add_form_tag($tag_types, $callback, $features);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register Frontend Script
|
||||
*
|
||||
* Register the frontend script to be optionally loaded later.
|
||||
*
|
||||
* @since 3.5.0
|
||||
*
|
||||
* @param string $hook Hook suffix for the current page
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function wpcf7dtx_enqueue_frontend_assets($hook = '')
|
||||
{
|
||||
$debug = defined('WP_DEBUG') && constant('WP_DEBUG');
|
||||
$url = plugin_dir_url(WPCF7DTX_FILE);
|
||||
$path = plugin_dir_path(WPCF7DTX_FILE);
|
||||
wp_register_script(
|
||||
'wpcf7dtx', // Handle
|
||||
$url . 'assets/scripts/dtx' . ($debug ? '' : '.min') . '.js', // Source
|
||||
array('jquery-core'), // Dependencies
|
||||
$debug ? @filemtime($path . 'assets/scripts/dtx.js') : WPCF7DTX_VERSION, // Version
|
||||
array('in_footer' => true, 'strategy' => 'defer') // Defer loading in footer
|
||||
|
||||
);
|
||||
wp_localize_script(
|
||||
'wpcf7dtx', // Handle
|
||||
'dtx_obj', // Object
|
||||
array('ajax_url' => admin_url('admin-ajax.php')) // Data
|
||||
);
|
||||
}
|
||||
add_action('wp_enqueue_scripts', 'wpcf7dtx_enqueue_frontend_assets');
|
||||
|
||||
/**
|
||||
* Include Utility Functions
|
||||
*/
|
||||
include_once(WPCF7DTX_DIR . '/includes/utilities.php');
|
||||
|
||||
/**
|
||||
* Include Validation Functions
|
||||
*/
|
||||
include_once(WPCF7DTX_DIR . '/includes/validation.php');
|
||||
|
||||
/**
|
||||
* Form Tag Handler
|
||||
*
|
||||
* @param WPCF7_FormTag $tag
|
||||
* @param WPCF7_FormTag $tag Current Contact Form 7 tag object
|
||||
*
|
||||
* @return string HTML output of the shortcode
|
||||
*/
|
||||
function wpcf7dtx_dynamictext_shortcode_handler($tag)
|
||||
function wpcf7dtx_shortcode_handler($tag)
|
||||
{
|
||||
$tag = new WPCF7_FormTag($tag);
|
||||
// Name attribute is required for these form tags
|
||||
if (empty($tag->name)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
//Validate
|
||||
// Validate
|
||||
$validation_error = wpcf7_get_validation_error($tag->name);
|
||||
|
||||
//Configure classes
|
||||
$class = wpcf7_form_controls_class($tag->type, 'wpcf7dtx-dynamictext');
|
||||
if ($validation_error) {
|
||||
$class .= ' wpcf7-not-valid';
|
||||
}
|
||||
|
||||
//Configure input attributes
|
||||
$atts = array();
|
||||
$atts['type'] = sanitize_key(str_replace(array('dynamic_', 'dynamic'), '', $tag->basetype));
|
||||
$atts['name'] = $tag->name;
|
||||
$atts['id'] = $tag->get_id_option();
|
||||
$atts['class'] = $tag->get_class_option($class);
|
||||
$atts['tabindex'] = $tag->get_option('tabindex', 'int', true);
|
||||
$atts['id'] = strval($tag->get_id_option());
|
||||
$atts['tabindex'] = $tag->get_option('tabindex', 'signed_int', true);
|
||||
$atts['size'] = $tag->get_size_option('40');
|
||||
$atts['maxlength'] = $tag->get_maxlength_option();
|
||||
$atts['minlength'] = $tag->get_minlength_option();
|
||||
$atts['aria-invalid'] = $validation_error ? 'true' : 'false';
|
||||
switch ($tag->basetype) {
|
||||
case 'dynamichidden':
|
||||
$atts['type'] = 'hidden'; //Override type as hidden
|
||||
break;
|
||||
default: // Includes `dynamictext`
|
||||
$atts['type'] = 'text'; //Override type as text
|
||||
break;
|
||||
}
|
||||
if ($atts['maxlength'] && $atts['minlength'] && $atts['maxlength'] < $atts['minlength']) {
|
||||
unset($atts['maxlength'], $atts['minlength']);
|
||||
$atts['class'] = explode(' ', wpcf7_form_controls_class($atts['type']));
|
||||
$atts['class'][] = 'wpcf7dtx';
|
||||
$atts['class'][] = sanitize_html_class('wpcf7dtx-' . $atts['type']);
|
||||
if ($validation_error) {
|
||||
$atts['class'][] = 'wpcf7-not-valid';
|
||||
$atts['aria-invalid'] = 'true';
|
||||
$atts['aria-describedby'] = wpcf7_get_validation_error_reference($tag->name);
|
||||
} else {
|
||||
$atts['aria-invalid'] = 'false';
|
||||
}
|
||||
|
||||
if ($tag->has_option('readonly')) {
|
||||
$atts['readonly'] = 'readonly';
|
||||
}
|
||||
if ($tag->is_required() && $atts['type'] !== 'hidden') {
|
||||
// Add required attribute to applicable input types
|
||||
if ($tag->is_required() && !in_array($atts['type'], array('hidden', 'quiz'))) {
|
||||
$atts['aria-required'] = 'true';
|
||||
$atts['required'] = 'required';
|
||||
}
|
||||
|
||||
// Evaluate the dynamic value
|
||||
$value = wpcf7_get_hangover($tag->name, $tag->get_default_option(strval(reset($tag->values)))); // Input value
|
||||
$scstr = '[' . $value . ']';
|
||||
$scval = do_shortcode($scstr); //Shortcode value
|
||||
if ($scval !== $scstr) {
|
||||
$value = $scval; //Set the input value to the evaluated shortcode
|
||||
}
|
||||
$sanitize_type = $atts['type'] == 'textarea' ? $atts['type'] : 'auto';
|
||||
$value = wpcf7dtx_get_dynamic(false, $tag, $sanitize_type);
|
||||
|
||||
// Identify placeholder
|
||||
if ($tag->has_option('placeholder') || $tag->has_option('watermark')) {
|
||||
//Reverse engineer what JS did (converted quotes to HTML entities --> URL encode) then sanitize
|
||||
$placeholder = sanitize_text_field(html_entity_decode(urldecode(implode('', (array)$tag->get_option('placeholder'))), ENT_QUOTES));
|
||||
$placeholder = html_entity_decode(urldecode($tag->get_option('placeholder', '', true)), ENT_QUOTES);
|
||||
if ($placeholder) {
|
||||
$scpstr = '[' . $placeholder . ']';
|
||||
$scpval = do_shortcode($scpstr); //Shortcode value
|
||||
if ($scpval !== $scpstr) {
|
||||
$placeholder = $scpval; //Set the placeholder value to the evaluated shortcode
|
||||
}
|
||||
//If a different placeholder text has been specified, set both attributes
|
||||
$placeholder = wpcf7dtx_get_dynamic($placeholder, false, $sanitize_type);
|
||||
$atts['placeholder'] = $placeholder;
|
||||
$atts['value'] = $value;
|
||||
} else {
|
||||
@@ -150,58 +289,233 @@ function wpcf7dtx_dynamictext_shortcode_handler($tag)
|
||||
$atts['value'] = $value;
|
||||
}
|
||||
|
||||
//Output the HTML
|
||||
return sprintf(
|
||||
'<span class="wpcf7-form-control-wrap %s"><input %s />%s</span>',
|
||||
sanitize_html_class($tag->name),
|
||||
wpcf7_format_atts($atts), //This function already escapes attribute values
|
||||
$validation_error
|
||||
// Page load attribute
|
||||
if ($tag->has_option('dtx_pageload') && is_array($tag->raw_values) && count($tag->raw_values)) {
|
||||
$atts['data-dtx-value'] = rawurlencode(sanitize_text_field($tag->raw_values[0]));
|
||||
$atts['class'][] = 'dtx-pageload';
|
||||
if (wp_style_is('wpcf7dtx', 'registered') && !wp_script_is('wpcf7dtx', 'queue')) {
|
||||
// If already registered, just enqueue it
|
||||
wp_enqueue_script('wpcf7dtx');
|
||||
} elseif (!wp_style_is('wpcf7dtx', 'registered')) {
|
||||
// If not registered, do that first, then enqueue it
|
||||
wpcf7dtx_enqueue_frontend_assets();
|
||||
wp_enqueue_script('wpcf7dtx');
|
||||
}
|
||||
}
|
||||
|
||||
// Additional configuration based on form field type
|
||||
if (in_array($atts['type'], array('select', 'checkbox', 'radio'))) {
|
||||
/**
|
||||
* Configuration for selection-based fields
|
||||
*/
|
||||
if ($tag->has_option('default')) {
|
||||
$atts['dtx-default'] = wpcf7dtx_get_dynamic(html_entity_decode(urldecode($tag->get_option('default', '', true)), ENT_QUOTES));
|
||||
}
|
||||
|
||||
// Get options for selection-based fields
|
||||
$options = array();
|
||||
$pipes = $tag->pipes->to_array();
|
||||
if (count($pipes)) {
|
||||
foreach ($pipes as $pipe) {
|
||||
$key = trim(strval($pipe[0]));
|
||||
$value = trim(strval($pipe[1]));
|
||||
if ($key && $value) {
|
||||
$options[$key] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($atts['type'] == 'select' && $tag->has_option('include_blank')) {
|
||||
$atts['placeholder'] = wpcf7dtx_array_has_key('placeholder', $atts, __('—Please choose an option—', 'contact-form-7-dynamic-text-extension'));
|
||||
}
|
||||
} else {
|
||||
/**
|
||||
* Configuration for text-based fields
|
||||
*/
|
||||
|
||||
// Attributes
|
||||
$atts['maxlength'] = $tag->get_maxlength_option();
|
||||
$atts['minlength'] = $tag->get_minlength_option();
|
||||
if ($atts['maxlength'] && $atts['minlength'] && $atts['maxlength'] < $atts['minlength']) {
|
||||
unset($atts['maxlength'], $atts['minlength']);
|
||||
}
|
||||
|
||||
// Autocomplete attribute
|
||||
if ($atts['type'] == 'hidden') {
|
||||
$atts['autocomplete'] = 'off'; // Always disable for hidden fields
|
||||
} else {
|
||||
// Disable autocomplete for this field if a dynamic value has been specified
|
||||
$atts['autocomplete'] = $atts['value'] ? 'off' : $tag->get_option('autocomplete', '[-0-9a-zA-Z]+', true);
|
||||
}
|
||||
|
||||
switch ($atts['type']) {
|
||||
case 'email':
|
||||
case 'url':
|
||||
case 'tel':
|
||||
case 'number':
|
||||
case 'date':
|
||||
// Client-side validation by type
|
||||
$atts['class'][] = sanitize_html_class('wpcf7-validates-as-' . $atts['type']);
|
||||
break;
|
||||
case 'range':
|
||||
// Client-side validation by type
|
||||
$atts['class'][] = 'wpcf7-validates-as-number';
|
||||
break;
|
||||
case 'textarea':
|
||||
// Attributes unique to textareas
|
||||
$atts['cols'] = $tag->get_cols_option('40');
|
||||
$atts['rows'] = $tag->get_rows_option('10');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Wrap up class attribute
|
||||
$atts['class'] = $tag->get_class_option($atts['class']);
|
||||
|
||||
// Output the form field HTML
|
||||
$wrapper = '<span class="wpcf7-form-control-wrap %1$s" data-name="%1$s">%2$s%3$s</span>';
|
||||
$allowed_html = array('br' => array(), 'span' => array('id' => array(), 'class' => array(), 'data-name' => array(), 'aria-hidden' => array()));
|
||||
switch ($atts['type']) {
|
||||
case 'checkbox':
|
||||
case 'radio':
|
||||
return wp_kses(sprintf(
|
||||
str_replace('<span class=', '<span%4$s class=', $wrapper), // Insert a 4th parameter for wrapper
|
||||
esc_attr($tag->name),
|
||||
wpcf7dtx_checkbox_group_html(
|
||||
$atts,
|
||||
$options,
|
||||
in_array('use_label_element', $tag->options),
|
||||
in_array('label_first', $tag->options),
|
||||
in_array('exclusive', $tag->options)
|
||||
),
|
||||
$validation_error,
|
||||
$atts['id'] ? sprintf(' id="%s"', esc_attr($atts['id'])) : ''
|
||||
), array_merge($allowed_html, array(
|
||||
'label' => array('for' => array()),
|
||||
'input' => wpcf7dtx_get_allowed_field_properties($atts['type'])
|
||||
)));
|
||||
case 'select':
|
||||
$allowed_html = array_merge($allowed_html, wpcf7dtx_get_allowed_field_properties('option'), array(
|
||||
'select' => wpcf7dtx_get_allowed_field_properties($atts['type'])
|
||||
));
|
||||
return wp_kses(sprintf(
|
||||
$wrapper,
|
||||
esc_attr($tag->name),
|
||||
wpcf7dtx_select_html(
|
||||
$atts,
|
||||
$options,
|
||||
$tag->has_option('dtx_hide_blank'),
|
||||
$tag->has_option('dtx_disable_blank')
|
||||
),
|
||||
$validation_error
|
||||
), array_merge($allowed_html, wpcf7dtx_get_allowed_field_properties('option'), array(
|
||||
'select' => wpcf7dtx_get_allowed_field_properties($atts['type']),
|
||||
)));
|
||||
case 'textarea':
|
||||
return wp_kses(sprintf(
|
||||
$wrapper,
|
||||
esc_attr($tag->name),
|
||||
wpcf7dtx_textarea_html($atts),
|
||||
$validation_error
|
||||
), array_merge($allowed_html, array(
|
||||
'textarea' => wpcf7dtx_get_allowed_field_properties($atts['type'])
|
||||
)));
|
||||
default:
|
||||
return wp_kses(sprintf(
|
||||
$wrapper,
|
||||
esc_attr($tag->name),
|
||||
wpcf7dtx_input_html($atts),
|
||||
$validation_error
|
||||
), array_merge($allowed_html, array(
|
||||
'input' => wpcf7dtx_get_allowed_field_properties($atts['type'])
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Form Tag Handler for Dynamic Submit
|
||||
*
|
||||
* @param WPCF7_FormTag $tag Current Contact Form 7 tag object
|
||||
*
|
||||
* @return string HTML output of the shortcode
|
||||
*/
|
||||
function wpcf7dtx_button_shortcode_handler($tag)
|
||||
{
|
||||
//Configure input attributes
|
||||
$atts = array();
|
||||
$atts['type'] = sanitize_key(str_replace('dynamic_', '', $tag->basetype));
|
||||
$atts['id'] = strval($tag->get_id_option());
|
||||
$atts['tabindex'] = $tag->get_option('tabindex', 'signed_int', true);
|
||||
$atts['value'] = wpcf7dtx_get_dynamic(false, $tag); // Evaluate the dynamic value
|
||||
$atts['class'] = explode(' ', wpcf7_form_controls_class($atts['type']));
|
||||
$atts['class'][] = 'wpcf7dtx';
|
||||
$atts['class'][] = sanitize_html_class('wpcf7dtx-' . $atts['type']);
|
||||
if ($atts['type'] == 'submit') {
|
||||
$atts['class'][] = 'has-spinner';
|
||||
}
|
||||
|
||||
// Default value if empty
|
||||
if (empty($atts['value'])) {
|
||||
switch ($atts['type']) {
|
||||
case 'reset':
|
||||
$atts['value'] = __('Clear', 'contact-form-7-dynamic-text-extension');
|
||||
break;
|
||||
default:
|
||||
$atts['value'] = __('Send', 'contact-form-7-dynamic-text-extension');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Page load attribute
|
||||
if ($tag->has_option('dtx_pageload') && is_array($tag->raw_values) && count($tag->raw_values)) {
|
||||
$atts['data-dtx-value'] = rawurlencode(sanitize_text_field($tag->raw_values[0]));
|
||||
$atts['class'][] = 'dtx-pageload';
|
||||
if (wp_style_is('wpcf7dtx', 'registered') && !wp_script_is('wpcf7dtx', 'queue')) {
|
||||
// If already registered, just enqueue it
|
||||
wp_enqueue_script('wpcf7dtx');
|
||||
} elseif (!wp_style_is('wpcf7dtx', 'registered')) {
|
||||
// If not registered, do that first, then enqueue it
|
||||
wpcf7dtx_enqueue_frontend_assets();
|
||||
wp_enqueue_script('wpcf7dtx');
|
||||
}
|
||||
}
|
||||
|
||||
// Wrap up class attribute
|
||||
$atts['class'] = $tag->get_class_option($atts['class']);
|
||||
|
||||
// Output the form field HTML
|
||||
return wp_kses(
|
||||
wpcf7dtx_input_html($atts),
|
||||
array('input' => wpcf7dtx_get_allowed_field_properties($atts['type']))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate Required Dynamic Text Field
|
||||
* AJAX Request Handler for After Page Loading
|
||||
*
|
||||
* @param mixed $result
|
||||
* @param WPCF7_FormTag $tag
|
||||
* @since 3.5.0
|
||||
*
|
||||
* @return mixed
|
||||
* @param array $_POST A sequential array of url encoded shortcode values to evaluate
|
||||
*
|
||||
* @return array A sequential array of objects with `raw_value` and `value` keys
|
||||
*/
|
||||
function wpcf7dtx_dynamictext_validation_filter($result, $tag)
|
||||
function wpcf7dtx_js_handler()
|
||||
{
|
||||
$tag = new WPCF7_FormTag($tag);
|
||||
|
||||
//Sanitize value
|
||||
$value = empty($_POST[$tag->name]) ? '' : sanitize_text_field(trim(strval($_POST[$tag->name])));
|
||||
|
||||
//Validate
|
||||
if ('dynamictext' == $tag->basetype) {
|
||||
if ($tag->is_required() && '' == $value) {
|
||||
$result->invalidate($tag, wpcf7_get_message('invalid_required'));
|
||||
$return = array();
|
||||
$queue = wpcf7dtx_array_has_key('shortcodes', $_POST);
|
||||
if (is_array($queue) && count($queue)) {
|
||||
foreach ($queue as $field) {
|
||||
$multiline = wpcf7dtx_array_has_key('multiline', $field, false);
|
||||
$raw_value = sanitize_text_field(rawurldecode(wpcf7dtx_array_has_key('value', $field)));
|
||||
$return[] = array(
|
||||
'raw_value' => esc_attr($raw_value),
|
||||
'value' => esc_attr(wpcf7dtx_get_dynamic($raw_value, false, $multiline ? 'textarea' : 'auto'))
|
||||
);
|
||||
}
|
||||
}
|
||||
if (!empty($value)) {
|
||||
$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'));
|
||||
} elseif ($minlength && $code_units < $minlength) {
|
||||
$result->invalidate($tag, wpcf7_get_message('invalid_too_short'));
|
||||
}
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
wp_die(json_encode($return));
|
||||
}
|
||||
|
||||
/**
|
||||
* Include Utility Functions
|
||||
*/
|
||||
include_once(WPCF7DTX_DIR . '/includes/utilities.php');
|
||||
add_action('wp_ajax_wpcf7dtx', 'wpcf7dtx_js_handler'); // Add AJAX call for logged in users
|
||||
add_action('wp_ajax_nopriv_wpcf7dtx', 'wpcf7dtx_js_handler'); // Add AJAX call for anonymous users
|
||||
|
||||
if (is_admin()) {
|
||||
/**
|
||||
@@ -211,6 +525,20 @@ if (is_admin()) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Included Shortcodes
|
||||
* Built-in Shortcodes
|
||||
*/
|
||||
include_once(WPCF7DTX_DIR . '/includes/shortcodes.php');
|
||||
|
||||
/**
|
||||
* Website's custom shortcodes, if they exist
|
||||
*/
|
||||
$user_files = array(
|
||||
constant('WP_CONTENT_DIR') . '/dtx.php', // e.g. C:\path\to\website\wp-content\dtx.php
|
||||
get_template_directory() . '/dtx.php', // e.g. C:\path\to\website\wp-content/themes/parent-theme/dtx.php
|
||||
get_stylesheet_directory() . '/dtx.php' // e.g. C:\path\to\website\wp-content/themes/child-theme/dtx.php
|
||||
);
|
||||
foreach ($user_files as $user_file) {
|
||||
if (file_exists($user_file)) {
|
||||
include_once($user_file);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,29 +8,32 @@
|
||||
* @since 3.1.0
|
||||
*
|
||||
* @param string $hook Hook suffix for the current admin page
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function wpcf7dtx_enqueue_admin_assets($hook)
|
||||
{
|
||||
//Only load on CF7 Form pages
|
||||
if ($hook == 'toplevel_page_wpcf7') {
|
||||
// Only load on CF7 Form pages (both editing forms and creating new forms)
|
||||
if ($hook === 'toplevel_page_wpcf7' || $hook === 'contact_page_wpcf7-new') {
|
||||
$prefix = 'wpcf7dtx-';
|
||||
$debug = defined('WP_DEBUG_SCRIPTS') && constant('WP_DEBUG_SCRIPTS');
|
||||
$url = plugin_dir_url(WPCF7DTX_FILE);
|
||||
$path = plugin_dir_path(WPCF7DTX_FILE);
|
||||
|
||||
wp_enqueue_style(
|
||||
$prefix . 'admin', //Handle
|
||||
$url . 'assets/styles/tag-generator.css', //Source
|
||||
$url . 'assets/styles/tag-generator' . ($debug ? '' : '.min') . '.css', //Source
|
||||
array('contact-form-7-admin'), //Dependencies
|
||||
@filemtime($path . 'assets/styles/tag-generator.css') //Version
|
||||
$debug ? @filemtime($path . 'assets/styles/tag-generator.css') : WPCF7DTX_VERSION //Version
|
||||
);
|
||||
|
||||
//Plugin Scripts
|
||||
wp_enqueue_script(
|
||||
$prefix . 'taggenerator', //Handle
|
||||
$url . 'assets/scripts/tag-generator.js', //Source
|
||||
$url . 'assets/scripts/tag-generator' . ($debug ? '' : '.min') . '.js', //Source
|
||||
array('jquery', 'wpcf7-admin-taggenerator'), //Dependencies
|
||||
@filemtime($path . 'assets/scripts/tag-generator.js'), //Version
|
||||
true //In footer
|
||||
$debug ? @filemtime($path . 'assets/scripts/tag-generator.js') : WPCF7DTX_VERSION, //Version
|
||||
array('in_footer' => true, 'strategy' => 'defer') // Defer loading in footer
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -41,66 +44,68 @@ add_action('admin_enqueue_scripts', 'wpcf7dtx_enqueue_admin_assets'); //Enqueue
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function wpcf7dtx_add_tag_generator_dynamictext()
|
||||
function wpcf7dtx_add_tag_generators()
|
||||
{
|
||||
if (!class_exists('WPCF7_TagGenerator')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Custom dynamic fields to add
|
||||
global $wpcf7_dynamic_fields_config;
|
||||
|
||||
// Loop fields to add them
|
||||
$tag_generator = WPCF7_TagGenerator::get_instance();
|
||||
|
||||
//Dynamic Text Field
|
||||
$tag_generator->add(
|
||||
'dynamictext', //id
|
||||
__('dynamic text', 'contact-form-7-dynamic-text-extension'), //title
|
||||
'wpcf7dtx_tag_generator_dynamictext', //callback
|
||||
array('placeholder', 'readonly') //options
|
||||
);
|
||||
|
||||
//Dynamic Hidden Field
|
||||
$tag_generator->add(
|
||||
'dynamichidden', //id
|
||||
__('dynamic hidden', 'contact-form-7-dynamic-text-extension'), //title
|
||||
'wpcf7dtx_tag_generator_dynamictext' //callback
|
||||
);
|
||||
foreach ($wpcf7_dynamic_fields_config as $id => $field) {
|
||||
$tag_generator->add($id, $field['title'], 'wpcf7dtx_tag_generator', array_merge(array('name-attr', 'dtx_pageload'), $field['options']));
|
||||
}
|
||||
}
|
||||
add_action('wpcf7_admin_init', 'wpcf7dtx_add_tag_generator_dynamictext', 100);
|
||||
add_action('wpcf7_admin_init', 'wpcf7dtx_add_tag_generators', 100);
|
||||
|
||||
/**
|
||||
* Echo HTML for Dynamic Tag Generator
|
||||
*
|
||||
* @param WPCF7_ContactForm $contact_form
|
||||
* @param array $options
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function wpcf7dtx_tag_generator_dynamictext($contact_form, $options = '')
|
||||
function wpcf7dtx_tag_generator($contact_form, $options = '')
|
||||
{
|
||||
$options = wp_parse_args($options);
|
||||
global $wpcf7_dynamic_fields_config;
|
||||
$type = $options['id'];
|
||||
switch ($type) {
|
||||
case 'dynamichidden': //hiden
|
||||
$description = __('Generate a form-tag for a hidden input field, with a dynamically generated default value.', 'contact-form-7-dynamic-text-extension');
|
||||
break;
|
||||
default:
|
||||
$description = __('Generate a form-tag for a single-line plain text input field, with a dynamically generated default value.', 'contact-form-7-dynamic-text-extension');
|
||||
break;
|
||||
}
|
||||
$input_type = str_replace('dynamic_', '', $type);
|
||||
$utm_source = urlencode(home_url());
|
||||
$description .= sprintf(
|
||||
' %s <a href="https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/?utm_source=%s&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=form-tag-generator-%s" target="_blank" rel="noopener">%s</a>.',
|
||||
__('For more details, see', 'contact-form-7-dynamic-text-extension'),
|
||||
esc_attr($utm_source), //UTM source
|
||||
esc_attr($type), //UTM content
|
||||
__('DTX knowledge base', 'contact-form-7-dynamic-text-extension')
|
||||
$description = sprintf(
|
||||
__('Generate a form-tag for %s with a dynamic default value. For more details, see %s fields in the %s.', 'contact-form-7-dynamic-text-extension'),
|
||||
esc_html($wpcf7_dynamic_fields_config[$type]['description']), // dynamic description
|
||||
// Link to specific form-tag documentation
|
||||
sprintf(
|
||||
'<a href="https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/form-tags/%s?utm_source=%s&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=form-tag-generator-%s" title="%s" target="_blank" rel="noopener">%s</a>',
|
||||
esc_attr(str_replace('_', '-', $type)), // URL component
|
||||
esc_attr($utm_source), //UTM source
|
||||
esc_attr($type), //UTM content
|
||||
esc_attr__('View this form-tag on the DTX Documentation website', 'contact-form-7-dynamic-text-extension'), // Link title
|
||||
esc_html(ucwords(str_replace('_', ' ', $type))) // Link label
|
||||
),
|
||||
// Link to general DTX documentation
|
||||
sprintf(
|
||||
'<a href="https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/?utm_source=%s&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=form-tag-generator-%s" title="%s" target="_blank" rel="noopener">%s</a>',
|
||||
esc_attr($utm_source), //UTM source
|
||||
esc_attr($type), //UTM content
|
||||
esc_attr__('Go to DTX Documentation website', 'contact-form-7-dynamic-text-extension'),
|
||||
esc_html__('DTX knowledge base', 'contact-form-7-dynamic-text-extension')
|
||||
)
|
||||
);
|
||||
|
||||
//Open Form-Tag Generator
|
||||
// Open Form-Tag Generator
|
||||
printf(
|
||||
'<div class="control-box"><fieldset><legend>%s</legend><table class="form-table"><tbody>',
|
||||
wp_kses($description, 'a') //Tag generator description
|
||||
'<div class="control-box dtx-taggen"><fieldset><legend>%s</legend><table class="form-table"><tbody>',
|
||||
wp_kses($description, array('a' => array('href' => array(), 'target' => array(), 'rel' => array(), 'title' => array()))) //Tag generator description
|
||||
);
|
||||
|
||||
//Input field - Required checkbox (not available for hidden fields)
|
||||
if ($type != 'dynamichidden') {
|
||||
// Input field - Required checkbox (not available for some fields)
|
||||
if (!in_array($input_type, array('hidden', 'quiz', 'submit', 'reset'))) {
|
||||
printf(
|
||||
'<tr><th scope="row"><label for="%s">%s</label></th><td><label><input %s />%s</label></td></tr>',
|
||||
esc_attr($options['content'] . '-required'), // field id
|
||||
@@ -114,62 +119,253 @@ function wpcf7dtx_tag_generator_dynamictext($contact_form, $options = '')
|
||||
);
|
||||
}
|
||||
|
||||
//Input field - Field Name
|
||||
printf(
|
||||
'<tr><th scope="row"><label for="%s">%s</label></th><td><input %s /></td></tr>',
|
||||
esc_attr($options['content'] . '-name'), // field id
|
||||
esc_html__('Name', 'contact-form-7-dynamic-text-extension'), // field label
|
||||
wpcf7_format_atts(array(
|
||||
'type' => 'text',
|
||||
'name' => 'name',
|
||||
'id' => $options['content'] . '-name',
|
||||
'class' => 'tg-name oneline'
|
||||
))
|
||||
);
|
||||
// Input field - Field Name (not available for some fields)
|
||||
if (!in_array($input_type, array('submit', 'reset'))) {
|
||||
printf(
|
||||
'<tr><th scope="row"><label for="%s">%s</label></th><td><input %s /></td></tr>',
|
||||
esc_attr($options['content'] . '-name'), // field id
|
||||
esc_html__('Name', 'contact-form-7-dynamic-text-extension'), // field label
|
||||
wpcf7_format_atts(array(
|
||||
'type' => 'text',
|
||||
'name' => 'name',
|
||||
'id' => $options['content'] . '-name',
|
||||
'class' => 'tg-name oneline',
|
||||
'autocomplete' => 'off'
|
||||
))
|
||||
);
|
||||
}
|
||||
|
||||
//Input field - Dynamic value
|
||||
// Input field - Dynamic value/options
|
||||
$value_name = __('Dynamic value', 'contact-form-7-dynamic-text-extension');
|
||||
$value_description = __('Can be static text or a shortcode.', 'contact-form-7-dynamic-text-extension');
|
||||
$value_placeholder = "CF7_GET key='foo'";
|
||||
$value_input_type = '<input %s />';
|
||||
switch ($input_type) {
|
||||
case 'textarea':
|
||||
$value_placeholder = "CF7_get_post_var key='post_excerpt'";
|
||||
$value_input_type = '<textarea %s></textarea>';
|
||||
break;
|
||||
case 'select':
|
||||
$value_name = __('Dynamic options', 'contact-form-7-dynamic-text-extension');
|
||||
$value_description .= ' ' . __('If static text, use one option per line. Can define static key/value pairs using pipes.', 'contact-form-7-dynamic-text-extension');
|
||||
$value_description .= ' ' . __('If shortcode, it must return only option or optgroup HTML and can override the first option and select default settings here.', 'contact-form-7-dynamic-text-extension');
|
||||
$value_placeholder = "hello-world | Hello World" . PHP_EOL . "Foo";
|
||||
$value_input_type = '<textarea %s></textarea>';
|
||||
break;
|
||||
case 'checkbox':
|
||||
case 'radio':
|
||||
$value_name = __('Dynamic options', 'contact-form-7-dynamic-text-extension');
|
||||
$value_description .= ' ' . __('If static text, use one option per line. Can define static key/value pairs using pipes.', 'contact-form-7-dynamic-text-extension');
|
||||
$value_description .= ' ' . __('If shortcode, it must return only option or optgroup HTML.', 'contact-form-7-dynamic-text-extension');
|
||||
$value_placeholder = "hello-world | Hello World" . PHP_EOL . "Foo";
|
||||
$value_input_type = '<textarea %s></textarea>';
|
||||
break;
|
||||
default: // All other text fields
|
||||
break;
|
||||
}
|
||||
printf(
|
||||
'<tr><th scope="row"><label for="%s">%s</label></th><td><input %s /><br /><small>%s <a href="https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/shortcodes/?utm_source=%s&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=form-tag-generator-%s" target="_blank" rel="noopener">%s</a></small></td></tr>',
|
||||
'<tr><th scope="row"><label for="%s">%s</label></th><td>' . $value_input_type . '<br /><small>%s <a href="https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/shortcodes/?utm_source=%s&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=form-tag-generator-%s" target="_blank" rel="noopener">%s</a></small></td></tr>',
|
||||
esc_attr($options['content'] . '-values'), // field id
|
||||
esc_html__('Dynamic value', 'contact-form-7-dynamic-text-extension'), // field label
|
||||
esc_html($value_name), // field label
|
||||
wpcf7_format_atts(array(
|
||||
'type' => 'text',
|
||||
'name' => 'values',
|
||||
'id' => $options['content'] . '-values',
|
||||
'class' => 'oneline',
|
||||
'placeholder' => "CF7_GET key='foo'"
|
||||
'class' => 'multiline',
|
||||
'placeholder' => $value_placeholder,
|
||||
'list' => 'dtx-shortcodes'
|
||||
)),
|
||||
esc_html__('Can be static text or a shortcode.', 'contact-form-7-dynamic-text-extension'),
|
||||
esc_attr($utm_source), //UTM source
|
||||
esc_attr($type), //UTM content
|
||||
esc_html__('View DTX shortcode syntax documentation', 'contact-form-7-dynamic-text-extension') //Link label
|
||||
esc_html($value_description),
|
||||
esc_attr($utm_source), // UTM source
|
||||
esc_attr($type), // UTM content
|
||||
esc_html__('View DTX shortcode syntax documentation', 'contact-form-7-dynamic-text-extension') // Link label
|
||||
);
|
||||
|
||||
//Input field - Dynamic placeholder (not available for hidden fields)
|
||||
if ($type != 'dynamichidden') {
|
||||
if ($input_type == 'select') {
|
||||
// Input field - Multiple selections checkbox
|
||||
printf(
|
||||
'<tr><th scope="row"><label for="%s">%s</label></th><td><input %s /><input %s /><br /><small>%s <a href="https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/shortcodes/dtx-attribute-placeholder/?utm_source=%s&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=form-tag-generator-%s" target="_blank" rel="noopener">%s</a></small></td></tr>',
|
||||
'<tr><th scope="row"><label for="%s">%s</label></th><td><label><input %s />%s</label></td></tr>',
|
||||
esc_attr($options['content'] . '-multiple'), // field id
|
||||
esc_html__('Multiple Options', 'contact-form-7-dynamic-text-extension'), // field Label
|
||||
wpcf7_format_atts(array(
|
||||
'type' => 'checkbox',
|
||||
'name' => 'multiple',
|
||||
'id' => $options['content'] . '-multiple',
|
||||
'class' => 'option'
|
||||
)),
|
||||
esc_html__('Allow user to select multiple options', 'contact-form-7-dynamic-text-extension') // checkbox label
|
||||
);
|
||||
|
||||
// Input field - Include blank checkbox
|
||||
printf(
|
||||
'<tr><th scope="row"><label for="%s">%s</label></th><td><label><input %s />%s</label></td></tr>',
|
||||
esc_attr($options['content'] . '-include_blank'), // field id
|
||||
esc_html__('First Option', 'contact-form-7-dynamic-text-extension'), // field Label
|
||||
wpcf7_format_atts(array(
|
||||
'type' => 'checkbox',
|
||||
'name' => 'include_blank',
|
||||
'id' => $options['content'] . '-include_blank',
|
||||
'class' => 'include_blankvalue option'
|
||||
)),
|
||||
esc_html__('Insert a blank item as the first option', 'contact-form-7-dynamic-text-extension') // checkbox label
|
||||
);
|
||||
}
|
||||
|
||||
// Input field - Dynamic placeholder (not available for some fields)
|
||||
if (!in_array($input_type, array('hidden', 'radio', 'checkbox', 'quiz', 'submit', 'reset'))) {
|
||||
$placeholder_description = '';
|
||||
if (in_array($input_type, array('select', 'checkbox', 'radio'))) {
|
||||
$placeholder_label = __('First Option Label', 'contact-form-7-dynamic-text-extension');
|
||||
$placeholder_description .= __('Optionally define a label for the first option.', 'contact-form-7-dynamic-text-extension') . ' ';
|
||||
} else {
|
||||
$placeholder_label = __('Dynamic placeholder', 'contact-form-7-dynamic-text-extension');
|
||||
}
|
||||
$placeholder_description .= __('Can be static text or a shortcode.', 'contact-form-7-dynamic-text-extension');
|
||||
$placeholder_input_type = $input_type == 'textarea' ? $value_input_type : '<input %s />';
|
||||
printf(
|
||||
'<tr><th scope="row"><label for="%s">%s</label></th><td><input %s />' . $placeholder_input_type . '<br /><small>%s <a href="https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/shortcodes/dtx-attribute-placeholder/?utm_source=%s&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=form-tag-generator-%s" target="_blank" rel="noopener">%s</a></small></td></tr>',
|
||||
esc_attr($options['content'] . '-placeholder'), // field id
|
||||
esc_html__('Dynamic placeholder', 'contact-form-7-dynamic-text-extension'), // field label
|
||||
esc_html($placeholder_label), // field label
|
||||
wpcf7_format_atts(array(
|
||||
'type' => 'hidden',
|
||||
'name' => 'placeholder',
|
||||
'class' => 'option'
|
||||
)),
|
||||
wpcf7_format_atts(array(
|
||||
'type' => 'text',
|
||||
'name' => 'dtx-placeholder',
|
||||
'id' => $options['content'] . '-placeholder', // field id
|
||||
'class' => 'oneline dtx-option',
|
||||
'placeholder' => 'CF7_get_post_var key=\'post_title\''
|
||||
'class' => 'multiline dtx-option',
|
||||
'placeholder' => "CF7_get_post_var key='post_title'",
|
||||
'list' => 'dtx-shortcodes'
|
||||
)),
|
||||
esc_html__('Can be static text or a shortcode.', 'contact-form-7-dynamic-text-extension'),
|
||||
esc_html($placeholder_description), // Small note below input
|
||||
esc_attr($utm_source), //UTM source
|
||||
esc_attr($type), //UTM content
|
||||
esc_html__('View DTX placeholder documentation', 'contact-form-7-dynamic-text-extension') //Link label
|
||||
);
|
||||
}
|
||||
|
||||
// Additional fields for select regarding placeholder options
|
||||
if ($input_type == 'select') {
|
||||
|
||||
// Input field - Hide Blank Option
|
||||
printf(
|
||||
'<tr><th scope="row"><label for="%s">%s</label></th><td><label><input %s />%s</label><br /><small>%s <a href="https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/form-tags/dynamic-select/?utm_source=%s&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=form-tag-generator-%s" target="_blank" rel="noopener">%s</a></small></td></tr>',
|
||||
esc_attr($options['content'] . '-dtx_hide_blank'), // field id
|
||||
esc_html__('Hide First Option', 'contact-form-7-dynamic-text-extension'), // field Label
|
||||
wpcf7_format_atts(array(
|
||||
'type' => 'checkbox',
|
||||
'name' => 'dtx_hide_blank',
|
||||
'id' => $options['content'] . '-dtx_hide_blank',
|
||||
'class' => 'option'
|
||||
)),
|
||||
esc_html__('Hide the first blank option from being visible in the drop-down', 'contact-form-7-dynamic-text-extension'), // checkbox label
|
||||
esc_html__('Optional. Only works if "First Option" is checked.', 'contact-form-7-dynamic-text-extension'), // Small note below input
|
||||
esc_attr($utm_source), //UTM source
|
||||
esc_attr($type), //UTM content
|
||||
esc_html__('View Dynamic Select documentation', 'contact-form-7-dynamic-text-extension') //Link label
|
||||
);
|
||||
|
||||
// Input field - Disable Blank Option
|
||||
printf(
|
||||
'<tr><th scope="row"><label for="%s">%s</label></th><td><label><input %s />%s</label><br /><small>%s <a href="https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/form-tags/dynamic-select/?utm_source=%s&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=form-tag-generator-%s" target="_blank" rel="noopener">%s</a></small></td></tr>',
|
||||
esc_attr($options['content'] . '-dtx_disable_blank'), // field id
|
||||
esc_html__('Disable First Option', 'contact-form-7-dynamic-text-extension'), // field Label
|
||||
wpcf7_format_atts(array(
|
||||
'type' => 'checkbox',
|
||||
'name' => 'dtx_disable_blank',
|
||||
'id' => $options['content'] . '-dtx_disable_blank',
|
||||
'class' => 'option'
|
||||
)),
|
||||
esc_html__('Disable the first blank option from being selectable in the drop-down', 'contact-form-7-dynamic-text-extension'), // checkbox label
|
||||
esc_html__('Optional. Only works if "First Option" is checked.', 'contact-form-7-dynamic-text-extension'), // Small note below input
|
||||
esc_attr($utm_source), //UTM source
|
||||
esc_attr($type), //UTM content
|
||||
esc_html__('View Dynamic Select documentation', 'contact-form-7-dynamic-text-extension') //Link label
|
||||
|
||||
);
|
||||
} elseif (in_array($input_type, array('checkbox', 'radio'))) {
|
||||
// Additional fields for checkboxes and radio buttons
|
||||
|
||||
// Input field - Checkbox Layout Reverse Option
|
||||
printf(
|
||||
'<tr><th scope="row"><label for="%s">%s</label></th><td><label><input %s />%s</label></td></tr>',
|
||||
esc_attr($options['content'] . '-label_first'), // field id
|
||||
esc_html__('Reverse', 'contact-form-7-dynamic-text-extension'), // field Label
|
||||
wpcf7_format_atts(array(
|
||||
'type' => 'checkbox',
|
||||
'name' => 'label_first',
|
||||
'id' => $options['content'] . '-label_first',
|
||||
'class' => 'option'
|
||||
)),
|
||||
esc_html__('Put a label first, an input last', 'contact-form-7-dynamic-text-extension') // checkbox label
|
||||
);
|
||||
|
||||
// Input field - Label UI
|
||||
printf(
|
||||
'<tr><th scope="row"><label for="%s">%s</label></th><td><label><input %s />%s</label></td></tr>',
|
||||
esc_attr($options['content'] . '-use_label_element'), // field id
|
||||
esc_html__('Label', 'contact-form-7-dynamic-text-extension'), // field Label
|
||||
wpcf7_format_atts(array(
|
||||
'type' => 'checkbox',
|
||||
'name' => 'use_label_element',
|
||||
'id' => $options['content'] . '-use_label_element',
|
||||
'class' => 'option'
|
||||
)),
|
||||
esc_html__('Wrap each item with label element', 'contact-form-7-dynamic-text-extension') // checkbox label
|
||||
);
|
||||
|
||||
// Input field - Exclusive Checkbox
|
||||
if ($input_type == 'checkbox') {
|
||||
printf(
|
||||
'<tr><th scope="row"><label for="%s">%s</label></th><td><label><input %s />%s</label></td></tr>',
|
||||
esc_attr($options['content'] . '-exclusive'), // field id
|
||||
esc_html__('Exclusive', 'contact-form-7-dynamic-text-extension'), // field Label
|
||||
wpcf7_format_atts(array(
|
||||
'type' => 'checkbox',
|
||||
'name' => 'exclusive',
|
||||
'id' => $options['content'] . '-exclusive',
|
||||
'class' => 'option'
|
||||
)),
|
||||
esc_html__('Make checkboxes exclusive', 'contact-form-7-dynamic-text-extension') // checkbox label
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Input field - Dynamic default value (not available for some fields)
|
||||
if (in_array($input_type, array('select'))) {
|
||||
$default_input_type = '<input %s />';
|
||||
$default_placeholder = '';
|
||||
if ($input_type == 'checkbox') {
|
||||
$default_input_type = '<textarea %s></textarea>';
|
||||
$default_description = __('Optionally define the default on/off status of the checkboxes by putting a 1 (checked) or 0 (not checked) on each line that corresponds with the options.', 'contact-form-7-dynamic-text-extension') . ' ';
|
||||
$default_placeholder = '0' . PHP_EOL . '1';
|
||||
} else {
|
||||
$default_description = __('Optionally define the option that is selected by default. This can be different than the first [blank] option. If options use key/value pairs, only define the key here.', 'contact-form-7-dynamic-text-extension') . ' ';
|
||||
}
|
||||
$default_description .= __('Can be static text or a shortcode.', 'contact-form-7-dynamic-text-extension');
|
||||
printf(
|
||||
'<tr><th scope="row"><label for="%s">%s</label></th><td><input %s />' . $default_input_type . '<br /><small>%s <a href="https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/form-tags/dynamic-select/?utm_source=%s&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=form-tag-generator-%s" target="_blank" rel="noopener">%s</a></small></td></tr>',
|
||||
esc_attr($options['content'] . '-default'), // field id
|
||||
esc_html__('Selected Default'), // field label
|
||||
wpcf7_format_atts(array(
|
||||
'type' => 'hidden',
|
||||
'name' => 'default',
|
||||
'class' => 'option'
|
||||
)),
|
||||
wpcf7_format_atts(array(
|
||||
'name' => 'dtx-default',
|
||||
'id' => $options['content'] . '-default', // field id
|
||||
'class' => 'oneline dtx-option',
|
||||
'placeholder' => $default_placeholder,
|
||||
'list' => 'dtx-shortcodes'
|
||||
)),
|
||||
esc_html($default_description), // Small note below input
|
||||
esc_attr($utm_source), //UTM source
|
||||
esc_attr($type), //UTM content
|
||||
esc_html__('View Dynamic Select documentation', 'contact-form-7-dynamic-text-extension') //Link label
|
||||
);
|
||||
}
|
||||
|
||||
//Input field - ID attribute
|
||||
printf(
|
||||
'<tr><th scope="row"><label for="%s">%s</label></th><td><input %s /></td></tr>',
|
||||
@@ -196,8 +392,8 @@ function wpcf7dtx_tag_generator_dynamictext($contact_form, $options = '')
|
||||
))
|
||||
);
|
||||
|
||||
//Input field - Readonly attribute (not available for hidden fields)
|
||||
if ($type != 'dynamichidden') {
|
||||
//Input field - Readonly attribute (not available for hidden, submit, or quiz fields)
|
||||
if (!in_array($input_type, array('hidden', 'submit', 'quiz'))) {
|
||||
printf(
|
||||
'<tr><th scope="row"><label for="%s">%s</label></th><td><label><input %s />%s</label></td></tr>',
|
||||
esc_attr($options['content'] . '-readonly'), // field id
|
||||
@@ -212,6 +408,55 @@ function wpcf7dtx_tag_generator_dynamictext($contact_form, $options = '')
|
||||
);
|
||||
}
|
||||
|
||||
// Input field - Page load data attribute (triggers the loading of a frontend script)
|
||||
printf(
|
||||
'<tr><th scope="row"><label for="%s">%s</label></th><td><label><input %s />%s</label><br /><small>%s <a href="https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/form-tag-attribute-after-page-load/?utm_source=%s&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=form-tag-generator-%s" target="_blank" rel="noopener">%s</a></small></td></tr>',
|
||||
esc_attr($options['content'] . '-dtx_pageload'), // field id
|
||||
esc_html__('Cache Compatible', 'contact-form-7-dynamic-text-extension'), // field Label
|
||||
wpcf7_format_atts(array(
|
||||
'type' => 'checkbox',
|
||||
'name' => 'dtx_pageload',
|
||||
'id' => $options['content'] . '-dtx_pageload',
|
||||
'class' => 'option'
|
||||
)),
|
||||
esc_html__('Get the dynamic value after the page has loaded', 'contact-form-7-dynamic-text-extension'), // checkbox label
|
||||
esc_html__('May impact page performance.', 'contact-form-7-dynamic-text-extension'), // Small note below input
|
||||
esc_attr($utm_source), //UTM source
|
||||
esc_attr($type), //UTM content
|
||||
esc_html__('View DTX page load documentation', 'contact-form-7-dynamic-text-extension') //Link label
|
||||
|
||||
);
|
||||
|
||||
// Input field - Akismet module (only available for text, email, and url fields)
|
||||
if (in_array($input_type, array('text', 'email', 'url'))) {
|
||||
switch ($input_type) {
|
||||
case 'email':
|
||||
$akismet_name = 'author_email';
|
||||
$akismet_desc = __("This field requires author's email address", 'contact-form-7-dynamic-text-extension');
|
||||
break;
|
||||
case 'url':
|
||||
$akismet_name = 'author_url';
|
||||
$akismet_desc = __("This field requires author's URL", 'contact-form-7-dynamic-text-extension');
|
||||
break;
|
||||
default:
|
||||
$akismet_name = 'author';
|
||||
$akismet_desc = __("This field requires author's name", 'contact-form-7-dynamic-text-extension');
|
||||
break;
|
||||
}
|
||||
printf(
|
||||
'<tr><th scope="row"><label for="%s">%s</label></th><td><label><input %s />%s</label></td></tr>',
|
||||
esc_attr($options['content'] . '-readonly'), // field id
|
||||
esc_html__('Akismet', 'contact-form-7-dynamic-text-extension'), // field Label
|
||||
wpcf7_format_atts(array(
|
||||
'type' => 'checkbox',
|
||||
'name' => 'akismet:' . $akismet_name,
|
||||
'id' => $options['content'] . '-akismet-' . $akismet_name,
|
||||
'class' => 'akismetvalue option'
|
||||
)),
|
||||
esc_html($akismet_desc) // checkbox label
|
||||
);
|
||||
}
|
||||
|
||||
//Close Form-Tag Generator
|
||||
printf(
|
||||
'</tbody></table></fieldset></div><div class="insert-box"><input type="text" name="%s" class="tag code" readonly="readonly" onfocus="this.select()" /><div class="submitbox"><input type="button" class="button button-primary insert-tag" value="%s" /></div><br class="clear" /></div>',
|
||||
|
||||
@@ -17,207 +17,183 @@
|
||||
*/
|
||||
function wpcf7dtx_init_shortcodes()
|
||||
{
|
||||
add_shortcode('CF7_GET', 'wpcf7dtx_get');
|
||||
add_shortcode('CF7_POST', 'wpcf7dtx_post');
|
||||
add_shortcode('CF7_URL', 'wpcf7dtx_url');
|
||||
add_shortcode('CF7_referrer', 'wpcf7dtx_referrer');
|
||||
add_shortcode('CF7_bloginfo', 'wpcf7dtx_bloginfo');
|
||||
add_shortcode('CF7_get_post_var', 'wpcf7dtx_get_post_var');
|
||||
add_shortcode('CF7_get_custom_field', 'wpcf7dtx_get_custom_field');
|
||||
add_shortcode('CF7_get_current_user', 'wpcf7dtx_get_current_user');
|
||||
add_shortcode('CF7_get_attachment', 'wpcf7dtx_get_attachment');
|
||||
add_shortcode('CF7_guid', 'wpcf7dtx_guid');
|
||||
add_shortcode('CF7_GET', 'wpcf7dtx_get', 10, 1);
|
||||
add_shortcode('CF7_POST', 'wpcf7dtx_post', 10, 1);
|
||||
add_shortcode('CF7_URL', 'wpcf7dtx_url', 10, 1);
|
||||
add_shortcode('CF7_referrer', 'wpcf7dtx_referrer', 10, 1);
|
||||
add_shortcode('CF7_bloginfo', 'wpcf7dtx_bloginfo', 10, 1);
|
||||
add_shortcode('CF7_get_post_var', 'wpcf7dtx_get_post_var', 10, 1);
|
||||
add_shortcode('CF7_get_custom_field', 'wpcf7dtx_get_custom_field', 10, 1);
|
||||
add_shortcode('CF7_get_current_var', 'wpcf7dtx_get_current_var', 10, 1);
|
||||
add_shortcode('CF7_get_current_user', 'wpcf7dtx_get_current_user', 10, 1);
|
||||
add_shortcode('CF7_get_attachment', 'wpcf7dtx_get_attachment', 10, 1);
|
||||
add_shortcode('CF7_get_cookie', 'wpcf7dtx_get_cookie', 10, 1);
|
||||
add_shortcode('CF7_get_taxonomy', 'wpcf7dtx_get_taxonomy', 10, 1);
|
||||
add_shortcode('CF7_get_theme_option', 'wpcf7dtx_get_theme_option', 10, 1);
|
||||
add_shortcode('CF7_guid', 'wpcf7dtx_guid', 10, 0);
|
||||
}
|
||||
add_action('init', 'wpcf7dtx_init_shortcodes'); //Add init hook to add shortcodes
|
||||
|
||||
/**
|
||||
* Get Variable from $_GET Array
|
||||
*
|
||||
* @see https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/shortcodes/dtx-shortcode-php-get-variables/
|
||||
*
|
||||
* @param array $atts Optional. An associative array of shortcode attributes. Default is an empty array.
|
||||
* @param string $content Optional. A string of content between the opening and closing tags. Default is an empty string.
|
||||
* @param string $tag Optional. The shortcode tag. Default is an empty string.
|
||||
*
|
||||
* @return string Output of the shortcode
|
||||
*/
|
||||
function wpcf7dtx_get($atts = array(), $content = '', $tag = '')
|
||||
function wpcf7dtx_get($atts = array())
|
||||
{
|
||||
extract(shortcode_atts(array(
|
||||
'key' => 0,
|
||||
'default' => '',
|
||||
'obfuscate' => ''
|
||||
), array_change_key_case((array)$atts, CASE_LOWER)));
|
||||
$valid_key = (is_numeric($key) && intval($key) > -1) || (is_string($key) && !empty($key));
|
||||
if ($valid_key && is_array($_GET) && count($_GET) && array_key_exists($key, $_GET) && !empty($_GET[$key])) {
|
||||
$value = sanitize_text_field(strval($_GET[$key]));
|
||||
if ($obfuscate && !empty($value)) {
|
||||
return wpcf7dtx_obfuscate($value);
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
return '';
|
||||
$value = apply_filters('wpcf7dtx_sanitize', wpcf7dtx_array_has_key($key, $_GET, $default));
|
||||
return apply_filters('wpcf7dtx_escape', $value, $obfuscate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Variable from $_POST Array
|
||||
*
|
||||
* @see https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/shortcodes/dtx-shortcode-php-post-variables/
|
||||
*
|
||||
* @param array $atts Optional. An associative array of shortcode attributes. Default is an empty array.
|
||||
* @param string $content Optional. A string of content between the opening and closing tags. Default is an empty string.
|
||||
* @param string $tag Optional. The shortcode tag. Default is an empty string.
|
||||
*
|
||||
* @return string Output of the shortcode
|
||||
*/
|
||||
function wpcf7dtx_post($atts = array(), $content = '', $tag = '')
|
||||
function wpcf7dtx_post($atts = array())
|
||||
{
|
||||
extract(shortcode_atts(array(
|
||||
'key' => '',
|
||||
'default' => '',
|
||||
'obfuscate' => ''
|
||||
), array_change_key_case((array)$atts, CASE_LOWER)));
|
||||
$valid_key = (is_numeric($key) && intval($key) > -1) || (is_string($key) && !empty($key));
|
||||
if ($valid_key && is_array($_POST) && count($_POST) && array_key_exists($key, $_POST) && !empty($_POST[$key])) {
|
||||
$value = sanitize_text_field(strval($_POST[$key]));
|
||||
if ($obfuscate && !empty($value)) {
|
||||
return wpcf7dtx_obfuscate($value);
|
||||
$value = apply_filters('wpcf7dtx_sanitize', wpcf7dtx_array_has_key($key, $_POST, $default));
|
||||
return apply_filters('wpcf7dtx_escape', $value, $obfuscate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Current URL or Part
|
||||
*
|
||||
* @see https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/shortcodes/dtx-shortcode-current-url/
|
||||
*
|
||||
* @param array $atts Optional. An associative array of shortcode attributes. Default is an empty array.
|
||||
*
|
||||
* @return string Output of the shortcode
|
||||
*/
|
||||
function wpcf7dtx_url($atts = array())
|
||||
{
|
||||
extract(shortcode_atts(array(
|
||||
'allowed_protocols' => '',
|
||||
'part' => '',
|
||||
'obfuscate' => ''
|
||||
), array_change_key_case((array)$atts, CASE_LOWER)));
|
||||
$allowed_protocols = explode(',', sanitize_text_field($allowed_protocols));
|
||||
|
||||
// Get the absolute URL
|
||||
if (is_multisite() && !is_subdomain_install()) {
|
||||
// Network installs not using subdomains
|
||||
$url = apply_filters('wpcf7dtx_sanitize', network_home_url($_SERVER['REQUEST_URI']), 'url', $allowed_protocols);
|
||||
} else {
|
||||
// Single installs and network installs using subdomains
|
||||
$url = apply_filters('wpcf7dtx_sanitize', home_url($_SERVER['REQUEST_URI']), 'url', $allowed_protocols);
|
||||
}
|
||||
if ($url && !empty($part = sanitize_key(strtolower($part)))) {
|
||||
// If an individual part is requested, get that specific value using parse_url()
|
||||
$part_constant_map = [
|
||||
'scheme' => PHP_URL_SCHEME, // e.g. `http`
|
||||
'host' => PHP_URL_HOST, // the domain (or subdomain) of the current website
|
||||
'path' => PHP_URL_PATH, // e.g. `/path/to/current/page/`
|
||||
'query' => PHP_URL_QUERY // after the question mark ?
|
||||
];
|
||||
$value = '';
|
||||
if (array_key_exists($part, $part_constant_map)) {
|
||||
$value = apply_filters('wpcf7dtx_sanitize', strval(wp_parse_url($url, $part_constant_map[$part])), 'text');
|
||||
}
|
||||
return $value;
|
||||
return apply_filters('wpcf7dtx_escape', $value, $obfuscate, 'text');
|
||||
}
|
||||
// No part requested, return the absolute URL
|
||||
return apply_filters('wpcf7dtx_escape', $url, $obfuscate, 'url', $allowed_protocols);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Referrering URL
|
||||
*
|
||||
* @see https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/shortcodes/dtx-shortcode-referrer-url/
|
||||
*
|
||||
* @param array $atts Optional. An associative array of shortcode attributes. Default is an empty array.
|
||||
*
|
||||
* @return string Output of the shortcode
|
||||
*/
|
||||
function wpcf7dtx_referrer($atts = array())
|
||||
{
|
||||
extract(shortcode_atts(array(
|
||||
'allowed_protocols' => '',
|
||||
'obfuscate' => ''
|
||||
), array_change_key_case((array)$atts, CASE_LOWER)));
|
||||
if ($value = wpcf7dtx_array_has_key('HTTP_REFERER', $_SERVER)) {
|
||||
$value = apply_filters('wpcf7dtx_sanitize', $value, 'url', $allowed_protocols);
|
||||
return apply_filters('wpcf7dtx_escape', $value, $obfuscate, 'url');
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Current URL
|
||||
*
|
||||
* @param array $atts Optional. An associative array of shortcode attributes. Default is an empty array.
|
||||
* @param string $content Optional. A string of content between the opening and closing tags. Default is an empty string.
|
||||
* @param string $tag Optional. The shortcode tag. Default is an empty string.
|
||||
*
|
||||
* @return string Output of the shortcode
|
||||
*/
|
||||
function wpcf7dtx_url($atts = array(), $content = '', $tag = '') {
|
||||
|
||||
extract(shortcode_atts(array(
|
||||
'allowed_protocols' => 'http,https',
|
||||
'obfuscate' => '',
|
||||
'part' => '',
|
||||
), array_change_key_case((array)$atts, CASE_LOWER)));
|
||||
|
||||
$allowed_protocols = explode(',', sanitize_text_field($allowed_protocols));
|
||||
|
||||
// Build the full URL from the $_SERVER array
|
||||
$url = sprintf('http%s://', is_ssl() ? 's' : '');
|
||||
if (!empty($_SERVER['SERVER_PORT']) && intval($_SERVER['SERVER_PORT']) !== 80) {
|
||||
$url = $url . $_SERVER['SERVER_NAME'] . ':' . $_SERVER['SERVER_PORT'] . $_SERVER['REQUEST_URI'];
|
||||
} else {
|
||||
$url = $url . $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'];
|
||||
}
|
||||
|
||||
// Determine the value to return
|
||||
$value = '';
|
||||
|
||||
// If an individual part is requested, get that specific value using parse_url()
|
||||
if( $part ){
|
||||
$part_constant_map = [
|
||||
'host' => PHP_URL_HOST,
|
||||
'query' => PHP_URL_QUERY,
|
||||
'path' => PHP_URL_PATH,
|
||||
// 'fragment' => PHP_URL_FRAGMENT, // Can't get fragment because it's not part of the $_SERVER array
|
||||
];
|
||||
if( isset( $part_constant_map[$part] ) ) {
|
||||
$value = sanitize_text_field(parse_url($url, $part_constant_map[$part]));
|
||||
}
|
||||
}
|
||||
// No part requested, return the whole thing
|
||||
else {
|
||||
$value = sanitize_url($url, $allowed_protocols);
|
||||
}
|
||||
|
||||
// Obfuscate if requested
|
||||
if ($obfuscate && !empty($value)) {
|
||||
return wpcf7dtx_obfuscate($value);
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Referrer
|
||||
*
|
||||
* @param array $atts Optional. An associative array of shortcode attributes. Default is an empty array.
|
||||
* @param string $content Optional. A string of content between the opening and closing tags. Default is an empty string.
|
||||
* @param string $tag Optional. The shortcode tag. Default is an empty string.
|
||||
*
|
||||
* @return string Output of the shortcode
|
||||
*/
|
||||
function wpcf7dtx_referrer($atts = array(), $content = '', $tag = '')
|
||||
{
|
||||
extract(shortcode_atts(array(
|
||||
'allowed_protocols' => 'http,https',
|
||||
'obfuscate' => ''
|
||||
), array_change_key_case((array)$atts, CASE_LOWER)));
|
||||
$allowed_protocols = explode(',', sanitize_text_field($allowed_protocols));
|
||||
$value = empty($_SERVER['HTTP_REFERER']) ? '' : sanitize_url($_SERVER['HTTP_REFERER'], $allowed_protocols);
|
||||
if ($obfuscate && !empty($value)) {
|
||||
return wpcf7dtx_obfuscate($value);
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Variable from Bloginfo
|
||||
*
|
||||
* See possible values: https://developer.wordpress.org/reference/functions/get_bloginfo/
|
||||
* @see https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/shortcodes/dtx-shortcode-post-page-variables/
|
||||
*
|
||||
* @param array $atts Optional. An associative array of shortcode attributes. Default is an empty array.
|
||||
* @param string $content Optional. A string of content between the opening and closing tags. Default is an empty string.
|
||||
* @param string $tag Optional. The shortcode tag. Default is an empty string.
|
||||
*
|
||||
* @return string Output of the shortcode
|
||||
*/
|
||||
function wpcf7dtx_bloginfo($atts = array(), $content = '', $tag = '')
|
||||
function wpcf7dtx_bloginfo($atts = array())
|
||||
{
|
||||
extract(shortcode_atts(array(
|
||||
'show' => 'name', //Backwards compatibility
|
||||
'key' => 'name',
|
||||
'obfuscate' => ''
|
||||
), array_change_key_case((array)$atts, CASE_LOWER)));
|
||||
$key = $show != $key && $show != 'name' ? $show : $key; //Use old value of "show" if not set to default value
|
||||
$value = sanitize_text_field(strval(get_bloginfo($key)));
|
||||
if ($obfuscate && !empty($value)) {
|
||||
return wpcf7dtx_obfuscate($value);
|
||||
}
|
||||
return $value;
|
||||
$key = $show != $key && $show != 'name' ? $show : $key; // Use old value of "show" if not set to default value
|
||||
return apply_filters('wpcf7dtx_escape', get_bloginfo($key), $obfuscate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Variable from a Post Object
|
||||
*
|
||||
* @link https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/shortcodes/dtx-shortcode-post-page-variables/
|
||||
*
|
||||
* @param array $atts Optional. An associative array of shortcode attributes. Default is an empty array.
|
||||
* @param string $content Optional. A string of content between the opening and closing tags. Default is an empty string.
|
||||
* @param string $tag Optional. The shortcode tag. Default is an empty string.
|
||||
*
|
||||
* @return string Output of the shortcode
|
||||
*/
|
||||
function wpcf7dtx_get_post_var($atts = array(), $content = '', $tag = '')
|
||||
function wpcf7dtx_get_post_var($atts = array())
|
||||
{
|
||||
extract(shortcode_atts(array(
|
||||
'key' => 'post_title',
|
||||
'post_id' => '',
|
||||
'obfuscate' => ''
|
||||
), array_change_key_case((array)$atts, CASE_LOWER)));
|
||||
$key = strtolower(apply_filters('wpcf7dtx_sanitize', $key));
|
||||
switch ($key) {
|
||||
case 'slug':
|
||||
case 'acf_id': // If requesting the handle for ACF, return the post ID
|
||||
case 'id':
|
||||
$key = 'ID';
|
||||
break;
|
||||
case 'slug': // Alias
|
||||
$key = 'post_name';
|
||||
break;
|
||||
case 'title':
|
||||
case 'title': // Alias
|
||||
$key = 'post_title';
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
$post_id = wpcf7dtx_get_post_id($post_id);
|
||||
if ($post_id && is_string($key) && !empty($key)) {
|
||||
$value = sanitize_text_field(trim(strval(get_post_field($key, $post_id))));
|
||||
if ($obfuscate && !empty($value)) {
|
||||
return wpcf7dtx_obfuscate($value);
|
||||
}
|
||||
return $value;
|
||||
if ($post_id) {
|
||||
return apply_filters('wpcf7dtx_escape', get_post_field($key, $post_id), $obfuscate);
|
||||
}
|
||||
return '';
|
||||
}
|
||||
@@ -225,13 +201,13 @@ function wpcf7dtx_get_post_var($atts = array(), $content = '', $tag = '')
|
||||
/**
|
||||
* Get Value from Post Meta Field
|
||||
*
|
||||
* @see https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/shortcodes/dtx-shortcode-post-meta-custom-fields/
|
||||
*
|
||||
* @param array $atts Optional. An associative array of shortcode attributes. Default is an empty array.
|
||||
* @param string $content Optional. A string of content between the opening and closing tags. Default is an empty string.
|
||||
* @param string $tag Optional. The shortcode tag. Default is an empty string.
|
||||
*
|
||||
* @return string Output of the shortcode
|
||||
*/
|
||||
function wpcf7dtx_get_custom_field($atts = array(), $content = '', $tag = '')
|
||||
function wpcf7dtx_get_custom_field($atts = array())
|
||||
{
|
||||
extract(shortcode_atts(array(
|
||||
'key' => '',
|
||||
@@ -239,12 +215,112 @@ function wpcf7dtx_get_custom_field($atts = array(), $content = '', $tag = '')
|
||||
'obfuscate' => ''
|
||||
), array_change_key_case((array)$atts, CASE_LOWER)));
|
||||
$post_id = wpcf7dtx_get_post_id($post_id);
|
||||
if ($post_id && is_string($key) && !empty($key)) {
|
||||
$value = get_post_meta($post_id, $key, true);
|
||||
if ($obfuscate && !empty($value)) {
|
||||
return wpcf7dtx_obfuscate($value);
|
||||
$key = apply_filters('wpcf7dtx_sanitize', $key, 'text');
|
||||
if ($post_id && $key) {
|
||||
return apply_filters('wpcf7dtx_escape', get_post_meta($post_id, $key, true), $obfuscate);
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Variable from the Current Object
|
||||
*
|
||||
* @since 3.4.0
|
||||
*
|
||||
* @link https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/shortcodes/dtx-shortcode-current-variables/
|
||||
*
|
||||
* @param array $atts Optional. An associative array of shortcode attributes. Default is an empty array.
|
||||
*
|
||||
* @return string Output of the shortcode
|
||||
*/
|
||||
function wpcf7dtx_get_current_var($atts = array())
|
||||
{
|
||||
extract(shortcode_atts(array(
|
||||
'key' => 'title',
|
||||
'obfuscate' => ''
|
||||
), array_change_key_case((array)$atts, CASE_LOWER)));
|
||||
$key = apply_filters('wpcf7dtx_sanitize', $key);
|
||||
$temp_key = str_replace('-', '_', sanitize_key($key));
|
||||
if ($temp_key === 'url') {
|
||||
return wpcf7dtx_url($atts); // Getting the current URL is the same for all WordPress pages
|
||||
} elseif (!empty($key)) {
|
||||
$type = '';
|
||||
$obj = null;
|
||||
if (!wp_doing_ajax()) {
|
||||
$obj = get_queried_object(); // Get the current WordPress queried object
|
||||
if (!is_null($obj)) {
|
||||
if ($obj instanceof WP_User) {
|
||||
$type = 'user';
|
||||
} elseif (property_exists($obj, 'ID')) {
|
||||
$type = 'post';
|
||||
} elseif (property_exists($obj, 'term_id')) {
|
||||
$type = 'term';
|
||||
}
|
||||
} elseif (is_archive()) {
|
||||
$type = 'archive';
|
||||
}
|
||||
}
|
||||
switch ($type) {
|
||||
case 'user': // This is an author page
|
||||
switch ($temp_key) {
|
||||
case 'acf_id': // Get handle for Advanced Custom Fields
|
||||
return apply_filters('wpcf7dtx_escape', 'user_' . $obj->ID, $obfuscate);
|
||||
case 'image':
|
||||
case 'featured_image': // Get the profile picture of the user being displayed on the page
|
||||
return apply_filters('wpcf7dtx_escape', get_avatar_url($obj->ID), $obfuscate, 'url');
|
||||
case 'title': // Get author's display name
|
||||
return apply_filters('wpcf7dtx_escape', $obj->display_name, $obfuscate);
|
||||
case 'slug': // Not all author pages use the `user_login` variable for security reasons, so get what is currently displayed as slug
|
||||
return apply_filters('wpcf7dtx_escape', basename(wpcf7dtx_url(array('part' => 'path'))), $obfuscate);
|
||||
default: // Get user value by key should it exist
|
||||
return apply_filters('wpcf7dtx_escape', $obj->get($key), $obfuscate);
|
||||
}
|
||||
case 'post': // This is a post object
|
||||
switch ($temp_key) {
|
||||
case 'image':
|
||||
case 'featured_image': // Get the current post's featured image
|
||||
return wpcf7dtx_get_attachment(array_merge($atts, array('post_id' => $obj->ID)));
|
||||
case 'terms': // Get the current post's assigned terms
|
||||
return wpcf7dtx_get_taxonomy(array_merge($atts, array('post_id' => $obj->ID)));
|
||||
default:
|
||||
// Use the post object shortcode should it exist as a post variable
|
||||
$value = wpcf7dtx_get_post_var(array_merge($atts, array('post_id' => $obj->ID)));
|
||||
if (empty($value)) {
|
||||
// Try post meta if post object variable failed
|
||||
$value = wpcf7dtx_get_custom_field(array_merge($atts, array('post_id' => $obj->ID)));
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
case 'term': // This is a taxonomy with a term ID
|
||||
switch ($key) {
|
||||
case 'id': // Get term ID
|
||||
return apply_filters('wpcf7dtx_escape', $obj->term_id, $obfuscate);
|
||||
case 'acf_id': // Get handle for Advanced Custom Fields
|
||||
return apply_filters('wpcf7dtx_escape', $obj->taxonomy . '_' . $obj->term_id, $obfuscate);
|
||||
case 'title': // Get term name
|
||||
return apply_filters('wpcf7dtx_escape', $obj->name, $obfuscate);
|
||||
default:
|
||||
if (property_exists($obj, $key)) {
|
||||
// Get any property if it exists
|
||||
return apply_filters('wpcf7dtx_escape', $obj->{$key}, $obfuscate);
|
||||
}
|
||||
// Otherwise, try meta data if the property doesn't exist
|
||||
return apply_filters('wpcf7dtx_escape', get_metadata('term', $obj->ID, $key, true), $obfuscate);
|
||||
}
|
||||
case 'archive': // Possibly a date or formats archive
|
||||
switch ($temp_key) {
|
||||
case 'title': // Get archive title
|
||||
return apply_filters('wpcf7dtx_escape', get_the_archive_title(), $obfuscate);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
default: // Possibly a search or 404 page at this point
|
||||
if ($temp_key == 'slug') {
|
||||
// no idea what else to get except the slug maybe
|
||||
return apply_filters('wpcf7dtx_escape', basename(wpcf7dtx_url(array('part' => 'path'))), $obfuscate);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
@@ -253,15 +329,14 @@ function wpcf7dtx_get_custom_field($atts = array(), $content = '', $tag = '')
|
||||
* Get Value from Current User
|
||||
*
|
||||
* Retreives data from the `users` and `usermeta` tables.
|
||||
* Documentation: https://developer.wordpress.org/reference/classes/wp_user/get/
|
||||
*
|
||||
* @see https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/shortcodes/dtx-shortcode-current-user-user-meta/
|
||||
*
|
||||
* @param array $atts Optional. An associative array of shortcode attributes. Default is an empty array.
|
||||
* @param string $content Optional. A string of content between the opening and closing tags. Default is an empty string.
|
||||
* @param string $tag Optional. The shortcode tag. Default is an empty string.
|
||||
*
|
||||
* @return string Output of the shortcode
|
||||
*/
|
||||
function wpcf7dtx_get_current_user($atts = array(), $content = '', $tag = '')
|
||||
function wpcf7dtx_get_current_user($atts = array())
|
||||
{
|
||||
extract(shortcode_atts(array(
|
||||
'key' => 'user_login',
|
||||
@@ -269,11 +344,7 @@ function wpcf7dtx_get_current_user($atts = array(), $content = '', $tag = '')
|
||||
), array_change_key_case((array)$atts, CASE_LOWER)));
|
||||
if (is_user_logged_in()) {
|
||||
$user = wp_get_current_user();
|
||||
$value = $user->get($key);
|
||||
if ($obfuscate && !empty($value)) {
|
||||
return wpcf7dtx_obfuscate($value);
|
||||
}
|
||||
return $value;
|
||||
return apply_filters('wpcf7dtx_escape', $user->get($key), $obfuscate);
|
||||
}
|
||||
return '';
|
||||
}
|
||||
@@ -285,13 +356,13 @@ function wpcf7dtx_get_current_user($atts = array(), $content = '', $tag = '')
|
||||
*
|
||||
* @since 3.1.0
|
||||
*
|
||||
* @see https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/shortcodes/dtx-shortcode-media-attachment/
|
||||
*
|
||||
* @param array $atts Optional. An associative array of shortcode attributes. Default is an empty array.
|
||||
* @param string $content Optional. A string of content between the opening and closing tags. Default is an empty string.
|
||||
* @param string $tag Optional. The shortcode tag. Default is an empty string.
|
||||
*
|
||||
* @return string Output of the shortcode
|
||||
*/
|
||||
function wpcf7dtx_get_attachment($atts = array(), $content = '', $tag = '')
|
||||
function wpcf7dtx_get_attachment($atts = array())
|
||||
{
|
||||
extract(shortcode_atts(array(
|
||||
'id' => '', //Get attachment by ID
|
||||
@@ -303,56 +374,131 @@ function wpcf7dtx_get_attachment($atts = array(), $content = '', $tag = '')
|
||||
|
||||
//No attachment ID was provided, check for post ID to get it's featured image
|
||||
if (empty($id)) {
|
||||
if ($post_id = sanitize_text_field(strval($post_id))) {
|
||||
if ($post_id = wpcf7dtx_get_post_id($post_id)) {
|
||||
//If a post ID was provided, get it's featured image
|
||||
if (is_numeric($post_id) && (int)$post_id > 0) {
|
||||
$id = get_post_thumbnail_id($post_id);
|
||||
}
|
||||
} else {
|
||||
//If no post ID was provided, get current featured image
|
||||
global $post;
|
||||
if (isset($post) && property_exists($post, 'ID') && is_numeric($post->ID)) {
|
||||
$id = get_post_thumbnail_id(intval($post->ID));
|
||||
}
|
||||
$id = get_post_thumbnail_id($post_id);
|
||||
}
|
||||
}
|
||||
|
||||
//Get the value
|
||||
$value = '';
|
||||
if ($id) {
|
||||
$id = intval(sanitize_text_field(strval($id)));
|
||||
switch ($return) {
|
||||
case 'id': //Return the attachment ID
|
||||
$value = esc_attr($id);
|
||||
break;
|
||||
return apply_filters('wpcf7dtx_escape', $id, $obfuscate);
|
||||
default: //Return attachment URL
|
||||
$url = wp_get_attachment_image_url(intval($id), sanitize_text_field(strval($size)));
|
||||
$value = $url ? esc_url($url) : '';
|
||||
break;
|
||||
}
|
||||
if ($obfuscate && !empty($value)) {
|
||||
return wpcf7dtx_obfuscate($value);
|
||||
return apply_filters('wpcf7dtx_escape', $url, $obfuscate, 'url');
|
||||
}
|
||||
}
|
||||
return $value;
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Cookie Value
|
||||
*
|
||||
* Retreives the value of a cookie
|
||||
*
|
||||
* @since 3.3.0
|
||||
*
|
||||
* @see https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/shortcodes/dtx-shortcode-cookie/
|
||||
*
|
||||
* @param array $atts Optional. An associative array of shortcode attributes. Default is an empty array.
|
||||
*
|
||||
* @return string Output of the shortcode
|
||||
*/
|
||||
function wpcf7dtx_get_cookie($atts = array())
|
||||
{
|
||||
extract(shortcode_atts(array(
|
||||
'key' => '',
|
||||
'default' => '',
|
||||
'obfuscate' => '' // Optionally obfuscate returned value
|
||||
), array_change_key_case((array)$atts, CASE_LOWER)));
|
||||
$key = apply_filters('wpcf7dtx_sanitize', $key);
|
||||
$value = wpcf7dtx_array_has_key($key, $_COOKIE, $default);
|
||||
return apply_filters('wpcf7dtx_escape', $value, $obfuscate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Taxonomy
|
||||
*
|
||||
* Retreives a list of taxonomy values
|
||||
*
|
||||
* @since 3.3.0
|
||||
*
|
||||
* @see https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/shortcodes/dtx-shortcode-taxonomy/
|
||||
* @see https://developer.wordpress.org/reference/classes/wp_term_query/get_terms/
|
||||
*
|
||||
* @param array $atts Optional. An associative array of shortcode attributes. Default is an empty array.
|
||||
*
|
||||
* @return string Output of the shortcode
|
||||
*/
|
||||
function wpcf7dtx_get_taxonomy($atts = array())
|
||||
{
|
||||
extract(shortcode_atts(array(
|
||||
'post_id' => '',
|
||||
'taxonomy' => 'category', // Default taxonomy is `category`
|
||||
'fields' => 'names', // Return an array of term names
|
||||
'obfuscate' => '' // Optionally obfuscate returned value
|
||||
), array_change_key_case((array)$atts, CASE_LOWER)));
|
||||
$post_id = wpcf7dtx_get_post_id($post_id);
|
||||
$fields = apply_filters('wpcf7dtx_sanitize', $fields, 'key');
|
||||
if ($post_id && in_array($fields, array('names', 'slugs', 'ids'))) {
|
||||
$terms = wp_get_object_terms(
|
||||
$post_id, // Get only the ones assigned to this post
|
||||
apply_filters('wpcf7dtx_sanitize', $taxonomy, 'slug'),
|
||||
array('fields' => $fields)
|
||||
);
|
||||
if (is_array($terms) && count($values = array_values($terms)) && (is_string($values[0]) || is_numeric($values[0]))) {
|
||||
return apply_filters('wpcf7dtx_escape', implode(', ', $values), $obfuscate, 'text');
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Theme Customization Option
|
||||
*
|
||||
* Retreives theme modification value for the active theme
|
||||
*
|
||||
* @since 3.3.0
|
||||
*
|
||||
* @see https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/shortcodes/dtx-shortcode-theme-option/
|
||||
* @see https://developer.wordpress.org/reference/functions/get_theme_mod/
|
||||
*
|
||||
* @param array $atts Optional. An associative array of shortcode attributes. Default is an empty array.
|
||||
*
|
||||
* @return string Output of the shortcode
|
||||
*/
|
||||
function wpcf7dtx_get_theme_option($atts = array())
|
||||
{
|
||||
extract(shortcode_atts(array(
|
||||
'key' => '',
|
||||
'default' => '', // Optional default value
|
||||
'obfuscate' => '' // Optionally obfuscate returned value
|
||||
), array_change_key_case((array)$atts, CASE_LOWER)));
|
||||
if ($key = apply_filters('wpcf7dtx_sanitize', $key, 'text')) {
|
||||
$default = apply_filters('wpcf7dtx_sanitize', $default);
|
||||
return apply_filters('wpcf7dtx_escape', get_theme_mod($key, $default), $obfuscate);
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* GUID Field
|
||||
*
|
||||
* Generate a random GUID (globally unique identifier)
|
||||
*
|
||||
* @since 3.1.0
|
||||
*
|
||||
* @param array $atts Optional. An associative array of shortcode attributes. Default is an empty array.
|
||||
* @param string $content Optional. A string of content between the opening and closing tags. Default is an empty string.
|
||||
* @param string $tag Optional. The shortcode tag. Default is an empty string.
|
||||
* @see https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/shortcodes/dtx-shortcode-guid/
|
||||
*
|
||||
* @return string Output of the shortcode
|
||||
* @return string a randomly generated 128-bit text string.
|
||||
*/
|
||||
function wpcf7dtx_guid()
|
||||
{
|
||||
if (function_exists('com_create_guid') === true) {
|
||||
return trim(com_create_guid(), '{}');
|
||||
return esc_attr(trim(com_create_guid(), '{}'));
|
||||
}
|
||||
return sprintf('%04X%04X-%04X-%04X-%04X-%04X%04X%04X', mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(16384, 20479), mt_rand(32768, 49151), mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(0, 65535));
|
||||
return esc_attr(sprintf('%04X%04X-%04X-%04X-%04X-%04X%04X%04X', mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(16384, 20479), mt_rand(32768, 49151), mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(0, 65535)));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,140 +1,640 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Custom DTX Allowed Protocols Filter
|
||||
*
|
||||
* @since 3.3.0
|
||||
*
|
||||
* @param array|string $protocols Optional. Specify protocols to allow either as an array of string values or a string value of comma separated protocols.
|
||||
* @param bool $replace Optional. If true, this function will only return the specified values. If false, will merge specified values with default values. Default is false.
|
||||
*
|
||||
* @return array An array of string values, default only includes `http` and `https` protocols.
|
||||
*/
|
||||
function wpcf7dtx_allow_protocols($protocols = false, $replace = false)
|
||||
{
|
||||
// Get user-inputted protocols
|
||||
$user_protocols = false;
|
||||
if (is_string($protocols) && !empty($protocols)) {
|
||||
$user_protocols = explode(',', sanitize_text_field($protocols));
|
||||
} elseif (is_array($protocols) && count($protocols)) {
|
||||
$user_protocols = array_filter(array_values($protocols));
|
||||
}
|
||||
$default = array('http', 'https');
|
||||
if (is_array($user_protocols) && count($user_protocols)) {
|
||||
// Sanitize each value before adding
|
||||
$allowed_protocols = array();
|
||||
foreach ($user_protocols as $protocol) {
|
||||
$allowed_protocols[] = sanitize_text_field($protocol);
|
||||
}
|
||||
if ($replace) {
|
||||
return array_unique($allowed_protocols);
|
||||
}
|
||||
return array_unique(array_merge(array('http', 'https'), $allowed_protocols)); // Return merged values
|
||||
} elseif ($replace) {
|
||||
return array(); // None allowed, apparently
|
||||
}
|
||||
return $default; // Return only default values
|
||||
}
|
||||
add_filter('wpcf7dtx_allow_protocols', 'wpcf7dtx_allow_protocols', 10, 2);
|
||||
|
||||
/**
|
||||
* Custom DTX Sanitize Filter
|
||||
*
|
||||
* @since 3.3.0
|
||||
*
|
||||
* @param string $value value to be sanitized
|
||||
* @param string $type Optional. The type of sanitation to return. Default is `auto` where automatic identification will be used to attempt to identify URLs and email addresses vs text.
|
||||
* @param array|string $protocols Optional. Specify protocols to allow either as an array of string values or a string value of comma separated protocols.
|
||||
*
|
||||
* @return string the sanitized value
|
||||
*/
|
||||
function wpcf7dtx_sanitize($value = '', $type = 'auto', $protocols = false)
|
||||
{
|
||||
if ($type == 'none') {
|
||||
return $value;
|
||||
}
|
||||
$value = is_string($value) ? $value : strval($value); // Force string value
|
||||
if (!empty($value)) {
|
||||
$type = $type == 'auto' ? wpcf7dtx_detect_value_type($value) : sanitize_text_field($type);
|
||||
switch ($type) {
|
||||
case 'email':
|
||||
return sanitize_email($value);
|
||||
case 'url':
|
||||
return sanitize_url($value, apply_filters('wpcf7dtx_allow_protocols', $protocols));
|
||||
case 'key':
|
||||
return sanitize_key($value);
|
||||
case 'slug':
|
||||
return sanitize_title($value);
|
||||
case 'textarea':
|
||||
return sanitize_textarea_field($value);
|
||||
}
|
||||
}
|
||||
return sanitize_text_field($value);
|
||||
}
|
||||
add_filter('wpcf7dtx_sanitize', 'wpcf7dtx_sanitize', 10, 3);
|
||||
|
||||
/**
|
||||
* Custom DTX Escape Filter
|
||||
*
|
||||
* @since 3.3.0
|
||||
*
|
||||
* @param string $value value to be escaped
|
||||
* @param bool $obfuscate Optional. If true, returned value will be obfuscated. Default is false.
|
||||
* @param string $type Optional. The type of escape to return. Default is `auto` where automatic identification will be used to attempt to identify the type of text.
|
||||
* @param array|string $protocols Optional. Specify protocols to allow either as an array of string values or a string value of comma separated protocols.
|
||||
*
|
||||
* @return string the escaped value
|
||||
*/
|
||||
function wpcf7dtx_escape($value = '', $obfuscate = false, $type = 'auto', $protocols = false)
|
||||
{
|
||||
if ($type == 'none') {
|
||||
return $value;
|
||||
}
|
||||
$value = apply_filters('wpcf7dtx_sanitize', $value, $type); // Sanitize value
|
||||
if (!empty($value)) {
|
||||
if ($obfuscate) {
|
||||
return apply_filters('wpcf7dtx_obfuscate', $value); // Return obfuscated value
|
||||
}
|
||||
$type = $type == 'auto' ? wpcf7dtx_detect_value_type($value) : sanitize_text_field($type);
|
||||
switch ($type) {
|
||||
case 'url':
|
||||
return esc_url($value, apply_filters('wpcf7dtx_allow_protocols', $protocols));
|
||||
case 'textarea':
|
||||
return esc_textarea($value);
|
||||
}
|
||||
}
|
||||
return esc_attr($value); // Return attribute value
|
||||
}
|
||||
add_filter('wpcf7dtx_escape', 'wpcf7dtx_escape', 10, 4);
|
||||
|
||||
/**
|
||||
* Detect Value Type
|
||||
*
|
||||
* @since 3.3.0
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @param string $value the value to be identified
|
||||
*
|
||||
* @return string Potentially identifies string values as `url`, `email`, or `text`.
|
||||
*/
|
||||
function wpcf7dtx_detect_value_type($value)
|
||||
{
|
||||
// Try to detect the value type
|
||||
$value = trim($value);
|
||||
$is_https_url = stripos($value, 'https') === 0 && strlen($value) > 5;
|
||||
$is_http_url = stripos($value, 'http') === 0 && strlen($value) > 4 && sanitize_key($value) != 'https';
|
||||
if ($is_https_url || $is_http_url) {
|
||||
return 'url';
|
||||
} elseif (preg_match('/^[^\s@]+@[^\s@]+\.[^\s@]+$/', $value)) {
|
||||
return 'email';
|
||||
}
|
||||
return 'text';
|
||||
}
|
||||
|
||||
/**
|
||||
* Obfuscate a value
|
||||
*
|
||||
* @param mixed $value
|
||||
* @see https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/shortcodes/dtx-attribute-obfuscate/
|
||||
*
|
||||
* @param mixed $value the value to be obfuscated
|
||||
*
|
||||
* @return string obfuscated value
|
||||
*/
|
||||
function wpcf7dtx_obfuscate($value = '')
|
||||
{
|
||||
$return = '';
|
||||
$value = strval($value); //Force value to be string
|
||||
if (!empty($value)) {
|
||||
foreach (str_split($value) as $letter) {
|
||||
$return .= '&#' . ord($letter) . ';';
|
||||
}
|
||||
$o = '';
|
||||
if (!is_string($value)) {
|
||||
$value = sanitize_text_field(strval($value)); // Force value to be string and sanitize it
|
||||
}
|
||||
return sanitize_text_field(trim($return));
|
||||
if (!empty($value)) {
|
||||
$value = htmlentities($value, ENT_QUOTES);
|
||||
foreach (str_split($value) as $letter) {
|
||||
$o .= '&#' . ord($letter) . ';';
|
||||
}
|
||||
return $o; // Return obfuscated value
|
||||
}
|
||||
return esc_attr($value); // Return default attribute escape
|
||||
}
|
||||
add_filter('wpcf7dtx_obfuscate', 'wpcf7dtx_obfuscate', 10, 1);
|
||||
|
||||
/**
|
||||
* Get Post ID
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @param mixed $post_id
|
||||
*
|
||||
* @return int An integer value of the passed post ID or the post ID of the current `$post` global object. 0 on Failure.
|
||||
*/
|
||||
function wpcf7dtx_get_post_id($post_id)
|
||||
function wpcf7dtx_get_post_id($post_id, $context = 'dtx')
|
||||
{
|
||||
$post_id = is_numeric($post_id) && (int)$post_id > 0 ? intval($post_id) : 0;
|
||||
if (!$post_id) {
|
||||
//No post ID was provided, look it up
|
||||
global $post;
|
||||
if (isset($post) && property_exists($post, 'ID')) {
|
||||
$post_id = $post->ID;
|
||||
$post_id = $post_id ? intval(sanitize_text_field(strval($post_id))) : '';
|
||||
if (!$post_id || !is_numeric($post_id)) {
|
||||
if ($context == 'dtx') {
|
||||
if (wp_doing_ajax()) {
|
||||
// If we're doing an AJAX call, just fail quietly
|
||||
return 0;
|
||||
} else {
|
||||
global $post;
|
||||
if (isset($post)) {
|
||||
$post_id = $post->ID; // If the global $post object is set, get its ID
|
||||
} else {
|
||||
$post_id = get_the_ID(); // Otherwise get it from "the loop"
|
||||
}
|
||||
}
|
||||
} elseif ($context == 'acf') {
|
||||
// When a post ID is not specified for ACF keys, it accepts the boolean `false`
|
||||
$post_id = false;
|
||||
}
|
||||
}
|
||||
return $post_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark a shortcode as deprecated and inform when it has been used.
|
||||
* Get Dynamic Value
|
||||
*
|
||||
* The current behavior is to trigger a user error if WP_DEBUG is true.
|
||||
* @since 3.2.2
|
||||
*
|
||||
* This function is to be used in every function that is deprecated.
|
||||
* @param string $value The form tag value.
|
||||
* @param WPCF7_FormTag|false $tag Optional. Use to look up default value.
|
||||
* @param string $sanitize Optional. Specify type of sanitization. Default is `auto`.
|
||||
*
|
||||
* @since 3.1.0
|
||||
* @access private
|
||||
*
|
||||
* @param string $tag The tag of the shortcode that was called.
|
||||
* @param string $version The version of the plugin that deprecated the shortcode.
|
||||
* @param string $replacement Optional. The shortcode that should have been used. Default null.
|
||||
* @return string The dynamic output or the original value, not escaped or sanitized.
|
||||
*/
|
||||
function wpcf7dtx_deprecated_shortcode($tag, $version, $replacement = null, $documentation = null)
|
||||
function wpcf7dtx_get_dynamic($value, $tag = false, $sanitize = 'auto')
|
||||
{
|
||||
/**
|
||||
* Filter whether to trigger an error for deprecated shortcodes.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*
|
||||
* @param bool $trigger Whether to trigger the error for deprecated functions. Default true.
|
||||
*/
|
||||
if (WP_DEBUG && apply_filters('deprecated_function_trigger_error', true)) {
|
||||
if (!is_null($replacement)) {
|
||||
if (!is_null($documentation)) {
|
||||
trigger_error(sprintf(
|
||||
__('%1$s is <strong>deprecated</strong> since version %2$s! Use Contact Form 7\'s built-in attribute "%3$s" instead. Contact Form 7 Documentation: %4$s', 'contact-form-7-dynamic-text-extension'),
|
||||
$tag,
|
||||
$version,
|
||||
$replacement,
|
||||
$documentation
|
||||
));
|
||||
} else {
|
||||
trigger_error(sprintf(
|
||||
__('%1$s is <strong>deprecated</strong> since version %2$s! Use Contact Form 7\'s built-in attribute "%3$s" instead.', 'contact-form-7-dynamic-text-extension'),
|
||||
$tag,
|
||||
$version,
|
||||
$replacement
|
||||
));
|
||||
}
|
||||
} else {
|
||||
trigger_error(sprintf(
|
||||
__('%1$s is <strong>deprecated</strong> since version %2$s with no alternative currently available.', 'contact-form-7-dynamic-text-extension'),
|
||||
$tag,
|
||||
$version
|
||||
));
|
||||
if ($tag !== false) {
|
||||
$default = $tag->get_option('defaultvalue', '', true);
|
||||
if (!$default) {
|
||||
$default = $tag->get_default_option(strval(reset($tag->values)));
|
||||
}
|
||||
$value = wpcf7_get_hangover($tag->name, $default);
|
||||
}
|
||||
$value = apply_filters('wpcf7dtx_sanitize', $value, $sanitize);
|
||||
if (is_string($value) && !empty($value)) {
|
||||
// If a shortcode was passed as the value, evaluate it and use the result
|
||||
$shortcode_tag = '[' . $value . ']';
|
||||
$shortcode_output = do_shortcode($shortcode_tag); //Shortcode value
|
||||
if (is_string($shortcode_output) && $shortcode_output != $shortcode_tag) {
|
||||
return apply_filters('wpcf7dtx_sanitize', $shortcode_output, $sanitize);
|
||||
}
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse Content for Specified Shortcodes
|
||||
* Get Allowed HTML for Form Field Properties
|
||||
*
|
||||
* Parse a string of content for a specific shortcode to retrieve its attributes and content
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @since 3.1.0
|
||||
* @param string $type Optional. The type of input for unique properties. Default is `text`.
|
||||
* @param array $extra Optional. A sequential array of properties to additionally include.
|
||||
*
|
||||
* @param string $content The content to parse
|
||||
* @param string $tag The shortcode tag
|
||||
*
|
||||
* @return array An associative array with `tag` (string) and `shortcodes` (sequential array). If shortcodes were discovered, each one has keys for `atts` (associative array) and `content` (string)
|
||||
* @return array An associative array of allowed properties appropriate for use in `wp_kses()`
|
||||
*/
|
||||
function wpcf7dtx_get_shortcode_atts($content)
|
||||
function wpcf7dtx_get_allowed_field_properties($type = 'text', $extra = array())
|
||||
{
|
||||
$return = array(
|
||||
'tag' => '',
|
||||
'atts' => array()
|
||||
if (in_array($type, array('option', 'optgroup'))) {
|
||||
return array(
|
||||
'optgroup' => array(
|
||||
'label' => array(),
|
||||
'disabled' => array(),
|
||||
'hidden' => array()
|
||||
),
|
||||
'option' => array(
|
||||
'value' => array(),
|
||||
'selected' => array(),
|
||||
'disabled' => array(),
|
||||
'hidden' => array()
|
||||
)
|
||||
);
|
||||
}
|
||||
$allowed_properties = array(
|
||||
// Global properties
|
||||
'type' => 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(),
|
||||
);
|
||||
//Search for shortcodes with attributes
|
||||
if (false !== ($start = strpos($content, ' '))) {
|
||||
$return['tag'] = substr($content, 0, $start); //Opens the start tag, assumes there are attributes because of the space
|
||||
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['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();
|
||||
$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();
|
||||
}
|
||||
if ($type == 'textarea') {
|
||||
// Additional properties exclusive to textarea fields
|
||||
$allowed_properties['cols'] = array();
|
||||
$allowed_properties['rows'] = 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
|
||||
$allowed_properties['pattern'] = array();
|
||||
}
|
||||
}
|
||||
if (is_array($extra) && count($extra)) {
|
||||
foreach ($extra as $property) {
|
||||
$allowed_properties[sanitize_title($property)] = array();
|
||||
}
|
||||
}
|
||||
return $allowed_properties;
|
||||
}
|
||||
|
||||
//Parse for shortcode attributes: `shortcode att1='foo' att2='bar'`
|
||||
|
||||
//Chop only the attributes e.g. `att1="foo" att2="bar"`
|
||||
$atts_str = trim(str_replace($return['tag'], '', $content));
|
||||
if (strpos($atts_str, "'") !== false) {
|
||||
$atts = explode("' ", substr(
|
||||
$atts_str,
|
||||
0,
|
||||
-1 //Clip off the last character, which is a single quote
|
||||
));
|
||||
if (is_array($atts) && count($atts)) {
|
||||
foreach ($atts as $att_str) {
|
||||
$pair = explode("='", $att_str);
|
||||
if (is_array($pair) && count($pair) > 1) {
|
||||
$key = sanitize_key(trim($pair[0])); //Validate & normalize the key
|
||||
if (!empty($key)) {
|
||||
$return['atts'][$key] = sanitize_text_field(html_entity_decode($pair[1]));
|
||||
}
|
||||
/**
|
||||
* Returns a formatted string of HTML attributes
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @param array $atts Associative array of attribute name and value pairs
|
||||
*
|
||||
* @return string Formatted HTML attributes with keys and values both escaped
|
||||
*/
|
||||
function wpcf7dtx_format_atts($atts)
|
||||
{
|
||||
if (is_array($atts) && count($atts)) {
|
||||
$sanitized_atts = array();
|
||||
static $boolean_attributes = array(
|
||||
'checked', 'disabled', 'multiple', 'readonly', 'required', 'selected'
|
||||
);
|
||||
foreach ($atts as $key => $value) {
|
||||
$key = sanitize_key(strval($key));
|
||||
if ($key) {
|
||||
if (in_array($key, $boolean_attributes) || is_bool($value)) {
|
||||
if ($value) {
|
||||
$sanitized_atts[$key] = $key;
|
||||
}
|
||||
} elseif ($value && (is_string($value) || is_numeric($value))) {
|
||||
$sanitized_atts[$key] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (count($sanitized_atts)) {
|
||||
$output = array();
|
||||
foreach ($sanitized_atts as $key => $value) {
|
||||
$output[] = sprintf('%s="%s"', esc_attr($key), esc_attr($value));
|
||||
}
|
||||
return implode(' ', $output);
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
return $return;
|
||||
/**
|
||||
* Create Input Field HTML
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @param array $atts An associative array of input attributes.
|
||||
*
|
||||
* @return string HTML output of input field
|
||||
*/
|
||||
function wpcf7dtx_input_html($atts)
|
||||
{
|
||||
return sprintf('<input %s />', wpcf7dtx_format_atts($atts));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create Checkbox Field HTML
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @param array $atts An associative array of select input attributes.
|
||||
* @param string $label_text Optional. The text to display next to the checkbox or radio button.
|
||||
* @param bool $label_ui Optional. If true, will place input and label text inside a `<label>` element. Default is true.
|
||||
* @param bool $reverse Optional. If true, will reverse the order to display the text label first then the button. Has no effect if label text is empty. Default is false.
|
||||
*
|
||||
* @return string HTML output of the checkbox or radio button or empty string on failure.
|
||||
*/
|
||||
function wpcf7dtx_checkbox_html($atts, $label_text = '', $label_ui = true, $reverse = false)
|
||||
{
|
||||
// Default field attributes
|
||||
$atts = array_merge(array('value' => '', 'dtx-default' => ''), array_change_key_case((array)$atts, CASE_LOWER));
|
||||
if ($atts['value'] && $atts['dtx-default'] && $atts['value'] == $atts['dtx-default']) {
|
||||
$atts['checked'] = 'checked';
|
||||
}
|
||||
$input = wpcf7dtx_input_html($atts);
|
||||
if (!empty(trim($label_text))) {
|
||||
$label_el = $label_ui ? 'span' : 'label'; // If not wrapping with a label element, display it next to it
|
||||
$label_text = sprintf(
|
||||
'<%1$s%2$s class="wpcf7-list-item-label">%3$s</%1$s>',
|
||||
$label_el,
|
||||
// If not wrapping with a label element and the element has an ID attribute, add a `for` attribute
|
||||
$label_ui ? '' : (wpcf7dtx_array_has_key('id', $atts) ? ' for="' . esc_attr($atts['id']) . '"' : ''),
|
||||
esc_html($label_text)
|
||||
);
|
||||
if ($reverse) {
|
||||
$html = $label_text . $input;
|
||||
} else {
|
||||
$html = $input . $label_text;
|
||||
}
|
||||
} else {
|
||||
$html = $input;
|
||||
}
|
||||
if ($label_ui) {
|
||||
$html = '<label>' . $html . '</label>';
|
||||
}
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create Checkbox Group HTML
|
||||
*
|
||||
* @since 4.0.3
|
||||
*
|
||||
* @param array $atts An associative array of select input attributes.
|
||||
* @param array|string $options Accepts an associative array of key/value pairs to use as the
|
||||
* select option's value/label pairs. It also accepts an associative array of associative
|
||||
* arrays with the keys being used as option group labels and the array values used as that
|
||||
* 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 $label_ui Optional. If true, will place input and label text inside a `<label>` element. Default is true.
|
||||
* @param bool $reverse Optional. If true, will reverse the order to display the text label first then the button. Has no effect if label text is empty. Default is false.
|
||||
*
|
||||
* @return string HTML output of the checkbox or radio button or empty string on failure.
|
||||
*/
|
||||
function wpcf7dtx_checkbox_group_html($atts, $options, $label_ui = false, $reverse = false, $exclusive = false)
|
||||
{
|
||||
$group_html = '';
|
||||
if ($count = count($options)) {
|
||||
// Attributes specific to HTML creation
|
||||
$atts = array_merge(array(
|
||||
'type' => 'checkbox',
|
||||
'id' => '',
|
||||
'name' => '',
|
||||
'value' => '',
|
||||
'dtx-default' => ''
|
||||
), array_change_key_case((array)$atts, CASE_LOWER));
|
||||
|
||||
// Loop all the options
|
||||
$group_html = array();
|
||||
$id_prefix = ($atts['id'] ? $atts['id'] : uniqid($atts['name'] . '_')) . '_'; // Create prefix from passed ID or Name
|
||||
$i = 1;
|
||||
foreach ($options as $value => $label) {
|
||||
$my_atts = array_merge($atts, array(
|
||||
'id' => sanitize_html_class($id_prefix . $i) // Always have unique IDs for group items
|
||||
));
|
||||
$dynamic_value = '';
|
||||
$dynamic_label = $label;
|
||||
if ($value && $label && $value === $label) {
|
||||
// These are identical, just handle it as one, could also be a raw shortcode
|
||||
$dynamic_option = trim(wpcf7dtx_get_dynamic($value, false, 'none')); // Do not sanitize yet, it may have HTML
|
||||
if (is_string($dynamic_option) && !empty($dynamic_option) && strpos($dynamic_option, '{') === 0 && strpos($dynamic_option, '}') === strlen($dynamic_option) - 1) {
|
||||
// If it outputs JSON, try parsing it
|
||||
try {
|
||||
$dynamic_option = json_decode($dynamic_option, true);
|
||||
if (is_array($dynamic_option) && count($dynamic_option)) {
|
||||
$group_html[] = wpcf7dtx_checkbox_group_html(
|
||||
$my_atts,
|
||||
$dynamic_option,
|
||||
$label_ui,
|
||||
$reverse,
|
||||
$exclusive
|
||||
);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
// Fail quietly
|
||||
if (WP_DEBUG && WP_DEBUG_LOG) {
|
||||
error_log('[Contact Form 7 - Dynamic Text Extension] Error parsing JSON value');
|
||||
error_log($e->getMessage());
|
||||
}
|
||||
}
|
||||
$i++;
|
||||
continue; // Continue with next iteration
|
||||
} elseif (is_string($dynamic_option) && !empty($dynamic_option) && esc_html($dynamic_option) != $dynamic_option) {
|
||||
$group_html[] = force_balance_tags($dynamic_option); // If it outputs HTML, escape and use them as-is
|
||||
$i++;
|
||||
continue; // Continue with next iteration
|
||||
} else {
|
||||
$dynamic_value = $dynamic_option;
|
||||
$dynamic_label = $dynamic_option;
|
||||
}
|
||||
} else {
|
||||
// These are different, could be raw shortcodes
|
||||
$dynamic_value = wpcf7dtx_get_dynamic($value, false);
|
||||
$dynamic_label = wpcf7dtx_get_dynamic($label, false);
|
||||
}
|
||||
// This could be a single??
|
||||
$class = array('wpcf7-list-item');
|
||||
$class[] = sanitize_html_class('wpcf7-list-item-' . $i);
|
||||
if ($i === 1) {
|
||||
$class[] = 'first';
|
||||
}
|
||||
if ($i === $count) {
|
||||
$class[] = 'last';
|
||||
}
|
||||
if ($exclusive) {
|
||||
$class[] = 'wpcf7-exclusive-checkbox';
|
||||
}
|
||||
if ($dynamic_value && $atts['dtx-default'] && $dynamic_value == $atts['dtx-default']) {
|
||||
$my_atts['checked'] = 'checked';
|
||||
}
|
||||
$group_html[] = sprintf(
|
||||
'<span class="%s">%s</span>',
|
||||
esc_attr(implode(' ', $class)),
|
||||
wpcf7dtx_checkbox_html(
|
||||
// Overwrite name attribute
|
||||
array_merge($my_atts, array(
|
||||
'name' => $atts['type'] == 'radio' || $exclusive || $count === 1 ? $atts['name'] : $atts['name'] . '[]', // if there are multiple checkboxes and they aren't exclusive, names are an array
|
||||
'value' => $dynamic_value
|
||||
)),
|
||||
$dynamic_label,
|
||||
$label_ui,
|
||||
$reverse
|
||||
)
|
||||
);
|
||||
$i++;
|
||||
}
|
||||
$group_html = implode('', $group_html);
|
||||
}
|
||||
return $group_html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create Textarea Field HTML
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @param array $atts An associative array of textarea field attributes.
|
||||
*
|
||||
* @return string HTML output of textarea field
|
||||
*/
|
||||
function wpcf7dtx_textarea_html($atts)
|
||||
{
|
||||
// Attributes specific to HTML creation
|
||||
$atts = array_merge(array('value' => ''), array_change_key_case((array)$atts, CASE_LOWER));
|
||||
return sprintf(
|
||||
'<textarea %s>%s</textarea>',
|
||||
wpcf7dtx_format_atts($atts),
|
||||
apply_filters('wpcf7dtx_escape', $atts['value'], false, 'textarea')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create Select Field HTML
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @param array $atts An associative array of select input attributes.
|
||||
* @param array|string $options Accepts an associative array of key/value pairs to use as the
|
||||
* select option's value/label pairs. It also accepts an associative array of associative
|
||||
* arrays with the keys being used as option group labels and the array values used as that
|
||||
* 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.
|
||||
*
|
||||
* @return string HTML output of select field
|
||||
*/
|
||||
function wpcf7dtx_select_html($atts, $options, $hide_blank = false, $disable_blank = false)
|
||||
{
|
||||
// Attributes specific to HTML creation
|
||||
$atts = array_merge(array('placeholder' => '', 'dtx-default' => ''), array_change_key_case((array)$atts, CASE_LOWER));
|
||||
$options_html = ''; // Open options HTML
|
||||
|
||||
// If using a placeholder, use it as the text of the first option
|
||||
if ($atts['placeholder']) {
|
||||
$options_html .= sprintf(
|
||||
'<option value=""%s%s%s>%s</option>',
|
||||
empty($atts['dtx-default']) ? ' selected' : '',
|
||||
$hide_blank ? ' hidden' : '',
|
||||
$disable_blank ? ' disabled' : '',
|
||||
apply_filters('wpcf7dtx_escape', $atts['placeholder'])
|
||||
);
|
||||
}
|
||||
if (is_array($options) && count($options)) {
|
||||
//Check if using option groups
|
||||
if (is_array(array_values($options)[0])) {
|
||||
foreach ($options as $group_name => $opt_group) {
|
||||
$options_html .= sprintf('<optgroup label="%s">', esc_attr(apply_filters('wpcf7dtx_escape', wpcf7dtx_get_dynamic($group_name)))); // Open option group
|
||||
foreach ($opt_group as $option_value => $option_label) {
|
||||
// Check if option values and groups are dynamic
|
||||
$dynamic_option_value = wpcf7dtx_get_dynamic($option_value);
|
||||
$options_html .= sprintf(
|
||||
'<option value="%1$s"%3$s>%2$s</option>',
|
||||
esc_attr(apply_filters('wpcf7dtx_escape', $dynamic_option_value)),
|
||||
esc_html(apply_filters('wpcf7dtx_escape', wpcf7dtx_get_dynamic($option_label))),
|
||||
$atts['dtx-default'] == $dynamic_option_value ? ' selected' : ''
|
||||
);
|
||||
}
|
||||
$options_html .= '</optgroup>'; // Close option group
|
||||
}
|
||||
} else {
|
||||
$allowed_html = wpcf7dtx_get_allowed_field_properties('option');
|
||||
foreach ($options as $option_value => $option_label) {
|
||||
if ($option_value === $option_label) {
|
||||
// These are identical, just handle it as one, could also be a raw shortcode
|
||||
$dynamic_option = trim(wpcf7dtx_get_dynamic($option_value, false, 'none')); // Do not sanitize yet, it may have HTML
|
||||
if (is_string($dynamic_option) && !empty($dynamic_option) && (strpos($dynamic_option, '<option') === 0 || stripos($dynamic_option, '<optgroup') === 0)) {
|
||||
$options_html .= wp_kses($dynamic_option, $allowed_html); // If it outputs HTML, escape and use them as-is
|
||||
} elseif ($dynamic_option) {
|
||||
// Just output the option
|
||||
$dynamic_option = apply_filters('wpcf7dtx_escape', $dynamic_option);
|
||||
$options_html .= sprintf(
|
||||
'<option value="%1$s"%3$s>%2$s</option>',
|
||||
esc_attr($dynamic_option),
|
||||
esc_html($dynamic_option),
|
||||
$atts['dtx-default'] == $dynamic_option ? ' selected' : ''
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$dynamic_option_value = wpcf7dtx_get_dynamic($option_value, false);
|
||||
$options_html .= sprintf(
|
||||
'<option value="%1$s"%3$s>%2$s</option>',
|
||||
esc_attr(apply_filters('wpcf7dtx_escape', $dynamic_option_value)),
|
||||
esc_html(apply_filters('wpcf7dtx_escape', wpcf7dtx_get_dynamic($option_label))),
|
||||
$atts['dtx-default'] == $dynamic_option_value ? ' selected' : ''
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
} elseif (is_string($options) && !empty($options = trim($options))) {
|
||||
$allowed_html = wpcf7dtx_get_allowed_field_properties('option');
|
||||
// If options were passed as a string, go ahead and use them
|
||||
if (strpos($options, '<option') === 0 || stripos($options, '<optgroup') === 0) {
|
||||
$options_html .= wp_kses($options, $allowed_html);
|
||||
} else {
|
||||
// If a shortcode was passed as the options, evaluate it and use the result
|
||||
$shortcode_output = wpcf7dtx_get_dynamic($options);
|
||||
if (is_string($shortcode_output) && !empty($shortcode_output) && (strpos($shortcode_output, '<option') === 0) || strpos($shortcode_output, '<optgroup') === 0) {
|
||||
$options_html .= wp_kses($shortcode_output, $allowed_html);
|
||||
}
|
||||
}
|
||||
}
|
||||
return sprintf('<select %s>%s</select>', wpcf7dtx_format_atts($atts), $options_html);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -161,21 +661,3 @@ function wpcf7dtx_array_has_key($key, $array = array(), $default = '')
|
||||
}
|
||||
return $default;
|
||||
}
|
||||
|
||||
if (!function_exists('array_key_first')) {
|
||||
/**
|
||||
* Gets the first key of an array
|
||||
*
|
||||
* Gets the first key of the given array without affecting the internal array pointer.
|
||||
*
|
||||
* @param array $array
|
||||
* @return int|string|null
|
||||
*/
|
||||
function array_key_first($array = array())
|
||||
{
|
||||
foreach ($array as $key => $value) {
|
||||
return $key;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,233 @@
|
||||
<?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');
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
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');
|
||||
@@ -0,0 +1 @@
|
||||
<?php // Silence is golden
|
||||
@@ -1,88 +1,183 @@
|
||||
=== Contact Form 7 - Dynamic Text Extension ===
|
||||
Contributors: sevenspark, tessawatkinsllc
|
||||
Donate link: https://just1voice.com/donate/
|
||||
Tags: Contact Form 7, contact, contact form, dynamic, text, input, GET, POST, title, slug, autofill, auto-fill, prepopulate, pre-populate, form field
|
||||
Tested up to: 6.1.1
|
||||
Stable tag: 3.2
|
||||
Tags: Contact Form 7, autofill, prepopulate, input, form field, contact form, text, hidden, input, dynamic, GET, POST, title, slug, auto-fill, pre-populate
|
||||
Tested up to: 6.3
|
||||
Stable tag: 4.1.0
|
||||
|
||||
This plugin provides additional form tags for the Contact Form 7 plugin. It allows dynamic generation of content for text or hidden input fields using any shortcode.
|
||||
This plugin provides additional form tags for the Contact Form 7 plugin. It allows dynamic generation of content for text-based input fields like text, hidden, and email, checkboxes, radio buttons, and drop-down selections using any shortcode.
|
||||
|
||||
== Description ==
|
||||
|
||||
Contact Form 7 is an excellent WordPress plugin and one of the top choices of free WordPress plugins for contact forms. Contact Form 7 - Dynamic Text Extension (DTX) makes it even more awesome by adding dynamic content capabilities. While default values in Contact Form 7 are static, DTX lets you create pre-populated fields based on other values. Some examples might include:
|
||||
Contact Form 7 is an excellent WordPress plugin and one of the top choices of free WordPress plugins for contact forms. Contact Form 7 - Dynamic Text Extension (DTX) makes it even more awesome by adding dynamic content capabilities. While default values in Contact Form 7 are static, DTX lets you create pre-populated fields pulled from other locations. Some examples might include:
|
||||
|
||||
* Auto-filling a URL
|
||||
* Auto-filling a URL or just getting the domain name or path
|
||||
* Auto-filling a post ID, title, or slug
|
||||
* Auto-filling a title, URL, or slug for the current page
|
||||
* Pre-populating a product number
|
||||
* Referencing other content on the site
|
||||
* Populating with post info
|
||||
* Populating with user info
|
||||
* Populating with custom fields
|
||||
* Populating with post or page info
|
||||
* Populating with the current user's info
|
||||
* Populating with custom and meta fields
|
||||
* Generating unique identifiers for support tickets
|
||||
* Getting a list of post categories or other custom taxonomies
|
||||
* Getting a value from a cookie
|
||||
* Getting custom theme modifications
|
||||
* Any value using custom shortcodes
|
||||
|
||||
For over 10 years, DTX only handled `<input type="text" />` and `<input type="hidden" />` form fields, but version 4 finally introduces more:
|
||||
|
||||
* email
|
||||
* URL
|
||||
* tel (for phone numbers)
|
||||
* number
|
||||
* range (slider)
|
||||
* textarea (multiline text)
|
||||
* drop-down menu (select field)
|
||||
* checkboxes
|
||||
* radio buttons
|
||||
* date
|
||||
* submit (yes, a submit button where you can have dynamic text!)
|
||||
|
||||
The possibilities are endless!
|
||||
|
||||
= WHAT DOES IT DO? =
|
||||
## WHAT DOES IT DO? ##
|
||||
|
||||
DTX comes with several built-in shortcodes that will allow the contact form to be populated from HTTPS GET variable or any info from the `get_bloginfo()` function, among others. See below for included shortcodes.
|
||||
DTX provides flexibility to WordPress users in creating dynamic forms in Contact Form 7. DTX comes with several built-in shortcodes that will allow the contact form to be populated from HTTPS GET variable or any info from the `get_bloginfo()` function, among others. See below for included shortcodes.
|
||||
|
||||
Don't see the shortcode you need on the list? You can write a [custom one](https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/shortcodes/custom-shortcodes/?utm_source=wordpress.org&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=readme)! Any shortcode that returns a string or numeric value can be used here. The included shortcodes just cover the most common scenarios, but DTX provides the flexibility for you to grab any value you have access to programmatically.
|
||||
|
||||
= HOW TO USE IT =
|
||||
= Dynamic Value =
|
||||
|
||||
After installing and activating the plugin, you will have 2 new tag types to select from when creating or editing a Contact Form 7 form: the dynamic text field and dynamic hidden field. Most of the options in their tag generators will be familiar to Contact Form 7 users but there have been some upgrades.
|
||||
|
||||
**Dynamic Value**
|
||||
|
||||
This fields can take a shortcode, with two important provisions:
|
||||
The bread and butter of this plugin, set a dynamic value! This field can take any shortcode, with two important provisions:
|
||||
|
||||
1. The shortcode should NOT include the normal square brackets (`[` and `]`). So, instead of `[CF7_GET key='value']` you would use `CF7_GET key='value'`.
|
||||
1. Any parameters in the shortcode must use single quotes. That is: `CF7_GET key='value'` and not `CF7_GET key="value"`
|
||||
|
||||
**Dynamic placeholder**
|
||||
= Dynamic Placeholder =
|
||||
|
||||
Only available for the dynamic text form tag, this field can take static text or a shortcode. If using a shortcode, the same syntax applies from the dynamic value field. However, this field also has a few more needs:
|
||||
Set a dynamic placeholder with this attribute! This feature accepts static text or a shortcode. If using a shortcode, the same syntax applies from the dynamic value field. However, this field also has a few more needs:
|
||||
|
||||
1. The text/shortcode must first have apostrophes converted to it's HTML entity code, `'`
|
||||
1. After that, it must be URL encoded so that spaces become `%20` and other non-alphanumeric characters are converted.
|
||||
|
||||
**Read Only Attribute**
|
||||
If you're using Contact Form 7's tag generator to create the form tag, those extra needs are already taken care of. Dynamic placeholders are not available for dynamic hidden form tags.
|
||||
|
||||
Only available for the dynamic text form tag, simply check this box if you do not want to let users edit this field. It will add the `readonly` attribute to your form field.
|
||||
Learn more and see examples from [the DTX Knowledge base](https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/shortcodes/dtx-attribute-placeholder/?utm_source=wordpress.org&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=readme).
|
||||
|
||||
= INCLUDED SHORTCODES =
|
||||
= Compatible with Caching Plugins =
|
||||
|
||||
DTX is cache friendly! You can set a field to be calculated after the page loads by setting the `dtx_pageload` attribute to any dynamic form tag.
|
||||
|
||||
Many websites use caching plugins to optimize for performance. If your website caches the HTML of the form, then any dynamic form fields you have get their first calculated value cached alongside it. This becomes an issue if you're using DTX to pull values from a cookie or the current URL's query string.
|
||||
|
||||
This is best for dynamic form fields that:
|
||||
|
||||
* gets the current URL
|
||||
* gets a value from the URL query
|
||||
* gets a value from a cookie
|
||||
* gets the current user's info
|
||||
* generates a unique identifier (GUID)
|
||||
|
||||
For dynamic fields that are page-specific, it's perfectly safe to cache those values. For example, dynamic form fields that:
|
||||
|
||||
* getting the page or post's ID, title, or slug
|
||||
* getting post meta for the current page
|
||||
* getting the post's assigned categories, tags, or other custom taxonomy
|
||||
* getting site info
|
||||
* getting theme modification values
|
||||
|
||||
*Note: Enabling a dynamic field to be calculated after the page loads will add frontend JavaScript. Depending on the shortcode used as the dynamic value, an AJAX call to the server may be sent to be processed. The script is minified and loaded in the footer and is deferred, minimizing impact on site performance and the AJAX calls are called asynchronously to avoid being a render-blocking resource and minimizing main-thread work. The script itself can be safely cached too.*
|
||||
|
||||
Learn more and see examples from [the DTX Knowledge base](https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/form-tag-attribute-after-page-load/?utm_source=wordpress.org&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=readme).
|
||||
|
||||
= Read Only Form Fields =
|
||||
|
||||
Check this box if you do not want to let users edit this field. It will add the `readonly` attribute to the input form field. This feature is not available for dynamic hidden form tags.
|
||||
|
||||
= Obfuscate Values for Enhanced Privacy =
|
||||
|
||||
If you're pre-filling a form field with an email address, bots can scrape that value from the page and use it for spam. You can add an additional layer of protecting by obfuscating the value, which turns each character into it's ASCII code. To the human eye, it looks like the character it's supposed to be because browsers will render the ASCII code, but for bots, it won't look like an email address!
|
||||
|
||||
## HOW TO USE IT ##
|
||||
|
||||
After installing and activating the plugin, you will have 2 new tag types to select from when creating or editing a Contact Form 7 form: the dynamic text field and dynamic hidden field. Most of the options in their tag generators will be familiar to Contact Form 7 users but there have been some upgrades.
|
||||
|
||||
= How to Obfuscate Values =
|
||||
|
||||
All of the shortcodes included with the DTX plugin allow the `obfuscate` attribute that you can set to any truthy value to provide an additional layer of security for sensitive data.
|
||||
|
||||
The Contact Form 7 tag with obfuscation turned on would look like this: `[dynamictext user_email "CF7_get_current_user key='user_email' obfuscate='on'"]`
|
||||
|
||||
= How to Enable Cache-Friendly Mode =
|
||||
|
||||
All of the dynamic form tags can be enabled for processing on the frontend of the website, or the client-side, by adding the `dtx_pageload` attribute to the Contact Form 7 form tag.
|
||||
|
||||
In the form editor of Contact Form 7, your form tag would look like: `[dynamictext current_url dtx_pageload "CF7_URL"]`
|
||||
|
||||
If using the tag generator, it's as simple as checking a box!
|
||||
|
||||
## INCLUDED SHORTCODES ##
|
||||
|
||||
The plugin includes several shortcodes for use with the Dynamic Text Extension right out of the box. You can write your own as well—any self-closing shortcode will work, even with attributes!
|
||||
|
||||
**Current URL or Current URL Part**
|
||||
= Current URL or Part =
|
||||
|
||||
Retrieve the current URL: `CF7_URL`
|
||||
|
||||
Your Contact Form 7 Tag would look like: `[dynamictext dynamicname "CF7_URL"]`
|
||||
In the form editor of Contact Form 7, your form tag would look like: `[dynamictext dynamicname "CF7_URL"]`
|
||||
|
||||
Optional parameter: `part`, which will return a parsed part of the URL. Valid values are `host`, `query`, and `path`
|
||||
|
||||
Host: Just the domain name and tld
|
||||
Host: Just the domain name and tld
|
||||
`[dynamictext host "CF7_URL part='host'"]`
|
||||
|
||||
Query: The query string after the ?, if one exists
|
||||
Query: The query string after the ?, if one exists
|
||||
`[dynamictext query "CF7_URL part='query'"]`
|
||||
|
||||
Path: The URL path, for example, /contact, if one exists
|
||||
Path: The URL path, for example, /contact, if one exists
|
||||
`[dynamictext path "CF7_URL part='path'"]`
|
||||
|
||||
Learn more and see examples from [the DTX Knowledge base](https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/shortcodes/dtx-shortcode-current-url/?utm_source=wordpress.org&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=readme).
|
||||
|
||||
|
||||
**Referrer URL**
|
||||
= Referrer URL =
|
||||
|
||||
Get the referral URL, if it exists. Note that this is not necessarily reliable as not all browsers send this data.
|
||||
|
||||
CF7 Tag: `[dynamictext dynamicname "CF7_referrer"]`
|
||||
|
||||
**Post/Page Info**
|
||||
Learn more and see examples from [the DTX Knowledge base](https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/shortcodes/dtx-shortcode-referrer-url/?utm_source=wordpress.org&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=readme).
|
||||
|
||||
Retrieve information about the current post or page that the contact form is displayed on. The shortcode works as follows:
|
||||
= Current Page Variables =
|
||||
|
||||
Retrieve information about the current page that the contact form is displayed on. Works great for use in templated areas like the site header, footer, widget, or sidebar! The shortcode works as follows:
|
||||
|
||||
Built-in shortcode: `CF7_get_current_var`
|
||||
|
||||
Required attribute: `key`
|
||||
|
||||
Possible values for `key` include:
|
||||
|
||||
* `id`
|
||||
* `title`
|
||||
* `url` (an alias for `CF7_URL`)
|
||||
* `slug`
|
||||
* `featured_image`
|
||||
* `terms` (an alias for `CF7_get_taxonomy`)
|
||||
|
||||
For pages that use a `WP_POST` object, this acts as an alias for `CF7_get_post_var` so those attributes work here as well.
|
||||
|
||||
For author pages, this acts as an alias for `CF7_get_current_user` so those attributes work here as well.
|
||||
|
||||
In the form editor of Contact Form 7, your form tag's value could look like: `CF7_get_current_var key='title'`
|
||||
|
||||
And then the full form tag would be: `[dynamictext dynamicname "CF7_get_current_var key='title'"]`
|
||||
|
||||
Learn more and see examples from [the DTX Knowledge base](https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/shortcodes/dtx-shortcode-current-variables/?utm_source=wordpress.org&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=readme).
|
||||
|
||||
= Post/Page Info =
|
||||
|
||||
Retrieve information about the current post or page (must be for a WP_POST object) that the contact form is displayed on. The shortcode works as follows:
|
||||
|
||||
`CF7_get_post_var key='title'` <-- retrieves the Post's Title
|
||||
`CF7_get_post_var key='slug'` <-- retrieves the Post's Slug
|
||||
@@ -97,7 +192,9 @@ Dynamic value: `CF7_get_post_var key='title' post_id='245'`
|
||||
|
||||
Contact Form 7 Tag: `[dynamictext dynamicname "CF7_get_post_var key='title' post_id='245'"]`
|
||||
|
||||
**Post Meta & Custom Fields**
|
||||
Learn more and see examples from [the DTX Knowledge base](https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/shortcodes/dtx-shortcode-post-page-variables//?utm_source=wordpress.org&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=readme).
|
||||
|
||||
= Post Meta & Custom Fields =
|
||||
|
||||
Retrieve custom fields from the current post/page. Just set the custom field as the key in the shortcode.
|
||||
|
||||
@@ -108,7 +205,9 @@ And the tag looks like this: `[dynamictext dynamicname "CF7_get_custom_field key
|
||||
For the purposes of including an email address, you can obfuscate the custom field value by setting obfuscate='on' in the shortcode like this:
|
||||
`[dynamictext dynamicname "CF7_get_custom_field key='my_custom_field' obfuscate='on'"]`
|
||||
|
||||
**Featured Images & Media Attachments**
|
||||
Learn more and see examples from [the DTX Knowledge base](https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/shortcodes/dtx-shortcode-post-meta-custom-fields/?utm_source=wordpress.org&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=readme).
|
||||
|
||||
= Featured Images & Media Attachments =
|
||||
|
||||
Retrieve the current post's featured image, the featured image of a different page, or any attachment from the Media Library with this shortcode!
|
||||
|
||||
@@ -130,7 +229,9 @@ If I wanted to get a specific image at a specific size, I can use this:
|
||||
|
||||
The only two attributes that can’t play together is `id` and `post_id`. If both are specified, it will get the attachment specified by `id` and completely ignore the `post_id` attribute. If neither are specified, then it looks to the current featured image assigned to the global `$post` object.
|
||||
|
||||
**Current User Info & User Meta**
|
||||
Learn more and see examples from [the DTX Knowledge base](https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/shortcodes/dtx-shortcode-media-attachment/?utm_source=wordpress.org&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=readme).
|
||||
|
||||
= Current User Info & User Meta =
|
||||
|
||||
Get data about the current logged-in user.
|
||||
|
||||
@@ -152,7 +253,9 @@ But also custom meta user keys!
|
||||
For the purposes of including an email address, you can obfuscate the value by setting obfuscate='on' in the shortcode like this:
|
||||
`[dynamictext dynamicname "CF7_get_current_user key='user_email' obfuscate='on'"]`
|
||||
|
||||
**Site/Blog Info**
|
||||
Learn more and see examples from [the DTX Knowledge base](https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/shortcodes/dtx-shortcode-current-user-user-meta/?utm_source=wordpress.org&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=readme).
|
||||
|
||||
= Site/Blog Info =
|
||||
|
||||
Want to grab some information from your blog like the URL or the site name? Use the `CF7_bloginfo` shortcode. For example, to get the site's URL:
|
||||
|
||||
@@ -162,7 +265,15 @@ Your Content Form 7 Tag will look something like this: `[dynamictext dynamicname
|
||||
|
||||
Your form's dynamicname text input will then be pre-populated with your site's URL
|
||||
|
||||
**HTTP GET Variables**
|
||||
Learn more and see examples from [the DTX Knowledge base](https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/shortcodes/dtx-shortcode-site-blog-information/?utm_source=wordpress.org&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=readme).
|
||||
|
||||
= Theme Options =
|
||||
|
||||
Want to retrieve values from your active theme's Customizer? Now you can with the `CF7_get_theme_option` shortcode.
|
||||
|
||||
Learn more and see examples from [the DTX Knowledge base](https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/shortcodes/dtx-shortcode-theme-option/?utm_source=wordpress.org&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=readme).
|
||||
|
||||
= HTTP GET Variables =
|
||||
|
||||
Want to use a variable from the PHP `$_GET` array? Just use the `CF7_GET` shortcode. For example, if you want to get the foo parameter from the url
|
||||
`http://mysite.com?foo=bar`
|
||||
@@ -173,7 +284,9 @@ Your Content Form 7 Tag will look something like this: `[dynamictext dynamicname
|
||||
|
||||
Your form's dynamicname text input will then be pre-populated with the value of `foo`, in this case, `bar`
|
||||
|
||||
**HTTP POST Variables**
|
||||
Learn more and see examples from [the DTX Knowledge base](https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/shortcodes/dtx-shortcode-php-get-variables/?utm_source=wordpress.org&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=readme).
|
||||
|
||||
= HTTP POST Variables =
|
||||
|
||||
Grab variables from the PHP `$_POST` array. The shortcode is much like the GET shortcode:
|
||||
|
||||
@@ -181,15 +294,25 @@ Dynamic value: `CF7_POST key='foo'`
|
||||
|
||||
Your Content Form 7 Tag will look something like this: `[dynamictext dynamicname "CF7_POST key='foo'"]`
|
||||
|
||||
**GUID**
|
||||
Learn more and see examples from [the DTX Knowledge base](https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/shortcodes/dtx-shortcode-php-post-variables/?utm_source=wordpress.org&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=readme).
|
||||
|
||||
= Cookie Values =
|
||||
|
||||
If your WordPress website uses cookies, you might want to pull the value of a specific cookie into a form. You can do that with the `CF7_get_cookie` shortcode. It only needs a `key` attribute.
|
||||
|
||||
Dynamic value: `CF7_get_cookie key='foo'`
|
||||
|
||||
Your Content Form 7 Tag will look something like this: `[dynamictext dynamicname "CF7_get_cookie key='foo'"]`
|
||||
|
||||
Learn more and see examples from [the DTX Knowledge base](https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/shortcodes/dtx-shortcode-cookie/?utm_source=wordpress.org&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=readme).
|
||||
|
||||
= GUID =
|
||||
|
||||
Generate a globally unique identifier (GUID) in a form field. This is a great utility shortcode for forms that need unique identifiers for support tickets, receipts, reference numbers, etc., without having to expose personally identifiable information (PII). This shortcode takes no parameters: `CF7_guid`
|
||||
|
||||
Your Contact Form 7 Tag would look like: `[dynamictext dynamicname "CF7_guid"]`
|
||||
In the form editor of Contact Form 7, your form tag would look like: `[dynamictext dynamicname "CF7_guid"]`
|
||||
|
||||
**Shortcode attribute: obfuscate**
|
||||
|
||||
All of the included shortcodes have an `obfuscate` attribute that you can set to any truthy value to provide an additional layer of security for sensitive data.
|
||||
Learn more and see examples from [the DTX Knowledge base](https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/shortcodes/dtx-shortcode-guid/?utm_source=wordpress.org&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=readme).
|
||||
|
||||
== Installation ==
|
||||
|
||||
@@ -232,7 +355,20 @@ This method is the most involved as it requires you to be familiar with the proc
|
||||
|
||||
== Screenshots ==
|
||||
|
||||
1. A screenshot of the form-tag generator for the dynamic text field.
|
||||
1. Screenshot of the form tag buttons in the form editor of Contact Form 7. The dynamic buttons appear in purple instead of blue to visually set them apart.
|
||||
2. The form tag generator screen for the dynamic text form tag
|
||||
3. The form tag generator screen for the dynamic hidden form tag
|
||||
4. The form tag generator screen for the dynamic email form tag
|
||||
5. The form tag generator screen for the dynamic URL form tag
|
||||
6. The form tag generator screen for the dynamic phone number (tel) form tag
|
||||
7. The form tag generator screen for the dynamic number spinbox form tag
|
||||
8. The form tag generator screen for the dynamic sliding range form tag
|
||||
9. The form tag generator screen for the dynamic textarea form tag
|
||||
10. The form tag generator screen for the dynamic drop-down menu (select) form tag
|
||||
11. The form tag generator screen for the dynamic checkboxes form tag
|
||||
12. The form tag generator screen for the dynamic radio buttons form tag
|
||||
13. The form tag generator screen for the dynamic date form tag
|
||||
14. The form tag generator screen for the dynamic submit form tag
|
||||
|
||||
== Frequently Asked Questions ==
|
||||
|
||||
@@ -240,124 +376,54 @@ Please check out the [FAQ on our website](https://aurisecreative.com/docs/contac
|
||||
|
||||
== Upgrade Notice ==
|
||||
|
||||
* 3.1.3 Fixed the syntax error that reappeared in 3.1.2. My apologies!
|
||||
= 4.1.0 =
|
||||
Extend functionality without losing your work!
|
||||
|
||||
== Changelog ==
|
||||
|
||||
= 3.2 =
|
||||
= 4.1.0 =
|
||||
|
||||
* Feature: Add optional 'part' parameter to CF7_URL shortcode to retrieve Host, Query, or Path from current URL
|
||||
* Updated minimum PHP requirement to 7.4 moving forward
|
||||
* Update branding assets
|
||||
* Update Tested Up To to 6.1.1
|
||||
* Plugin will now be jointly maintained by SevenSpark and AuRise Creative
|
||||
* Feature: Looks for a `dtx.php` file in the `wp_content` directory to maybe load custom shortcodes, [see support thread](https://wordpress.org/support/topic/how-to-avoid-custom-shortcodes-being-overwritten-on-updates/)
|
||||
* Feature: Looks for a `dtx.php` file in the current active theme's directory to maybe load custom shortcodes, [see support thread](https://wordpress.org/support/topic/how-to-avoid-custom-shortcodes-being-overwritten-on-updates/)
|
||||
* Feature: Looks for a `dtx.php` file in the current active theme's parent directory to maybe load custom shortcodes, [see support thread](https://wordpress.org/support/topic/how-to-avoid-custom-shortcodes-being-overwritten-on-updates/)
|
||||
* Fix: addressed user reported bug, [see support thread](https://wordpress.org/support/topic/fatal-error-v4-0-3/)
|
||||
|
||||
= 4.0.3 =
|
||||
|
||||
= 3.1.3 =
|
||||
* Feature: Added `exclusive` option to checkbox tag generator
|
||||
* Fix: addressed bug that put all dynamic checkbox/radio options into one
|
||||
* Fix: addressed bug in frontend validator for multiple selected values
|
||||
|
||||
* Fix: Fixed the syntax error that reappeared in 3.1.2.
|
||||
= 4.0.2 =
|
||||
|
||||
= 3.1.2 =
|
||||
* Fix: addressed bug that put all dynamic select options into one, [see support thread](https://wordpress.org/support/topic/dynamic-select-get-option-values-from-shortcode/)
|
||||
* Update: sanitizing and escaping filters now accept `none` as value for `$type` to bypass. Use with caution.
|
||||
|
||||
**Release Date: January 27, 2023**
|
||||
= 4.0.1 =
|
||||
|
||||
* Fix: updated the text domain to match the plugin slug
|
||||
* Fix: updated all of the translated strings to match
|
||||
* Fix: addressed bug that prevented translation for cache compatibility description
|
||||
|
||||
= 3.1.1 =
|
||||
= 4.0.0 =
|
||||
|
||||
**Release Date: January 26, 2023**
|
||||
* Major: modified function names
|
||||
* Major: deprecated `dynamictext` and `dynamichidden` form tags in favor of `dynamic_text` and `dynamic_hidden`. For more information, see the [knowledge base](https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/form-tags/?utm_source=wordpress.org&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=readme)
|
||||
* Feature: introduced `dynamic_email` form tag. For usage details, see the [knowledge base](https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/form-tags/dynamic-email/?utm_source=wordpress.org&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=readme)
|
||||
* Feature: introduced `dynamic_url` form tag. For usage details, see the [knowledge base](https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/form-tags/dynamic-url/?utm_source=wordpress.org&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=readme)
|
||||
* Feature: introduced `dynamic_tel` form tag. For usage details, see the [knowledge base](https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/form-tags/dynamic-tel/?utm_source=wordpress.org&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=readme)
|
||||
* Feature: introduced `dynamic_number` form tag. For usage details, see the [knowledge base](https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/form-tags/dynamic-number/?utm_source=wordpress.org&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=readme)
|
||||
* Feature: introduced `dynamic_range` form tag. For usage details, see the [knowledge base](https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/form-tags/dynamic-range/?utm_source=wordpress.org&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=readme)
|
||||
* Feature: introduced `dynamic_textarea` form tag. For usage details, see the [knowledge base](https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/form-tags/dynamic-textarea/?utm_source=wordpress.org&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=readme)
|
||||
* Feature: introduced `dynamic_select` form tag. For usage details, see the [knowledge base](https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/form-tags/dynamic-select/?utm_source=wordpress.org&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=readme)
|
||||
* Feature: introduced `dynamic_radio` form tag. For usage details, see the [knowledge base](https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/form-tags/dynamic-radio/?utm_source=wordpress.org&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=readme)
|
||||
* Feature: introduced `dynamic_date` form tag. For usage details, see the [knowledge base](https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/form-tags/dynamic-date/?utm_source=wordpress.org&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=readme)
|
||||
* Feature: introduced `dynamic_submit` form tag. For usage details, see the [knowledge base](https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/form-tags/dynamic-submit/?utm_source=wordpress.org&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=readme)
|
||||
* Feature: introduced `dtx_hide_blank` form tag attribute for `dynamic_select`. For usage details, see the [knowledge base](https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/form-tags/dynamic-select/?utm_source=wordpress.org&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=readme)
|
||||
* Feature: introduced `dtx_disable_blank` form tag attribute for `dynamic_select`. For usage details, see the [knowledge base](https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/form-tags/dynamic-select/?utm_source=wordpress.org&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=readme)
|
||||
* Feature: added mail validation for `dynamic_email` and `dynamic_hidden` for backend configuration. For more information, see the [FAQ](https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/frequently-asked-questions/?utm_source=wordpress.org&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=readme)
|
||||
* Feature: added the Akismet feature to DTX text, email, and URL form tags.
|
||||
* Update: adjusted how queued values were sent for cache compatibility mode to allow for multiline values in textareas
|
||||
* Removed unused utility functions
|
||||
|
||||
* Fix: Fixed the syntax error: Parse error: syntax error, unexpected `)` in /wp-content/plugins/contact-form-7-dynamic-text extension/includes/admin.php on line 212
|
||||
= Older Releases =
|
||||
|
||||
= 3.1.0 =
|
||||
|
||||
**Release Date: January 25, 2023**
|
||||
|
||||
* Feature: Added the `CF7_get_attachment` shortcode. For usage details, see the [knowledge base](https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/shortcodes/dtx-shortcode-media-attachment/?utm_source=wordpress.org&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=readme)
|
||||
* Feature: Added the `CF7_guid` shortcode. For usage details, see the [knowledge base](https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/shortcodes/dtx-shortcode-guid/?utm_source=wordpress.org&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=readme).
|
||||
* Feature: Added the dynamic placeholder option to the dynamic form tags that allows you to specify dynamic or static placeholder content while also setting dynamic values. For usage details, see the [knowledge base](https://aurisecreative.com/docs/contact-form-7-dynamic-text-extension/shortcodes/dtx-attribute-placeholder/?utm_source=wordpress.org&utm_medium=link&utm_campaign=contact-form-7-dynamic-text-extension&utm_content=readme)
|
||||
* Feature: Added a "required" dynamic hidden tag (e.g., `[dynamichidden* ...]`). It is identical to the original dynamic hidden tag (as in the field is not actually validated as required because it is hidden); it just doesn't break your website if you use it. This feature was requested by a user.
|
||||
* Feature: Added the `obfuscate` attribute to all included shortcodes
|
||||
|
||||
= 3.0.0 =
|
||||
|
||||
**Release Date: January 17, 2023**
|
||||
|
||||
* Major: Plugin was adopted by AuRise Creative
|
||||
* Major: All functions use the `wpcf7dtx_` prefix
|
||||
* Feature: Added a `post_id` key for the `CF7_get_post_var` shortcode so you can specify a different post
|
||||
* Feature: Updated the `CF7_get_current_user` shortcode to be able to pull data from user metadata too
|
||||
* Feature: Added the "obfuscate" option to `CF7_get_custom_field` shortcode
|
||||
* Feature: Added the "placeholder" checkbox option to the `dynamictext` tag
|
||||
* Fix: Added additional validation for post ID input
|
||||
* Fix: Added additional validation for the `key` attribute in the `CF7_GET` and `CF7_POST` shortcodes
|
||||
* Fix: Shortcode keys are normalized into lowercase before processing
|
||||
* Security: Sanitizing URLs for the `CF7_URL` and `CF7_referrer` shortcode outputs
|
||||
* Feature/Security: Added a `allowed_protocols` attribute to the `CF7_URL` and `CF7_referrer` shortcodes that defaults to `http,https`
|
||||
|
||||
= 2.0.3 =
|
||||
|
||||
* Security: [Fix Reflected XSS](https://web.archive.org/web/20230121180428/https://sevenspark.com/docs/cf7-dtx-security-2019-07-24)
|
||||
|
||||
= 2.0.2.1 =
|
||||
|
||||
* Update changelog properly for 2.0.2 changes:
|
||||
|
||||
= 2.0.2 =
|
||||
|
||||
* Update deprecated `get_currentuserinfo()` function to `wp_get_current_user()`
|
||||
* Update deprecated functions from `WPCF7_add_shortcode` to `WPCF7_add_formtag` and class from `WPCF7_Shortcode` to `WPCF7_FormTag` to comply with CF7 4.6 changes
|
||||
|
||||
= 2.0.1 =
|
||||
|
||||
* Hook change to guarantee the plugin only runs when Contact Form 7 is present in the admin (avoids errors if Contact Form 7 is disabled, or if there is a plugin sequencing issue)
|
||||
|
||||
= 2.0 =
|
||||
|
||||
* Complete rewrite for Compatibility with Contact Form 7 v4
|
||||
|
||||
= 1.2 =
|
||||
|
||||
* Compatibility update for Contact Form 7 v3.9
|
||||
|
||||
= 1.1.0.2 =
|
||||
|
||||
* Updated to work with Contact Form 7 v3.7.x
|
||||
|
||||
= 1.1.0.1 =
|
||||
|
||||
* Removed undefined variable warning
|
||||
|
||||
= 1.1 =
|
||||
|
||||
* Updated for compatibility with Contact Form 7 v3.6
|
||||
* Added Referrer shortcode
|
||||
|
||||
= 1.0.4.2 =
|
||||
|
||||
* Fixed a bug that created repeating square brackets around dynamic text values in cases where the form doesn't validate and JavaScript is deactivated.
|
||||
|
||||
= 1.0.4.1 =
|
||||
|
||||
* Removed trailing whitespace to fix "Headers already sent" errors
|
||||
|
||||
= 1.0.4 =
|
||||
|
||||
* Added Current User Info shortcode
|
||||
* Added Post Custom Field shortcode (with obfuscation support)
|
||||
* Added Hidden Field capability
|
||||
|
||||
= 1.0.3 =
|
||||
|
||||
* Added $_POST shortcode
|
||||
* Added current post/page variable shortcode
|
||||
* Added current URL shortcode
|
||||
|
||||
= 1.0.2 =
|
||||
|
||||
* Fixed administrative control panel dependency issue
|
||||
|
||||
= 1.0.1 =
|
||||
|
||||
* Fixed dependency issue.
|
||||
Please see our [additional changelog.txt file](https://plugins.trac.wordpress.org/browser/contact-form-7-dynamic-text-extension/trunk/changelog.txt)
|
||||
@@ -1,367 +0,0 @@
|
||||
<?php
|
||||
/*
|
||||
Plugin Name: Contact Form 7 Modules: Hidden Fields
|
||||
Plugin URI: https://katz.co/contact-form-7-hidden-fields/
|
||||
Description: Add hidden fields to the popular Contact Form 7 plugin.
|
||||
Author: Katz Web Services, Inc.
|
||||
Author URI: http://www.katz.co
|
||||
Version: 2.0.2
|
||||
Text Domain: cf7_modules
|
||||
Domain Path: languages
|
||||
License: GPLv2 or later
|
||||
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*/
|
||||
|
||||
add_action('plugins_loaded', 'contact_form_7_hidden_fields', 11);
|
||||
|
||||
function contact_form_7_hidden_fields() {
|
||||
global $pagenow;
|
||||
if ( class_exists( 'WPCF7_Shortcode' ) || class_exists('WPCF7_FormTag') ) {
|
||||
if ( function_exists( 'wpcf7_add_form_tag' ) ) {
|
||||
wpcf7_add_form_tag( array( 'hidden', 'hidden*' ), 'wpcf7_hidden_shortcode_handler', true );
|
||||
} else {
|
||||
wpcf7_add_shortcode( array( 'hidden', 'hidden*' ), 'wpcf7_hidden_shortcode_handler', true );
|
||||
}
|
||||
} else {
|
||||
if ( $pagenow != 'plugins.php' ) {
|
||||
return;
|
||||
}
|
||||
|
||||
add_action( 'admin_notices', 'contact_form_7_hidden_fields_error' );
|
||||
add_action( 'admin_enqueue_scripts', 'contact_form_7_hidden_fields_scripts' );
|
||||
}
|
||||
}
|
||||
|
||||
function contact_form_7_hidden_fields_error() {
|
||||
$out = '<div class="error" id="messages"><p>';
|
||||
if ( @ file_exists( WP_PLUGIN_DIR . '/contact-form-7/wp-contact-form-7.php' ) ) {
|
||||
$out .= esc_html__( 'The Contact Form 7 is installed, but you must activate Contact Form 7 below for the Hidden Fields Module to work.', 'cf7_modules' );
|
||||
} else {
|
||||
$out .= esc_html__( 'The Contact Form 7 plugin must be installed for the Hidden Fields Module to work.', 'cf7_modules' );
|
||||
$install_url = esc_url_raw( admin_url( 'plugin-install.php?tab=plugin-information&plugin=contact-form-7&from=plugins&TB_iframe=true&width=600&height=550' ) );
|
||||
$out .= sprintf( ' <a href="%s" class="thickbox" title="Contact Form 7">%s</a>', $install_url, esc_html__( 'Install Now.', 'cf7_modules' ) );
|
||||
}
|
||||
$out .= '</p></div>';
|
||||
echo $out;
|
||||
}
|
||||
|
||||
function contact_form_7_hidden_fields_scripts() {
|
||||
wp_enqueue_script('thickbox');
|
||||
}
|
||||
|
||||
/**
|
||||
** A base module for [hidden] and [hidden*]
|
||||
**/
|
||||
|
||||
/* Shortcode handler */
|
||||
|
||||
add_filter('wpcf7_form_elements', 'wpcf7_form_elements_strip_paragraphs_and_brs');
|
||||
|
||||
/**
|
||||
* Strip paragraph tags being wrapped around the field
|
||||
* @param $form
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
function wpcf7_form_elements_strip_paragraphs_and_brs($form) {
|
||||
return preg_replace_callback( '/<p>(<input\stype="hidden"(?:.*?))<\/p>/ism', 'wpcf7_form_elements_strip_paragraphs_and_brs_callback', $form );
|
||||
}
|
||||
|
||||
function wpcf7_form_elements_strip_paragraphs_and_brs_callback($matches = array()) {
|
||||
return "\n" . '<!-- CF7 Modules -->' . "\n" . '<div style=\'display:none;\'>' . str_replace( '<br>', '', str_replace( '<br />', '', stripslashes_deep( $matches[1] ) ) ) . '</div>' . "\n" . '<!-- End CF7 Modules -->' . "\n";
|
||||
}
|
||||
|
||||
/**
|
||||
** A base module for [hidden], [hidden*]
|
||||
**/
|
||||
|
||||
/* Shortcode handler */
|
||||
|
||||
function wpcf7_hidden_shortcode_handler( $tag ) {
|
||||
|
||||
if ( class_exists( 'WPCF7_FormTag' ) ) {
|
||||
$tag = new WPCF7_FormTag( $tag );
|
||||
} else {
|
||||
$tag = new WPCF7_Shortcode( $tag );
|
||||
}
|
||||
|
||||
if ( empty( $tag->name ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$validation_error = wpcf7_get_validation_error( $tag->name );
|
||||
|
||||
$class = wpcf7_form_controls_class( $tag->type, 'wpcf7-hidden' );
|
||||
|
||||
if ( $validation_error ) {
|
||||
$class .= ' wpcf7-not-valid';
|
||||
}
|
||||
|
||||
$class .= ' wpcf7-hidden';
|
||||
|
||||
if ( 'hidden*' === $tag->type ) {
|
||||
$class .= ' wpcf7-validates-as-required';
|
||||
}
|
||||
|
||||
$value = (string) reset( $tag->values );
|
||||
|
||||
$placeholder = '';
|
||||
if ( $tag->has_option( 'placeholder' ) || $tag->has_option( 'watermark' ) ) {
|
||||
$placeholder = $value;
|
||||
$value = '';
|
||||
}
|
||||
|
||||
$default_value = $tag->get_default_option( $value );
|
||||
|
||||
$value = contact_form_7_hidden_fields_fill_post_data( $value, $tag );
|
||||
|
||||
// Post data hasn't filled yet. No arrays.
|
||||
if ( $default_value === $value ) {
|
||||
$value = contact_form_7_hidden_fields_fill_user_data( $value );
|
||||
}
|
||||
|
||||
// Arrays get imploded.
|
||||
$value = is_array( $value ) ? implode( apply_filters( 'wpcf7_hidden_field_implode_glue', ', ' ), $value ) : $value;
|
||||
|
||||
// Make sure we're using a string. Objects get JSON-encoded.
|
||||
if ( ! is_string( $value ) ) {
|
||||
$value = json_encode( $value );
|
||||
}
|
||||
|
||||
$value = apply_filters( 'wpcf7_hidden_field_value', apply_filters( 'wpcf7_hidden_field_value_' . $tag->get_id_option(), $value ) );
|
||||
|
||||
$value = wpcf7_get_hangover( $tag->name, $value );
|
||||
|
||||
$atts = array(
|
||||
'type' => 'hidden',
|
||||
'class' => $tag->get_class_option( $class ),
|
||||
'id' => $tag->get_id_option(),
|
||||
'name' => $tag->name,
|
||||
'tabindex' => $tag->get_option( 'tabindex', 'int', true ),
|
||||
'placeholder' => $placeholder,
|
||||
'value' => $value,
|
||||
);
|
||||
|
||||
$atts = wpcf7_format_atts( $atts );
|
||||
|
||||
$html = sprintf( '<input %1$s />%2$s', $atts, $validation_error );
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill data based on user information.
|
||||
*
|
||||
* @param string $value Existing value, if any
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
function contact_form_7_hidden_fields_fill_user_data( $value ) {
|
||||
|
||||
$return = $value;
|
||||
|
||||
// Process user stuff
|
||||
if ( preg_match( '/user/ism', strtolower( trim( $value ) ) ) && is_user_logged_in() ) {
|
||||
|
||||
$current_user = wp_get_current_user();
|
||||
|
||||
switch ( $value ) {
|
||||
case 'user_name':
|
||||
$return = $current_user->user_login;
|
||||
break;
|
||||
case 'user_id':
|
||||
$return = $current_user->ID;
|
||||
break;
|
||||
case 'caps':
|
||||
$return = $current_user->caps;
|
||||
break;
|
||||
case 'allcaps':
|
||||
$return = $current_user->allcaps;
|
||||
break;
|
||||
case 'user_roles':
|
||||
$return = $current_user->roles;
|
||||
break;
|
||||
default:
|
||||
// Gets the values for `user_email`, others that have `user_` prefix.
|
||||
if ( $current_user->has_prop( $value ) ) {
|
||||
$return = $current_user->get( $value );
|
||||
} else {
|
||||
// Define some other item in the WP_User object using the `user_[what you want to get]` format
|
||||
// This works for the `user_display_name` setting
|
||||
$user_key = preg_replace( '/user[_-](.+)/ism', '$1', $value );
|
||||
if ( $current_user->has_prop( $user_key ) ) {
|
||||
$return = $current_user->get( $user_key );
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill data based on user information.
|
||||
*
|
||||
* @param string $value Existing value, if any
|
||||
* @param WPCF7_Shortcode $tag Tag
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
function contact_form_7_hidden_fields_fill_post_data( $value = '', $tag ) {
|
||||
global $post;
|
||||
|
||||
$return = $value;
|
||||
|
||||
if ( is_object( $post ) ) {
|
||||
|
||||
switch ( strtolower( trim( $value ) ) ) {
|
||||
case 'post_title':
|
||||
case 'post-title':
|
||||
$return = $post->post_title;
|
||||
break;
|
||||
case 'page_url':
|
||||
case 'post_url':
|
||||
$return = get_permalink( $post->ID );
|
||||
if ( empty( $return ) && isset( $post->guid ) ) {
|
||||
$return = $post->guid;
|
||||
}
|
||||
$return = esc_url( $return );
|
||||
break;
|
||||
case 'post_category':
|
||||
$categories = get_the_category( $post->ID );
|
||||
$catnames = array();
|
||||
// Get the category names
|
||||
foreach ( $categories as $cat ) {
|
||||
$catnames[] = $cat->cat_name;
|
||||
}
|
||||
|
||||
$return = implode( ', ', $catnames );
|
||||
break;
|
||||
case 'post_author_id':
|
||||
$return = $post->post_author;
|
||||
break;
|
||||
case 'post_author':
|
||||
$user = get_userdata( $post->post_author );
|
||||
$return = $user->display_name;
|
||||
break;
|
||||
default:
|
||||
// You want post_modified? just use [hidden hidden-123 "post_modified"]
|
||||
if ( isset( $post->{ $value } ) ) {
|
||||
$return = $post->{ $value };
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if ( preg_match( '/^custom_field\-(.*?)$/ism', $value ) ) {
|
||||
$custom_field = preg_replace( '/custom_field\-(.*?)/ism', '$1', $value );
|
||||
$return = get_post_meta( $post->ID, $custom_field, false ) ? get_post_meta( $post->ID, $custom_field, false ) : '';
|
||||
}
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
|
||||
/* Tag generator */
|
||||
|
||||
if ( is_admin() ) {
|
||||
add_action( 'admin_init', 'wpcf7_add_tag_generator_hidden', 30 );
|
||||
}
|
||||
|
||||
function wpcf7_add_tag_generator_hidden() {
|
||||
|
||||
if ( class_exists( 'WPCF7_TagGenerator' ) ) {
|
||||
|
||||
$tag_generator = WPCF7_TagGenerator::get_instance();
|
||||
$tag_generator->add( 'hidden', _x( 'hidden', 'the name of the field button in CF7', 'cf7_modules' ), 'wpcf7_tg_pane_hidden' );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function wpcf7_tg_pane_hidden( $contact_form, $args = '' ) {
|
||||
|
||||
$args = wp_parse_args( $args, array() );
|
||||
|
||||
$description = __( "Generate a form tag for a hidden field. For more details, see %s.", 'contact-form-7' );
|
||||
$desc_link = wpcf7_link( 'https://wordpress.org/plugins/contact-form-7-modules/', __( 'the plugin page on WordPress.org', 'contact-form-7' ), array( 'target' => '_blank' ) );
|
||||
?>
|
||||
<div class="control-box">
|
||||
<fieldset>
|
||||
<legend><?php printf( esc_html( $description ), $desc_link ); ?></legend>
|
||||
|
||||
<table class="form-table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row"><label
|
||||
for="<?php echo esc_attr( $args['content'] . '-name' ); ?>"><?php echo esc_html( __( 'Name', 'contact-form-7' ) ); ?></label>
|
||||
</th>
|
||||
<td><input type="text" name="name" class="tg-name oneline"
|
||||
id="<?php echo esc_attr( $args['content'] . '-name' ); ?>"/></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th scope="row"><label
|
||||
for="<?php echo esc_attr( $args['content'] . '-id' ); ?>"><?php echo esc_html( __( 'ID attribute', 'contact-form-7' ) ); ?>
|
||||
(<?php echo esc_html( __( 'optional', 'cf7_modules' ) ); ?>)</label></th>
|
||||
<td><input type="text" name="id" class="idvalue oneline option"
|
||||
id="<?php echo esc_attr( $args['content'] . '-id' ); ?>"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<?php _e( 'Value', 'cf7_modules' ); ?>
|
||||
</th>
|
||||
<td>
|
||||
<input type="text" name="values" class="oneline"/>
|
||||
<div>
|
||||
<input type="checkbox" name="watermark"
|
||||
class="option"/> <?php echo esc_html( __( 'Use this text as watermark?', 'cf7_modules' ) ); ?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<?php _e( 'Dynamic Values', 'cf7_modules' ); ?>
|
||||
</th>
|
||||
<td>
|
||||
<span class="howto"
|
||||
style="font-size:1em;"><?php _e( 'To use dynamic data from the post or page the form is embedded on, you can use the following values:', 'cf7_modules' ); ?></span>
|
||||
|
||||
<ul>
|
||||
<li><?php _e( '<code>post_title</code>: The title of the post/page', 'cf7_modules' ); ?></li>
|
||||
<li><?php _e( '<code>post_url</code>: The URL of the post/page', 'cf7_modules' ); ?></li>
|
||||
<li><?php _e( '<code>post_category</code>: The categories the post is in, comma-separated', 'cf7_modules' ); ?></li>
|
||||
<li><?php _e( '<code>post_date</code>: The date the post/page was created', 'cf7_modules' ); ?></li>
|
||||
<li><?php _e( '<code>post_author</code>: The name of the author of the post/page', 'cf7_modules' ); ?></li>
|
||||
</ul>
|
||||
<span class="howto"><?php _e( 'The following values will be replaced if an user is logged in:', 'cf7_modules' ); ?></span>
|
||||
<ul>
|
||||
<li><?php _e( '<code>user_name</code>: User Login', 'cf7_modules' ); ?></li>
|
||||
<li><?php _e( '<code>user_id</code>: User ID', 'cf7_modules' ); ?></li>
|
||||
<li><?php _e( '<code>user_email</code>: User Email Address', 'cf7_modules' ); ?></li>
|
||||
<li><?php _e( '<code>user_display_name</code>: Display Name (Generally the first and last name of the user)', 'cf7_modules' ); ?></li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</fieldset>
|
||||
</div>
|
||||
|
||||
<div class="insert-box">
|
||||
<input type="text" name="hidden" class="tag code" readonly="readonly" onfocus="this.select()"/>
|
||||
|
||||
<div class="submitbox">
|
||||
<input type="button" class="button button-primary insert-tag"
|
||||
value="<?php echo esc_attr( __( 'Insert Tag', 'contact-form-7' ) ); ?>"/>
|
||||
</div>
|
||||
|
||||
<br class="clear"/>
|
||||
|
||||
<p class="description mail-tag"><label
|
||||
for="<?php echo esc_attr( $args['content'] . '-mailtag' ); ?>"><?php echo sprintf( esc_html( __( "To use the value input through this field in a mail field, you need to insert the corresponding mail-tag (%s) into the field on the Mail tab.", 'contact-form-7' ) ), '<strong><span class="mail-tag"></span></strong>' ); ?>
|
||||
<input type="text" class="mail-tag code hidden" readonly="readonly"
|
||||
id="<?php echo esc_attr( $args['content'] . '-mailtag' ); ?>"/></label></p>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
Binary file not shown.
@@ -1,133 +0,0 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Contact Form 7 Modules: Send All Fields\n"
|
||||
"POT-Creation-Date: 2017-02-01 18:49-0700\n"
|
||||
"PO-Revision-Date: 2017-02-01 18:49-0700\n"
|
||||
"Last-Translator: Katz Web Services, Inc. <support@katz.co>\n"
|
||||
"Language-Team: Zack Katz <support@katz.co>\n"
|
||||
"Language: en_US\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 1.8.5\n"
|
||||
"X-Poedit-Basepath: ..\n"
|
||||
"X-Poedit-SourceCharset: UTF-8\n"
|
||||
"X-Poedit-KeywordsList: __;_e;_n:1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;esc_attr__;"
|
||||
"esc_attr_e;esc_attr_x:1,2c;esc_html__;esc_html_e;esc_html_x:1,2c;"
|
||||
"_n_noop:1,2;_nx_noop:3c,1,2;__ngettext_noop:1,2\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Poedit-SearchPath-0: .\n"
|
||||
|
||||
#: hidden.php:38
|
||||
msgid ""
|
||||
"The Contact Form 7 is installed, but you must activate Contact Form 7 below "
|
||||
"for the Hidden Fields Module to work."
|
||||
msgstr ""
|
||||
|
||||
#: hidden.php:40
|
||||
msgid ""
|
||||
"The Contact Form 7 plugin must be installed for the Hidden Fields Module to "
|
||||
"work."
|
||||
msgstr ""
|
||||
|
||||
#: hidden.php:42
|
||||
msgid "Install Now."
|
||||
msgstr ""
|
||||
|
||||
#: hidden.php:277
|
||||
msgctxt "the name of the field button in CF7"
|
||||
msgid "hidden"
|
||||
msgstr ""
|
||||
|
||||
#: hidden.php:286
|
||||
#, php-format
|
||||
msgid "Generate a form tag for a hidden field. For more details, see %s."
|
||||
msgstr ""
|
||||
|
||||
#: hidden.php:287
|
||||
msgid "the plugin page on WordPress.org"
|
||||
msgstr ""
|
||||
|
||||
#: hidden.php:297
|
||||
msgid "Name"
|
||||
msgstr ""
|
||||
|
||||
#: hidden.php:305
|
||||
msgid "ID attribute"
|
||||
msgstr ""
|
||||
|
||||
#: hidden.php:306
|
||||
msgid "optional"
|
||||
msgstr ""
|
||||
|
||||
#: hidden.php:312
|
||||
msgid "Value"
|
||||
msgstr ""
|
||||
|
||||
#: hidden.php:318
|
||||
msgid "Use this text as watermark?"
|
||||
msgstr ""
|
||||
|
||||
#: hidden.php:324
|
||||
msgid "Dynamic Values"
|
||||
msgstr ""
|
||||
|
||||
#: hidden.php:328
|
||||
msgid ""
|
||||
"To use dynamic data from the post or page the form is embedded on, you can "
|
||||
"use the following values:"
|
||||
msgstr ""
|
||||
|
||||
#: hidden.php:331
|
||||
msgid "<code>post_title</code>: The title of the post/page"
|
||||
msgstr ""
|
||||
|
||||
#: hidden.php:332
|
||||
msgid "<code>post_url</code>: The URL of the post/page"
|
||||
msgstr ""
|
||||
|
||||
#: hidden.php:333
|
||||
msgid ""
|
||||
"<code>post_category</code>: The categories the post is in, comma-separated"
|
||||
msgstr ""
|
||||
|
||||
#: hidden.php:334
|
||||
msgid "<code>post_date</code>: The date the post/page was created"
|
||||
msgstr ""
|
||||
|
||||
#: hidden.php:335
|
||||
msgid "<code>post_author</code>: The name of the author of the post/page"
|
||||
msgstr ""
|
||||
|
||||
#: hidden.php:337
|
||||
msgid "The following values will be replaced if an user is logged in:"
|
||||
msgstr ""
|
||||
|
||||
#: hidden.php:339
|
||||
msgid "<code>user_name</code>: User Login"
|
||||
msgstr ""
|
||||
|
||||
#: hidden.php:340
|
||||
msgid "<code>user_id</code>: User ID"
|
||||
msgstr ""
|
||||
|
||||
#: hidden.php:341
|
||||
msgid "<code>user_email</code>: User Email Address"
|
||||
msgstr ""
|
||||
|
||||
#: hidden.php:342
|
||||
msgid ""
|
||||
"<code>user_display_name</code>: Display Name (Generally the first and last "
|
||||
"name of the user)"
|
||||
msgstr ""
|
||||
|
||||
#: hidden.php:356
|
||||
msgid "Insert Tag"
|
||||
msgstr ""
|
||||
|
||||
#: hidden.php:362
|
||||
#, php-format
|
||||
msgid ""
|
||||
"To use the value input through this field in a mail field, you need to "
|
||||
"insert the corresponding mail-tag (%s) into the field on the Mail tab."
|
||||
msgstr ""
|
||||
@@ -1,256 +0,0 @@
|
||||
=== Contact Form 7 Modules ===
|
||||
Tags: Contact Form 7, cf7, Contact Forms 7, hidden fields, all fields
|
||||
Requires at least: 2.8
|
||||
Tested up to: 4.7.2
|
||||
Stable tag: trunk
|
||||
Contributors: katzwebdesign, katzwebservices
|
||||
Donate link: https://katz.co/contact-form-7-hidden-fields/
|
||||
License: GPLv2 or later
|
||||
|
||||
Contact Form 7 - Add useful modules such as hidden fields and "send all fields" to the Contact Form 7 plugin
|
||||
|
||||
== Description ==
|
||||
|
||||
### Add Hidden Fields to Contact Form 7
|
||||
|
||||
The Contact Form 7 plugin has over <em>1 million</em> active installations, yet the great plugin still lacks a simple feature: <strong>hidden fields</strong>. This plugin adds hidden fields to Contact Form 7 once and for all.
|
||||
|
||||
#### Inserting dynamic values
|
||||
|
||||
You can also choose to have the value of the hidden field dynamically populated in your form when you are contacted. To do so, choose the "Default value" to be:
|
||||
|
||||
* `post_title` - Inserts the title of the post/page
|
||||
* `post_category` - The categories of the post or page
|
||||
* `post_url` - The URL of the post or page
|
||||
* `post_author` - The author of the post or page
|
||||
* `custom_field-[Name]` - The value of a post or page's custom field. If you had a custom field "Foo", you would use the following as the hidden field value: `custom_field-Foo`
|
||||
|
||||
The following values will be replaced if an user is logged in:
|
||||
|
||||
* `user_name`: User Login
|
||||
* `user_id`: User ID
|
||||
* `user_email`: User Email Address
|
||||
* `user_display_name`: Display Name (Generally the first and last name of the user)
|
||||
* `user_url`: User Website
|
||||
|
||||
And you can also use it for user custom meta data using the format of `user-{field}`:
|
||||
|
||||
* `user-aim`: AIM
|
||||
* `user-jabber`: Jabber / Google Talk
|
||||
* `user-description`: User Bio
|
||||
|
||||
<strong>You can also use a filter:</strong> hook into the `wpcf7_hidden_field_value` filter to modify the value of the hidden field using <a href="http://codex.wordpress.org/Function_Reference/add_filter" rel="nofollow"><code>add_filter()</code></a>. If you know the ID of the input, you can also use the `wpcf7_hidden_field_value_[#ID]` filter.
|
||||
|
||||
Now, when someone contacts you using your Contact Form 7 contact form, you can have lots more information about their visit - and you'll see it when you receive the email that tells you you've been contacted.
|
||||
|
||||
### Easily Send All Submitted Fields At Once
|
||||
|
||||
####Save time setting up your form emails...and never miss a field!
|
||||
|
||||
One of the limitations of Contact Form 7 is that you need to manually add each field to generated emails. This means that if you update the form with a new field and forget to add it to your email message, you won't receive it in your email. <strong>No longer.</strong>.
|
||||
|
||||
Using the <strong>Send All Fields</strong> module, you simply need to add `[all-fields]` to your message, and you will receive every field submitted. If you use HTML formatting, the formatting even looks nice.
|
||||
|
||||
<h4>Visit the official <a href="https://katz.co/contact-form-7-hidden-fields/">Contact Form 7 Modules plugin page</a> for more support & additional information</h4>
|
||||
|
||||
== Screenshots ==
|
||||
|
||||
1. The Hidden fields tag generator
|
||||
2. The `[all-fields]` Mail tag
|
||||
|
||||
== Installation ==
|
||||
|
||||
1. Upload plugin files to your plugins folder, or install using WordPress' built-in Add New Plugin installer
|
||||
1. Activate the plugin
|
||||
1. Edit a form in Contact Form 7
|
||||
1. Choose "Hidden field" from the Generate Tag dropdown
|
||||
1. Follow the instructions on the page
|
||||
|
||||
== Frequently Asked Questions ==
|
||||
|
||||
= How do I turn off formatting the key in the `[all-fields]` output? =
|
||||
Add the following to your theme's `functions.php` file:
|
||||
|
||||
`
|
||||
add_filter('wpcf7_send_all_fields_format_key', '__return_false');
|
||||
`
|
||||
|
||||
= How do I set non-standard user data as hidden field values? =
|
||||
|
||||
Starting with Version 1.4, you can access user data, including meta data.
|
||||
|
||||
You need to set the default value as: `user-{meta_key}` where `{meta_key}` is the key of the meta field you want the value of.
|
||||
|
||||
To get the values of WordPress default profile fields, for example, you would use:
|
||||
|
||||
* `user-aim` - AOL
|
||||
* `user-jabber` - Jabber / Google Talk
|
||||
* `user-description` - Biographical description
|
||||
|
||||
= What is the plugin license? =
|
||||
|
||||
* This plugin is released under a GPL license.
|
||||
|
||||
= How do I send empty values with the `[all-fields]` shortcode? =
|
||||
|
||||
Add this to your `functions.php` file: `add_filter('wpcf7_send_all_fields_send_empty_fields', '__return_true');`
|
||||
|
||||
= How do I modify the output of the `[all-fields]` shortcode? =
|
||||
|
||||
* `wpcf7_send_all_fields_format_before` - Before the loop of fields (`<dl>` for HTML output)
|
||||
* `$value` _string_ Previous output
|
||||
* `$format` _string_ Either "html" or "text"
|
||||
* `wpcf7_send_all_fields_format_item` - Change each item output. Passes four arguments:
|
||||
* `$value` _string_ Previous output
|
||||
* `$k` _string_ Field label
|
||||
* `$v` _string_ Value of the field
|
||||
* `$format` _string_ Either "html" or "text"
|
||||
* `wpcf7_send_all_fields_format_after` - After the loop of fields (`</dl>` for HTML output). Passes two arguments:
|
||||
* `$value` _string_ Previous output
|
||||
* `$format` _string_ Either "html" or "text"
|
||||
|
||||
== Changelog ==
|
||||
|
||||
= 2.0.1 & 2.0.2 on February 1, 2017 =
|
||||
|
||||
* Confirmed compatibility with WordPress 4.7.2
|
||||
* Updated to work with Contact Form 7 4.6
|
||||
* Fixed: `[hidden]` shortcodes not being replaced in emails
|
||||
* Fixed: PHP warning related to deprecated function
|
||||
* Fixed: Removed use of deprecated `get_currentuserinfo()` function
|
||||
* Updated translations
|
||||
|
||||
= 2.0 on June 28, 2015 =
|
||||
* **Requires Contact Form 7 4.2 or higher**
|
||||
* Updated to work with latest Contact Form 7
|
||||
* Removed Contact Form 7 Newsletter plugin promotion
|
||||
|
||||
= 1.4.2 on March 25, 2014 =
|
||||
* Added: `[all-fields]` shortcode now skips sending data for empty fields
|
||||
* Added `wpcf7_send_all_fields_send_empty_fields` filter to override the setting. See the FAQ.
|
||||
* Added: `[all-fields]` shortcode output filters (see the FAQ item "How do I modify the output...")
|
||||
* `wpcf7_send_all_fields_format_before`
|
||||
* `wpcf7_send_all_fields_format_item`
|
||||
* `wpcf7_send_all_fields_format_after`
|
||||
|
||||
= 1.4 & 1.4.1 on March 15, 2014 =
|
||||
* Added: Internationalization support. [Help translate the plugin!](https://www.transifex.com/projects/p/contact-form-7-modules/)
|
||||
|
||||
__The below updates apply only to the Hidden Fields module.__
|
||||
|
||||
* Added: Support for retrieving other user data by using the field name `user_{data you want}`. See the FAQ "How do I set non-standard user data as hidden field values?"
|
||||
* Added: `wpcf7_hidden_field_implode_glue` filter. If you want to modify how arrays of data get combined into a string (default is CSV), use this filter.
|
||||
* Fixed: `$post` global no longer needs to be defined for user data to be successfully passed.
|
||||
* Fixed: Now supports multiple post `custom_field` data values, instead of only fetching one
|
||||
* Modified: Added callback function to format the hidden field instead of relying on depricated PHP
|
||||
* Modified: Improved include path for `functions.php` file
|
||||
* Modified: Added text to support additional localization
|
||||
|
||||
= 1.3.3 =
|
||||
* Hidden Fields: Fixed issue that broke the plugin with WordPress 3.8.
|
||||
|
||||
= 1.3.2 =
|
||||
* Hidden Fields: Fixed PHP notice caused by improper adding of script in administration
|
||||
* Hidden Fields: Fixed double inputs that were the exact same (<a href="http://wordpress.org/support/topic/render-the-fields-twice">as reported here</a>)
|
||||
|
||||
= 1.3.1 =
|
||||
* Fixed: issue in Hidden Fields where the `[hidden-###]` shortcode no longer worked and only `[post_title]` format worked.
|
||||
* Added: Hidden fields now support both formats: `[hidden-123]` and `[post_title]` as long as they're in the form itself.
|
||||
* Fixed: issue in Send All Fields where the <a href="http://wordpress.org/support/topic/post_title-hidden-field-no-longer-working#post-3708463">HTML was showing as text</a>.
|
||||
* Added `wpcf7_send_all_fields_format_key` filter to Send All Fields plugin to turn on or off formatting of the key (replacing `example-key` with `Example Key` in output). See "How do I turn off formatting the key in the `[all-fields]` output?" in the FAQ.
|
||||
|
||||
= 1.3 =
|
||||
* Fixed: Hidden field now supports new Contact Form 7 format; post fields will work again.
|
||||
* Fixed: Send All Fields no longer causes spinning form submission in WordPress 3.5
|
||||
* Added: access any of the <a href="http://www.rlmseo.com/blog/wordpress-post-variable-quick-reference/" rel='nofollow'>data in `$post` object</a> by using the variable name. Example: You want `post_modified`? Use `[hidden hidden-123 "post_modified"]`
|
||||
* Added: If an user is logged in, you can now use `user_name`, `user_id`, `user_email`, `user_display_name` replacement values
|
||||
* Added/Improved: `post_author` will now return the author's Display Name. Use `post_author_id` for the post author's ID.
|
||||
* Added: Inline instructions on the Hidden field module
|
||||
* Improved: In Send All Fields, the name of the field now has dashes replaced with spaces. This will show "your name", rather than "your-name". Thanks, <a href="http://wordpress.org/support/topic/sending-all-fields-with-content-code-provided">@hitolonen</a>
|
||||
|
||||
= 1.2.2 =
|
||||
* Removed `_wpnonce` field from `[all-fields]` output
|
||||
* Fixed a conflict when using "Send All Fields" module alongside "Hidden Fields" module (<a href="http://wordpress.org/support/topic/plugin-contact-form-7-modules-all-fields-doesn´t-work-wit-wordpress-33">as reported here</a>)
|
||||
|
||||
= 1.2.1 =
|
||||
* Added support for checkboxes with Send All Fields (`[all-fields]`)
|
||||
|
||||
= 1.2 =
|
||||
* Hidden fields are now displayed inside a hidden `<div>` instead of Contact Form 7's default `<p>`. This makes hidden fields more hidden :-)
|
||||
* Added brand-new module: Send All Fields. Allows you to add a `[all-fields]` tag to your email message that includes every submitted field in one tag.
|
||||
|
||||
= 1.1.1 =
|
||||
* Fixed `Parameter 1 to wpcf7_add_tag_generator_hidden() expected to be a reference, value given` error, <a href="http://www.seodenver.com/contact-form-7-hidden-fields/#comment-116384456"> as reported by BDN Online</a>
|
||||
|
||||
= 1.1 =
|
||||
* Added support for using post titles as hidden fields
|
||||
* Added support for using custom field values as hidden fields
|
||||
* Added `wpcf7_hidden_field_value` filter to hook into using <a href="http://codex.wordpress.org/Function_Reference/add_filter" rel="nofollow"><code>add_filter()</code></a>
|
||||
|
||||
= 1.0 =
|
||||
* Initial plugin release.
|
||||
|
||||
== Upgrade Notice ==
|
||||
|
||||
= 1.4.2 on March 25, 2014 =
|
||||
* Added: `[all-fields]` shortcode now skips sending data for empty fields
|
||||
* Added `wpcf7_send_all_fields_send_empty_fields` filter to override the setting. See the FAQ.
|
||||
* Added: `[all-fields]` shortcode output filters (see the FAQ item "How do I modify the output...")
|
||||
* `wpcf7_send_all_fields_format_before`
|
||||
* `wpcf7_send_all_fields_format_item`
|
||||
* `wpcf7_send_all_fields_format_after`
|
||||
|
||||
= 1.4 & 1.4.1 on March 15, 2014 =
|
||||
* Added: Internationalization support. [Help translate the plugin!](https://www.transifex.com/projects/p/contact-form-7-modules/)
|
||||
|
||||
__The below updates apply only to the Hidden Fields module.__
|
||||
|
||||
* Added: Support for retrieving other user data by using the field name `user_{data you want}`. See the FAQ "How do I set non-standard user data as hidden field values?"
|
||||
* Added: `wpcf7_hidden_field_implode_glue` filter. If you want to modify how arrays of data get combined into a string (default is CSV), use this filter.
|
||||
* Fixed: `$post` global no longer needs to be defined for user data to be successfully passed.
|
||||
* Fixed: Now supports multiple post `custom_field` data values, instead of only fetching one
|
||||
* Modified: Added callback function to format the hidden field instead of relying on depricated PHP
|
||||
* Modified: Improved include path for `functions.php` file
|
||||
* Modified: Added text to support additional localization
|
||||
|
||||
= 1.3.3 =
|
||||
* Hidden Fields: Fixed issue that broke the plugin with the WordPress 3.8
|
||||
|
||||
= 1.3.2 =
|
||||
* Hidden Fields: Fixed PHP notice caused by improper adding of script in administration
|
||||
* Hidden Fields: Fixed double inputs that were the exact same (<a href="http://wordpress.org/support/topic/render-the-fields-twice">as reported here</a>)
|
||||
|
||||
= 1.3.1 =
|
||||
* Fixed: issue in Hidden Fields where the `[hidden-###]` shortcode no longer worked and only `[post_title]` format worked.
|
||||
* Fixed: issue in Send All Fields where the <a href="http://wordpress.org/support/topic/post_title-hidden-field-no-longer-working#post-3708463">HTML was showing as text</a>.
|
||||
|
||||
= 1.3 =
|
||||
* Fixed: Hidden field now supports new Contact Form 7 format; post fields will work again.
|
||||
* Fixed: Send All Fields no longer causes spinning form submission in WordPress 3.5
|
||||
* Added: access any of the <a href="http://www.rlmseo.com/blog/wordpress-post-variable-quick-reference/" rel='nofollow'>data in `$post` object</a> by using the variable name. Example: You want `post_modified`? Use `[hidden hidden-123 "post_modified"]`
|
||||
* Added: If an user is logged in, you can now use `user_name`, `user_id`, `user_email`, `user_display_name` replacement values
|
||||
* Added/Improved: `post_author` will now return the author's Display Name. Use `post_author_id` for the post author's ID.
|
||||
* Added: Inline instructions on the Hidden field module
|
||||
* Improved: In Send All Fields, the name of the field now has dashes replaced with spaces. This will show "your name", rather than "your-name". Thanks, <a href="http://wordpress.org/support/topic/sending-all-fields-with-content-code-provided">@hitolonen</a>
|
||||
|
||||
= 1.2.2 =
|
||||
* Removed `_wpnonce` field from `[all-fields]` output
|
||||
* Fixed a conflict when using "Send All Fields" module alongside "Hidden Fields" module (<a href="http://wordpress.org/support/topic/plugin-contact-form-7-modules-all-fields-doesn´t-work-wit-wordpress-33">as reported here</a>)
|
||||
|
||||
= 1.2.1 =
|
||||
* Added support for checkboxes with Send All Fields (`[all-fields]`)
|
||||
|
||||
= 1.2 =
|
||||
* Hidden fields are now displayed inside a hidden `<div>` instead of Contact Form 7's default `<p>`. This makes hidden fields more hidden :-)
|
||||
* Added brand-new module: Send All Fields. Allows you to add a `[all-fields]` tag to your email message that includes every submitted field in one tag.
|
||||
|
||||
= 1.1.1 =
|
||||
* Fixed `Parameter 1 to wpcf7_add_tag_generator_hidden() expected to be a reference, value given` error, <a href="http://www.seodenver.com/contact-form-7-hidden-fields/#comment-116384456"> as reported by BDN Online</a>
|
||||
|
||||
= 1.1 =
|
||||
* Added support for using post titles as hidden fields
|
||||
* Added support for using custom field values as hidden fields
|
||||
* Added `wpcf7_hidden_field_value` filter to hook into using <a href="http://codex.wordpress.org/Function_Reference/add_filter" rel="nofollow"><code>add_filter()</code></a>
|
||||
|
||||
= 1.0 =
|
||||
* Woot!
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 186 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 94 KiB |
@@ -1,111 +0,0 @@
|
||||
<?php
|
||||
/*
|
||||
Plugin Name: Contact Form 7 Modules: Send All Fields
|
||||
Plugin URI: https://katz.co/contact-form-7-hidden-fields/
|
||||
Description: Send all submitted fields in the message body using one simple tag: <code>[all-fields]</code>
|
||||
Author: Katz Web Services, Inc.
|
||||
Author URI: http://www.katz.co
|
||||
Version: 2.0.2
|
||||
Text Domain: cf7_modules
|
||||
Domain Path: languages
|
||||
License: GPLv2 or later
|
||||
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*/
|
||||
|
||||
add_filter('wpcf7_mail_components', 'all_fields_wpcf7_before_send_mail');
|
||||
|
||||
function all_fields_wpcf7_before_send_mail($array) {
|
||||
$debug = false;
|
||||
|
||||
if ( $debug ) {
|
||||
print_r( $array );
|
||||
}
|
||||
if ( $debug ) {
|
||||
print_r( $_POST );
|
||||
}
|
||||
|
||||
$post = $_POST;
|
||||
|
||||
$html = false;
|
||||
if ( wpautop( $array['body'] ) == $array['body'] ) {
|
||||
$html = true;
|
||||
}
|
||||
|
||||
foreach ( $post as $k => $v ) {
|
||||
if ( substr( $k, 0, 6 ) == '_wpcf7' || strpos( $k, 'all-fields' ) || $k === '_wpnonce' ) {
|
||||
unset( $post["{$k}"] );
|
||||
}
|
||||
}
|
||||
if ( $debug ) {
|
||||
print_r( $post );
|
||||
}
|
||||
|
||||
$postbody = '';
|
||||
|
||||
if ( $html ) {
|
||||
$postbody = apply_filters( 'wpcf7_send_all_fields_format_before', '<dl>', 'html' );
|
||||
} else {
|
||||
$postbody = apply_filters( 'wpcf7_send_all_fields_format_before', '', 'text' );
|
||||
}
|
||||
|
||||
foreach ( $post as $k => $v ) {
|
||||
|
||||
// Remove dupe content. The Hidden and Values are both sent.
|
||||
if ( preg_match( '/hidden\-/', $k ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If there's no value for the field, don't send it.
|
||||
if ( empty( $v ) && false === apply_filters( 'wpcf7_send_all_fields_send_empty_fields', false ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( is_array( $v ) ) {
|
||||
$v = implode( ', ', $v );
|
||||
}
|
||||
|
||||
// Make the fields easier to read. Thanks, @hitolonen
|
||||
$k = apply_filters( 'wpcf7_send_all_fields_format_key', true ) ? ucwords( str_replace( "-", " ", str_replace( "_", " ", $k ) ) ) : $k;
|
||||
|
||||
// Sanitize!
|
||||
$k = esc_attr( $k );
|
||||
$v = esc_attr( $v );
|
||||
|
||||
if ( $html ) {
|
||||
$postbody .= apply_filters( 'wpcf7_send_all_fields_format_item', "<dt style='font-size:1.2em;'><font size='3'><strong style='font-weight:bold;'>{$k}</strong>:</font></dt><dd style='padding:0 0 .5em 1.5em; margin:0;'>{$v}</dd>", $k, $v, 'html' );
|
||||
} else {
|
||||
$postbody .= apply_filters( 'wpcf7_send_all_fields_format_item', "{$k}: {$v}\n", $k, $v, 'text' );
|
||||
}
|
||||
}
|
||||
if ( $html ) {
|
||||
$postbody .= apply_filters( 'wpcf7_send_all_fields_format_after', '</dl>', 'html' );
|
||||
} else {
|
||||
$postbody .= apply_filters( 'wpcf7_send_all_fields_format_after', '', 'text' );
|
||||
}
|
||||
|
||||
if ( $debug ) {
|
||||
print_r( $postbody );
|
||||
}
|
||||
|
||||
$array['body'] = str_replace( '<p>[all-fields]</p>', $postbody, str_replace( '[all-fields]', $postbody, $array['body'] ) );
|
||||
|
||||
if ( $debug ) {
|
||||
die();
|
||||
} else {
|
||||
return $array;
|
||||
}
|
||||
}
|
||||
|
||||
add_filter('wpcf7_collect_mail_tags', 'wpcf7_collect_mail_tags_add_all_fields_tag');
|
||||
|
||||
/**
|
||||
* Add a all-fields option to the Mail tab's merge tags
|
||||
* @since 2.0
|
||||
* @param array $mailtags
|
||||
*/
|
||||
function wpcf7_collect_mail_tags_add_all_fields_tag( $mailtags = array() ) {
|
||||
|
||||
$mailtags[] = 'all-fields';
|
||||
|
||||
return $mailtags;
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
<?php
|
||||
/*
|
||||
Plugin Name: Contact Form 7 Shortcode Enabler
|
||||
Plugin URI: #
|
||||
Description: This plugin enables the usage of external shortcuts inside Contact Form 7 Forms.
|
||||
Version: 1.1
|
||||
Author: Tobias Zimpel (TZ Media)
|
||||
Author URI: http://www.tobias-zimpel.de
|
||||
License: GPLv2 or later.
|
||||
*/
|
||||
|
||||
function wpcf7_shortcode_enabler_activate() {
|
||||
if ( ! is_plugin_active( 'contact-form-7/wp-contact-form-7.php' ) and current_user_can( 'activate_plugins' ) ) {
|
||||
// Stop activation redirect and show error
|
||||
wp_die('Sorry, but this plugin requires the <a href="https://wordpress.org/plugins/contact-form-7/">Contact Form 7</a> Plugin to be installed and active. <br><a href="' . admin_url( 'plugins.php' ) . '">« Return to Plugins</a>');
|
||||
}
|
||||
}
|
||||
register_activation_hook( __FILE__, 'wpcf7_shortcode_enabler_activate' );
|
||||
|
||||
// Activate Shortcode Execution for Contact Form 7
|
||||
|
||||
add_filter( 'wpcf7_form_elements', 'do_shortcode' );
|
||||
|
||||
?>
|
||||
@@ -1,36 +0,0 @@
|
||||
=== Contact Form 7 Shortcode Enabler ===
|
||||
Contributors: TZ Media
|
||||
Tags: Contact Form 7, CF7, Shortcode, Shortcodes
|
||||
Requires at least: 4.0
|
||||
Tested up to: 4.6.1
|
||||
Stable tag: 1.1
|
||||
License: GPLv2 or later.
|
||||
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
|
||||
This plugin enables the usage of external shortcuts inside Contact Form 7 Forms.
|
||||
|
||||
== Description ==
|
||||
Many themes, as well as other plugins, provide shortcodes for layout options like multi-column-layouts, tabs, etc.
|
||||
|
||||
By default, Contact Form 7 forms can not include shortcodes provided by WordPress or third-party-plugins or -themes.
|
||||
|
||||
This plugin enables the usage of external shortcodes inside Contact Form 7 Forms.
|
||||
|
||||
== Installation ==
|
||||
1. Upload the entire cf7-enable-shortcode folder to the /wp-content/plugins/ directory.
|
||||
1. Activate the plugin through the 'Plugins' menu in WordPress.
|
||||
|
||||
The Plugin requires no additional configuration.
|
||||
|
||||
|
||||
== Frequently Asked Questions ==
|
||||
= I'm missing some feature in the plugin =
|
||||
|
||||
I'm pretty sure you are missing a feature in Contact Form 7 itself, not in this plugin. Otherwise, please drop me a message and I'll see what I can do.
|
||||
|
||||
== Changelog ==
|
||||
= 1.1 =
|
||||
* NEW: Added dependency to Contact Form 7 Plugin
|
||||
|
||||
= 1.0 =
|
||||
* NEW: Enables shortcodes inside Contact Form 7 Forms
|
||||
@@ -120,7 +120,7 @@ function wpcf7_editor_box_mail( $post, $args = '' ) {
|
||||
<?php
|
||||
if ( ! empty( $args['use'] ) ) :
|
||||
?>
|
||||
<label for="<?php echo $id; ?>-active"><input type="checkbox" id="<?php echo $id; ?>-active" name="<?php echo $id; ?>[active]" class="toggle-form-table" value="1"<?php echo ( $mail['active'] ) ? ' checked="checked"' : ''; ?> /> <?php echo esc_html( $args['use'] ); ?></label>
|
||||
<label for="<?php echo $id; ?>-active"><input type="checkbox" id="<?php echo $id; ?>-active" name="<?php echo $id; ?>[active]" data-config-field="" class="toggle-form-table" value="1"<?php echo ( $mail['active'] ) ? ' checked="checked"' : ''; ?> /> <?php echo esc_html( $args['use'] ); ?></label>
|
||||
<p class="description"><?php echo esc_html( __( "Mail (2) is an additional mail template often used as an autoresponder.", 'contact-form-7' ) ); ?></p>
|
||||
<?php
|
||||
endif;
|
||||
|
||||
@@ -62,6 +62,7 @@ function wpcf7_enqueue_block_editor_assets() {
|
||||
static function ( $contact_form ) {
|
||||
return array(
|
||||
'id' => $contact_form->id(),
|
||||
'hash' => $contact_form->hash(),
|
||||
'slug' => $contact_form->name(),
|
||||
'title' => $contact_form->title(),
|
||||
'locale' => $contact_form->locale(),
|
||||
|
||||
@@ -11,6 +11,9 @@
|
||||
"id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"hash": {
|
||||
"type": "string"
|
||||
},
|
||||
"title": {
|
||||
"type": "string"
|
||||
},
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,989 +0,0 @@
|
||||
<?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.6.1';
|
||||
|
||||
const error = 100;
|
||||
const error_maybe_empty = 101;
|
||||
const error_invalid_mailbox_syntax = 102;
|
||||
const error_email_not_in_site_domain = 103;
|
||||
const error_html_in_message = 104;
|
||||
const error_multiple_controls_in_label = 105;
|
||||
const error_file_not_found = 106;
|
||||
const error_unavailable_names = 107;
|
||||
const error_invalid_mail_header = 108;
|
||||
const error_deprecated_settings = 109;
|
||||
const error_file_not_in_content_dir = 110;
|
||||
const error_unavailable_html_elements = 111;
|
||||
const error_attachments_overweight = 112;
|
||||
const error_dots_in_names = 113;
|
||||
const error_colons_in_names = 114;
|
||||
const error_upload_filesize_overlimit = 115;
|
||||
|
||||
|
||||
/**
|
||||
* Returns a URL linking to the documentation page for the error type.
|
||||
*/
|
||||
public static function get_doc_link( $error_code = '' ) {
|
||||
$url = __( 'https://contactform7.com/configuration-errors/',
|
||||
'contact-form-7'
|
||||
);
|
||||
|
||||
if ( '' !== $error_code ) {
|
||||
$error_code = strtr( $error_code, '_', '-' );
|
||||
|
||||
$url = sprintf( '%s/%s', untrailingslashit( $url ), $error_code );
|
||||
}
|
||||
|
||||
return esc_url( $url );
|
||||
}
|
||||
|
||||
|
||||
private $contact_form;
|
||||
private $errors = array();
|
||||
|
||||
public function __construct( WPCF7_ContactForm $contact_form ) {
|
||||
$this->contact_form = $contact_form;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Counts detected errors.
|
||||
*/
|
||||
public function count_errors( $args = '' ) {
|
||||
$args = wp_parse_args( $args, 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 ( $args['section']
|
||||
and $key != $args['section']
|
||||
and preg_replace( '/\..*$/', '', $key, 1 ) != $args['section'] ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ( $errors as $error ) {
|
||||
if ( empty( $error ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( $args['code'] and $error['code'] != $args['code'] ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
return $count;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Collects messages for detected errors.
|
||||
*/
|
||||
public function collect_error_messages() {
|
||||
$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'] );
|
||||
}
|
||||
|
||||
$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 ) {
|
||||
switch ( $code ) {
|
||||
case self::error_maybe_empty:
|
||||
return __( "There is a possible empty field.", 'contact-form-7' );
|
||||
case self::error_invalid_mailbox_syntax:
|
||||
return __( "Invalid mailbox syntax is used.", 'contact-form-7' );
|
||||
case self::error_email_not_in_site_domain:
|
||||
return __( "Sender email address does not belong to the site domain.", 'contact-form-7' );
|
||||
case self::error_html_in_message:
|
||||
return __( "HTML tags are used in a message.", 'contact-form-7' );
|
||||
case self::error_multiple_controls_in_label:
|
||||
return __( "Multiple form controls are in a single label element.", 'contact-form-7' );
|
||||
case self::error_invalid_mail_header:
|
||||
return __( "There are invalid mail header fields.", 'contact-form-7' );
|
||||
case self::error_deprecated_settings:
|
||||
return __( "Deprecated settings are used.", 'contact-form-7' );
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds a validation error.
|
||||
*
|
||||
* @param string $section The section where the error detected.
|
||||
* @param int $code The unique code of the error.
|
||||
* This must be one of the class constants.
|
||||
* @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(),
|
||||
) );
|
||||
|
||||
if ( ! isset( $this->errors[$section] ) ) {
|
||||
$this->errors[$section] = array();
|
||||
}
|
||||
|
||||
$this->errors[$section][] = array( 'code' => $code, 'args' => $args );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Removes an 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->errors = array();
|
||||
|
||||
$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_errors' );
|
||||
|
||||
if ( $this->errors ) {
|
||||
update_post_meta(
|
||||
$this->contact_form->id(), '_config_errors', $this->errors
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Restore errors from the database.
|
||||
*/
|
||||
public function restore() {
|
||||
$config_errors = get_post_meta(
|
||||
$this->contact_form->id(), '_config_errors', true
|
||||
);
|
||||
|
||||
foreach ( (array) $config_errors as $section => $errors ) {
|
||||
if ( empty( $errors ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( ! is_array( $errors ) ) { // for back-compat
|
||||
$code = $errors;
|
||||
$this->add_error( $section, $code );
|
||||
} else {
|
||||
foreach ( (array) $errors as $error ) {
|
||||
if ( ! empty( $error['code'] ) ) {
|
||||
$code = $error['code'];
|
||||
$args = isset( $error['args'] ) ? $error['args'] : '';
|
||||
$this->add_error( $section, $code, $args );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Callback function for WPCF7_MailTaggedText. Replaces mail-tags with
|
||||
* the most conservative inputs.
|
||||
*/
|
||||
public function replace_mail_tags_with_minimum_input( $matches ) {
|
||||
// allow [[foo]] syntax for escaping a tag
|
||||
if ( $matches[1] == '[' && $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 = '';
|
||||
|
||||
$form_tags = $this->contact_form->scan_form_tags(
|
||||
array( 'name' => $field_name )
|
||||
);
|
||||
|
||||
if ( $form_tags ) {
|
||||
$form_tag = new WPCF7_FormTag( $form_tags[0] );
|
||||
|
||||
$is_required = ( $form_tag->is_required() || 'radio' == $form_tag->type );
|
||||
|
||||
if ( ! $is_required ) {
|
||||
return $example_blank;
|
||||
}
|
||||
|
||||
if ( wpcf7_form_tag_supports( $form_tag->type, 'selectable-values' ) ) {
|
||||
if ( $form_tag->pipes instanceof WPCF7_Pipes ) {
|
||||
if ( $mail_tag->get_option( 'do_not_heat' ) ) {
|
||||
$before_pipes = $form_tag->pipes->collect_befores();
|
||||
$last_item = array_pop( $before_pipes );
|
||||
} else {
|
||||
$after_pipes = $form_tag->pipes->collect_afters();
|
||||
$last_item = array_pop( $after_pipes );
|
||||
}
|
||||
} else {
|
||||
$last_item = array_pop( $form_tag->values );
|
||||
}
|
||||
|
||||
if ( $last_item and wpcf7_is_mailbox_list( $last_item ) ) {
|
||||
return $example_email;
|
||||
} else {
|
||||
return $example_text;
|
||||
}
|
||||
}
|
||||
|
||||
if ( 'email' == $form_tag->basetype ) {
|
||||
return $example_email;
|
||||
} else {
|
||||
return $example_text;
|
||||
}
|
||||
|
||||
} else { // maybe special mail tag
|
||||
// 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 ( '_user_' == substr( $field_name, 0, 6 ) ) {
|
||||
return $this->contact_form->is_true( 'subscribers_only' )
|
||||
? $example_text
|
||||
: $example_blank;
|
||||
|
||||
} elseif ( '_' == substr( $field_name, 0, 1 ) ) {
|
||||
return '_email' == substr( $field_name, -6 )
|
||||
? $example_email
|
||||
: $example_text;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return $tag;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Runs error detection for the form section.
|
||||
*/
|
||||
public function validate_form() {
|
||||
$section = 'form.body';
|
||||
$form = $this->contact_form->prop( 'form' );
|
||||
$this->detect_multiple_controls_in_label( $section, $form );
|
||||
$this->detect_unavailable_names( $section, $form );
|
||||
$this->detect_unavailable_html_elements( $section, $form );
|
||||
$this->detect_dots_in_names( $section, $form );
|
||||
$this->detect_colons_in_names( $section, $form );
|
||||
$this->detect_upload_filesize_overlimit( $section, $form );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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 $this->add_error( $section,
|
||||
self::error_multiple_controls_in_label, array(
|
||||
'link' => self::get_doc_link( 'multiple_controls_in_label' ),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 ) {
|
||||
$ng_names = array_unique( $ng_names );
|
||||
|
||||
return $this->add_error( $section,
|
||||
self::error_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 ) ),
|
||||
'link' => self::get_doc_link( 'unavailable_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 $this->add_error( $section,
|
||||
self::error_unavailable_html_elements,
|
||||
array(
|
||||
'message' => __( "Unavailable HTML elements are used in the form template.", 'contact-form-7' ),
|
||||
'link' => self::get_doc_link( 'unavailable_html_elements' ),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
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 ( false !== strpos( $tag->raw_name, '.' ) ) {
|
||||
return $this->add_error( $section,
|
||||
self::error_dots_in_names,
|
||||
array(
|
||||
'message' => __( "Dots are used in form-tag names.", 'contact-form-7' ),
|
||||
'link' => self::get_doc_link( 'dots_in_names' ),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
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 ( false !== strpos( $tag->raw_name, ':' ) ) {
|
||||
return $this->add_error( $section,
|
||||
self::error_colons_in_names,
|
||||
array(
|
||||
'message' => __( "Colons are used in form-tag names.", 'contact-form-7' ),
|
||||
'link' => self::get_doc_link( 'colons_in_names' ),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
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 $this->add_error( $section,
|
||||
self::error_upload_filesize_overlimit,
|
||||
array(
|
||||
'message' => __( "Uploadable file size exceeds PHP’s maximum acceptable size.", 'contact-form-7' ),
|
||||
'link' => self::get_doc_link( 'upload_filesize_overlimit' ),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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' => '',
|
||||
) );
|
||||
|
||||
$callback = array( $this, 'replace_mail_tags_with_minimum_input' );
|
||||
|
||||
$subject = new WPCF7_MailTaggedText(
|
||||
$components['subject'],
|
||||
array( 'callback' => $callback )
|
||||
);
|
||||
|
||||
$subject = $subject->replace_tags();
|
||||
$subject = wpcf7_strip_newline( $subject );
|
||||
|
||||
$this->detect_maybe_empty( sprintf( '%s.subject', $template ), $subject );
|
||||
|
||||
$sender = new WPCF7_MailTaggedText(
|
||||
$components['sender'],
|
||||
array( 'callback' => $callback )
|
||||
);
|
||||
|
||||
$sender = $sender->replace_tags();
|
||||
$sender = wpcf7_strip_newline( $sender );
|
||||
|
||||
$invalid_mailbox = $this->detect_invalid_mailbox_syntax(
|
||||
sprintf( '%s.sender', $template ),
|
||||
$sender
|
||||
);
|
||||
|
||||
if ( ! $invalid_mailbox and ! wpcf7_is_email_in_site_domain( $sender ) ) {
|
||||
$this->add_error( sprintf( '%s.sender', $template ),
|
||||
self::error_email_not_in_site_domain, array(
|
||||
'link' => self::get_doc_link( 'email_not_in_site_domain' ),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$recipient = new WPCF7_MailTaggedText(
|
||||
$components['recipient'],
|
||||
array( 'callback' => $callback )
|
||||
);
|
||||
|
||||
$recipient = $recipient->replace_tags();
|
||||
$recipient = wpcf7_strip_newline( $recipient );
|
||||
|
||||
$this->detect_invalid_mailbox_syntax(
|
||||
sprintf( '%s.recipient', $template ),
|
||||
$recipient
|
||||
);
|
||||
|
||||
$additional_headers = new WPCF7_MailTaggedText(
|
||||
$components['additional_headers'],
|
||||
array( 'callback' => $callback )
|
||||
);
|
||||
|
||||
$additional_headers = $additional_headers->replace_tags();
|
||||
$additional_headers = explode( "\n", $additional_headers );
|
||||
$mailbox_header_types = array( 'reply-to', 'cc', 'bcc' );
|
||||
$invalid_mail_header_exists = false;
|
||||
|
||||
foreach ( $additional_headers as $header ) {
|
||||
$header = trim( $header );
|
||||
|
||||
if ( '' === $header ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( ! preg_match( '/^([0-9A-Za-z-]+):(.*)$/', $header, $matches ) ) {
|
||||
$invalid_mail_header_exists = true;
|
||||
} else {
|
||||
$header_name = $matches[1];
|
||||
$header_value = trim( $matches[2] );
|
||||
|
||||
if ( in_array( strtolower( $header_name ), $mailbox_header_types )
|
||||
and '' !== $header_value ) {
|
||||
$this->detect_invalid_mailbox_syntax(
|
||||
sprintf( '%s.additional_headers', $template ),
|
||||
$header_value,
|
||||
array(
|
||||
'message' =>
|
||||
__( "Invalid mailbox syntax is used in the %name% field.", 'contact-form-7' ),
|
||||
'params' => array( 'name' => $header_name )
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( $invalid_mail_header_exists ) {
|
||||
$this->add_error( sprintf( '%s.additional_headers', $template ),
|
||||
self::error_invalid_mail_header, array(
|
||||
'link' => self::get_doc_link( 'invalid_mail_header' ),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$body = new WPCF7_MailTaggedText(
|
||||
$components['body'],
|
||||
array( 'callback' => $callback )
|
||||
);
|
||||
|
||||
$body = $body->replace_tags();
|
||||
|
||||
$this->detect_maybe_empty( sprintf( '%s.body', $template ), $body );
|
||||
|
||||
if ( '' !== $components['attachments'] ) {
|
||||
$attachables = array();
|
||||
|
||||
$tags = $this->contact_form->scan_form_tags(
|
||||
array( 'type' => array( 'file', 'file*' ) )
|
||||
);
|
||||
|
||||
foreach ( $tags as $tag ) {
|
||||
$name = $tag->name;
|
||||
|
||||
if ( false === strpos( $components['attachments'], "[{$name}]" ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$limit = (int) $tag->get_limit_option();
|
||||
|
||||
if ( empty( $attachables[$name] )
|
||||
or $attachables[$name] < $limit ) {
|
||||
$attachables[$name] = $limit;
|
||||
}
|
||||
}
|
||||
|
||||
$total_size = array_sum( $attachables );
|
||||
|
||||
$has_file_not_found = false;
|
||||
$has_file_not_in_content_dir = false;
|
||||
|
||||
foreach ( explode( "\n", $components['attachments'] ) as $line ) {
|
||||
$line = trim( $line );
|
||||
|
||||
if ( '' === $line or '[' == substr( $line, 0, 1 ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$has_file_not_found = $this->detect_file_not_found(
|
||||
sprintf( '%s.attachments', $template ), $line
|
||||
);
|
||||
|
||||
if ( ! $has_file_not_found and ! $has_file_not_in_content_dir ) {
|
||||
$has_file_not_in_content_dir = $this->detect_file_not_in_content_dir(
|
||||
sprintf( '%s.attachments', $template ), $line
|
||||
);
|
||||
}
|
||||
|
||||
if ( ! $has_file_not_found ) {
|
||||
$path = path_join( WP_CONTENT_DIR, $line );
|
||||
$total_size += (int) @filesize( $path );
|
||||
}
|
||||
}
|
||||
|
||||
$max = 25 * MB_IN_BYTES; // 25 MB
|
||||
|
||||
if ( $max < $total_size ) {
|
||||
$this->add_error( sprintf( '%s.attachments', $template ),
|
||||
self::error_attachments_overweight,
|
||||
array(
|
||||
'message' => __( "The total size of attachment files is too large.", 'contact-form-7' ),
|
||||
'link' => self::get_doc_link( '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, $args = '' ) {
|
||||
$args = wp_parse_args( $args, array(
|
||||
'link' => self::get_doc_link( 'invalid_mailbox_syntax' ),
|
||||
'message' => '',
|
||||
'params' => array(),
|
||||
) );
|
||||
|
||||
if ( ! wpcf7_is_mailbox_list( $content ) ) {
|
||||
return $this->add_error( $section,
|
||||
self::error_invalid_mailbox_syntax, $args
|
||||
);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Detects errors of empty message fields.
|
||||
*
|
||||
* @link https://contactform7.com/configuration-errors/maybe-empty/
|
||||
*/
|
||||
public function detect_maybe_empty( $section, $content ) {
|
||||
if ( '' === $content ) {
|
||||
return $this->add_error( $section,
|
||||
self::error_maybe_empty, array(
|
||||
'link' => self::get_doc_link( 'maybe_empty' ),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
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 $this->add_error( $section,
|
||||
self::error_file_not_found,
|
||||
array(
|
||||
'message' =>
|
||||
__( "Attachment file does not exist at %path%.", 'contact-form-7' ),
|
||||
'params' => array( 'path' => $content ),
|
||||
'link' => self::get_doc_link( 'file_not_found' ),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
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 $this->add_error( $section,
|
||||
self::error_file_not_in_content_dir,
|
||||
array(
|
||||
'message' =>
|
||||
__( "It is not allowed to use files outside the wp-content directory.", 'contact-form-7' ),
|
||||
'link' => self::get_doc_link( 'file_not_in_content_dir' ),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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 );
|
||||
$this->detect_html_in_message( $section, $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 $this->add_error( $section,
|
||||
self::error_html_in_message,
|
||||
array(
|
||||
'link' => self::get_doc_link( 'html_in_message' ),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Runs error detection for the additional settings section.
|
||||
*/
|
||||
public function validate_additional_settings() {
|
||||
$deprecated_settings_used =
|
||||
$this->contact_form->additional_setting( 'on_sent_ok' ) ||
|
||||
$this->contact_form->additional_setting( 'on_submit' );
|
||||
|
||||
if ( $deprecated_settings_used ) {
|
||||
return $this->add_error( 'additional_settings.body',
|
||||
self::error_deprecated_settings,
|
||||
array(
|
||||
'link' => self::get_doc_link( 'deprecated_settings' ),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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,603 @@
|
||||
<?php
|
||||
|
||||
trait WPCF7_ConfigValidator_Mail {
|
||||
|
||||
/**
|
||||
* Replaces all mail-tags in the given content.
|
||||
*/
|
||||
public function replace_mail_tags( $content, $args = '' ) {
|
||||
$args = wp_parse_args( $args, array(
|
||||
'html' => false,
|
||||
'callback' =>
|
||||
array( $this, 'replace_mail_tags_with_minimum_input_callback' ),
|
||||
) );
|
||||
|
||||
$content = new WPCF7_MailTaggedText( $content, $args );
|
||||
|
||||
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 = '';
|
||||
|
||||
$form_tags = $this->contact_form->scan_form_tags(
|
||||
array( 'name' => $field_name )
|
||||
);
|
||||
|
||||
if ( $form_tags ) {
|
||||
$form_tag = new WPCF7_FormTag( $form_tags[0] );
|
||||
|
||||
$is_required = $form_tag->is_required() || 'radio' === $form_tag->type;
|
||||
|
||||
if ( ! $is_required ) {
|
||||
return $example_blank;
|
||||
}
|
||||
|
||||
if ( wpcf7_form_tag_supports( $form_tag->type, 'selectable-values' ) ) {
|
||||
if ( $form_tag->pipes instanceof WPCF7_Pipes ) {
|
||||
if ( $mail_tag->get_option( 'do_not_heat' ) ) {
|
||||
$before_pipes = $form_tag->pipes->collect_befores();
|
||||
$last_item = array_pop( $before_pipes );
|
||||
} else {
|
||||
$after_pipes = $form_tag->pipes->collect_afters();
|
||||
$last_item = array_pop( $after_pipes );
|
||||
}
|
||||
} else {
|
||||
$last_item = array_pop( $form_tag->values );
|
||||
}
|
||||
|
||||
if ( $last_item and wpcf7_is_mailbox_list( $last_item ) ) {
|
||||
return $example_email;
|
||||
} else {
|
||||
return $example_text;
|
||||
}
|
||||
}
|
||||
|
||||
if ( 'email' === $form_tag->basetype ) {
|
||||
return $example_email;
|
||||
} else {
|
||||
return $example_text;
|
||||
}
|
||||
|
||||
} else { // maybe special mail tag
|
||||
// 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;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return $tag;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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' )
|
||||
) 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' ) ) 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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 ) {
|
||||
static $is_recaptcha_active = null;
|
||||
|
||||
if ( null === $is_recaptcha_active ) {
|
||||
$is_recaptcha_active = call_user_func( function () {
|
||||
$service = WPCF7_RECAPTCHA::get_instance();
|
||||
return $service->is_active();
|
||||
} );
|
||||
}
|
||||
|
||||
if ( $is_recaptcha_active ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$example_email = 'example@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,376 @@
|
||||
<?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, $args = '' ) {
|
||||
$args = wp_parse_args( $args, array(
|
||||
'include' => null,
|
||||
'exclude' => null,
|
||||
) );
|
||||
|
||||
$this->contact_form = $contact_form;
|
||||
|
||||
if ( isset( $args['include'] ) ) {
|
||||
$this->include = (array) $args['include'];
|
||||
}
|
||||
|
||||
if ( isset( $args['exclude'] ) ) {
|
||||
$this->exclude = (array) $args['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( $args = '' ) {
|
||||
$args = wp_parse_args( $args, 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 ( $args['section']
|
||||
and $key !== $args['section']
|
||||
and preg_replace( '/\..*$/', '', $key, 1 ) !== $args['section'] ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ( $errors as $error ) {
|
||||
if ( empty( $error ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( $args['code'] and $error['code'] !== $args['code'] ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
return $count;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Collects messages for detected errors.
|
||||
*/
|
||||
public function collect_error_messages() {
|
||||
$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']
|
||||
);
|
||||
}
|
||||
|
||||
$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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -33,6 +33,32 @@ function wpcf7_get_contact_form_by_old_id( $old_id ) {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Searches for a contact form by a hash string.
|
||||
*
|
||||
* @param string $hash Part of a hash string.
|
||||
* @return WPCF7_ContactForm Contact form object.
|
||||
*/
|
||||
function wpcf7_get_contact_form_by_hash( $hash ) {
|
||||
global $wpdb;
|
||||
|
||||
$hash = trim( $hash );
|
||||
|
||||
if ( strlen( $hash ) < 7 ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$like = $wpdb->esc_like( $hash ) . '%';
|
||||
|
||||
$q = "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '_hash'"
|
||||
. $wpdb->prepare( " AND meta_value LIKE %s", $like );
|
||||
|
||||
if ( $post_id = $wpdb->get_var( $q ) ) {
|
||||
return wpcf7_contact_form( $post_id );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Searches for a contact form by title.
|
||||
*
|
||||
@@ -166,20 +192,22 @@ function wpcf7_get_message( $status ) {
|
||||
*/
|
||||
function wpcf7_form_controls_class( $type, $default_classes = '' ) {
|
||||
$type = trim( $type );
|
||||
$default_classes = array_filter( explode( ' ', $default_classes ) );
|
||||
|
||||
$classes = array_merge( array( 'wpcf7-form-control' ), $default_classes );
|
||||
if ( is_string( $default_classes ) ) {
|
||||
$default_classes = explode( ' ', $default_classes );
|
||||
}
|
||||
|
||||
$typebase = rtrim( $type, '*' );
|
||||
$required = ( '*' == substr( $type, -1 ) );
|
||||
$classes = array(
|
||||
'wpcf7-form-control',
|
||||
sprintf( 'wpcf7-%s', rtrim( $type, '*' ) ),
|
||||
);
|
||||
|
||||
$classes[] = 'wpcf7-' . $typebase;
|
||||
|
||||
if ( $required ) {
|
||||
if ( str_ends_with( $type, '*' ) ) {
|
||||
$classes[] = 'wpcf7-validates-as-required';
|
||||
}
|
||||
|
||||
$classes = array_unique( $classes );
|
||||
$classes = array_merge( $classes, $default_classes );
|
||||
$classes = array_filter( array_unique( $classes ) );
|
||||
|
||||
return implode( ' ', $classes );
|
||||
}
|
||||
@@ -193,10 +221,10 @@ function wpcf7_contact_form_tag_func( $atts, $content = null, $code = '' ) {
|
||||
return '[contact-form-7]';
|
||||
}
|
||||
|
||||
if ( 'contact-form-7' == $code ) {
|
||||
if ( 'contact-form-7' === $code ) {
|
||||
$atts = shortcode_atts(
|
||||
array(
|
||||
'id' => 0,
|
||||
'id' => '',
|
||||
'title' => '',
|
||||
'html_id' => '',
|
||||
'html_name' => '',
|
||||
@@ -207,10 +235,16 @@ function wpcf7_contact_form_tag_func( $atts, $content = null, $code = '' ) {
|
||||
$atts, 'wpcf7'
|
||||
);
|
||||
|
||||
$id = (int) $atts['id'];
|
||||
$id = trim( $atts['id'] );
|
||||
$title = trim( $atts['title'] );
|
||||
|
||||
if ( ! $contact_form = wpcf7_contact_form( $id ) ) {
|
||||
$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 );
|
||||
}
|
||||
|
||||
@@ -235,11 +269,15 @@ function wpcf7_contact_form_tag_func( $atts, $content = null, $code = '' ) {
|
||||
return $contact_form->form_html( $atts );
|
||||
};
|
||||
|
||||
return wpcf7_switch_locale(
|
||||
$output = wpcf7_switch_locale(
|
||||
$contact_form->locale(),
|
||||
$callback,
|
||||
$contact_form, $atts
|
||||
);
|
||||
|
||||
do_action( 'wpcf7_shortcode_callback', $contact_form, $atts );
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
|
||||
@@ -415,3 +453,19 @@ function wpcf7_sanitize_additional_settings( $input, $default_template = '' ) {
|
||||
$output = trim( $input );
|
||||
return $output;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generates a random hash string for a contact form.
|
||||
*
|
||||
* @param int $post_id Post ID.
|
||||
* @return string SHA-1 hash.
|
||||
*/
|
||||
function wpcf7_generate_contact_form_hash( $post_id ) {
|
||||
return sha1( implode( '|', array(
|
||||
get_current_user_id(),
|
||||
$post_id,
|
||||
time(),
|
||||
home_url(),
|
||||
) ) );
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ class WPCF7_ContactFormTemplate {
|
||||
. '-- ' . "\n"
|
||||
. sprintf(
|
||||
/* translators: 1: blog name, 2: blog URL */
|
||||
__( 'This e-mail was sent from a contact form on %1$s (%2$s)', 'contact-form-7' ),
|
||||
__( 'This is a notification that a contact form was submitted on your website (%1$s %2$s).', 'contact-form-7' ),
|
||||
'[_site_title]',
|
||||
'[_site_url]'
|
||||
),
|
||||
@@ -108,7 +108,7 @@ class WPCF7_ContactFormTemplate {
|
||||
. '-- ' . "\n"
|
||||
. sprintf(
|
||||
/* translators: 1: blog name, 2: blog URL */
|
||||
__( 'This e-mail was sent from a contact form on %1$s (%2$s)', 'contact-form-7' ),
|
||||
__( '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]'
|
||||
),
|
||||
|
||||
@@ -18,6 +18,7 @@ class WPCF7_ContactForm {
|
||||
private $responses_count = 0;
|
||||
private $scanned_form_tags;
|
||||
private $shortcode_atts = array();
|
||||
private $hash = '';
|
||||
|
||||
|
||||
/**
|
||||
@@ -207,11 +208,12 @@ class WPCF7_ContactForm {
|
||||
$post = get_post( $post );
|
||||
|
||||
if ( $post
|
||||
and self::post_type == get_post_type( $post ) ) {
|
||||
and self::post_type === get_post_type( $post ) ) {
|
||||
$this->id = $post->ID;
|
||||
$this->name = $post->post_name;
|
||||
$this->title = $post->post_title;
|
||||
$this->locale = get_post_meta( $post->ID, '_locale', true );
|
||||
$this->hash = get_post_meta( $post->ID, '_hash', true );
|
||||
|
||||
$this->construct_properties( $post );
|
||||
$this->upgrade();
|
||||
@@ -471,6 +473,17 @@ class WPCF7_ContactForm {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the random hash string tied to this contact form.
|
||||
*
|
||||
* @param int $length Length of hash string.
|
||||
* @return string Hash string unique to this contact form.
|
||||
*/
|
||||
public function hash( $length = 7 ) {
|
||||
return substr( $this->hash, 0, absint( $length ) );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the specified shortcode attribute value.
|
||||
*
|
||||
@@ -626,9 +639,9 @@ class WPCF7_ContactForm {
|
||||
'data-status' => $data_status_attr,
|
||||
);
|
||||
|
||||
$atts = wpcf7_format_atts( $atts );
|
||||
$atts += (array) apply_filters( 'wpcf7_form_additional_atts', array() );
|
||||
|
||||
$html .= sprintf( '<form %s>', $atts ) . "\n";
|
||||
$html .= sprintf( '<form %s>', wpcf7_format_atts( $atts ) ) . "\n";
|
||||
$html .= $this->form_hidden_fields();
|
||||
$html .= $this->form_elements();
|
||||
|
||||
@@ -1263,6 +1276,11 @@ class WPCF7_ContactForm {
|
||||
update_post_meta( $post_id, '_locale', $this->locale );
|
||||
}
|
||||
|
||||
add_post_meta( $post_id, '_hash',
|
||||
wpcf7_generate_contact_form_hash( $post_id ),
|
||||
true // Unique
|
||||
);
|
||||
|
||||
if ( $this->initial() ) {
|
||||
$this->id = $post_id;
|
||||
do_action( 'wpcf7_after_create', $this );
|
||||
@@ -1333,8 +1351,8 @@ class WPCF7_ContactForm {
|
||||
}
|
||||
} else {
|
||||
$shortcode = sprintf(
|
||||
'[contact-form-7 id="%1$d" title="%2$s"]',
|
||||
$this->id,
|
||||
'[contact-form-7 id="%1$s" title="%2$s"]',
|
||||
$this->hash(),
|
||||
$title
|
||||
);
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ class WPCF7_FormTag implements ArrayAccess {
|
||||
* Returns true if the type has a trailing asterisk.
|
||||
*/
|
||||
public function is_required() {
|
||||
return ( '*' === substr( $this->type, -1 ) );
|
||||
return str_ends_with( $this->type, '*' );
|
||||
}
|
||||
|
||||
|
||||
@@ -115,7 +115,21 @@ class WPCF7_FormTag implements ArrayAccess {
|
||||
* Retrieves the id option value from the form-tag.
|
||||
*/
|
||||
public function get_id_option() {
|
||||
return $this->get_option( 'id', 'id', true );
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -134,9 +148,10 @@ class WPCF7_FormTag implements ArrayAccess {
|
||||
|
||||
$options = array_merge(
|
||||
(array) $default_classes,
|
||||
(array) $this->get_option( 'class', 'class' )
|
||||
(array) $this->get_option( 'class' )
|
||||
);
|
||||
|
||||
$options = array_map( 'sanitize_html_class', $options );
|
||||
$options = array_filter( array_unique( $options ) );
|
||||
|
||||
if ( empty( $options ) ) {
|
||||
@@ -395,7 +410,7 @@ class WPCF7_FormTag implements ArrayAccess {
|
||||
if ( $contact_form = WPCF7_ContactForm::get_current() ) {
|
||||
$val = $contact_form->shortcode_attr( $this->name );
|
||||
|
||||
if ( strlen( $val ) ) {
|
||||
if ( isset( $val ) and strlen( $val ) ) {
|
||||
if ( $args['multiple'] ) {
|
||||
$values[] = $val;
|
||||
} else {
|
||||
|
||||
@@ -522,7 +522,13 @@ function wpcf7_format_atts( $atts ) {
|
||||
}
|
||||
|
||||
static $boolean_attributes = array(
|
||||
'checked', 'disabled', 'multiple', 'readonly', 'required', 'selected',
|
||||
'checked',
|
||||
'disabled',
|
||||
'inert',
|
||||
'multiple',
|
||||
'readonly',
|
||||
'required',
|
||||
'selected',
|
||||
);
|
||||
|
||||
if ( in_array( $name, $boolean_attributes ) and '' === $value ) {
|
||||
|
||||
@@ -210,7 +210,7 @@ function wpcf7_validate_configuration() {
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if wpcf7_autop() is applied to form content.
|
||||
* Returns true if wpcf7_autop() is applied.
|
||||
*/
|
||||
function wpcf7_autop_or_not() {
|
||||
return (bool) apply_filters( 'wpcf7_autop_or_not', WPCF7_AUTOP );
|
||||
|
||||
@@ -1,5 +1,19 @@
|
||||
<?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() ) {
|
||||
$body = wpcf7_autop( $body );
|
||||
}
|
||||
|
||||
return $body;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Class that represents an attempt to compose and send email.
|
||||
*/
|
||||
@@ -142,14 +156,19 @@ class WPCF7_Mail {
|
||||
<title>' . esc_html( $this->get( 'subject', true ) ) . '</title>
|
||||
</head>
|
||||
<body>
|
||||
', $this );
|
||||
',
|
||||
$this
|
||||
);
|
||||
|
||||
$body = apply_filters( 'wpcf7_mail_html_body', $body, $this );
|
||||
|
||||
$footer = apply_filters( 'wpcf7_mail_html_footer',
|
||||
'</body>
|
||||
</html>', $this );
|
||||
</html>',
|
||||
$this
|
||||
);
|
||||
|
||||
$html = $header . wpcf7_autop( $body ) . $footer;
|
||||
return $html;
|
||||
return $header . $body . $footer;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -179,6 +179,7 @@ class WPCF7_REST_Controller {
|
||||
foreach ( $items as $item ) {
|
||||
$response[] = array(
|
||||
'id' => $item->id(),
|
||||
'hash' => $item->hash(),
|
||||
'slug' => $item->name(),
|
||||
'title' => $item->title(),
|
||||
'locale' => $item->locale(),
|
||||
|
||||
@@ -32,7 +32,7 @@ function wpcf7_special_mail_tag( $output, $name, $html, $mail_tag = null ) {
|
||||
return $output;
|
||||
}
|
||||
|
||||
if ( '_remote_ip' == $name ) {
|
||||
if ( '_remote_ip' === $name ) {
|
||||
if ( $remote_ip = $submission->get_meta( 'remote_ip' ) ) {
|
||||
return $remote_ip;
|
||||
} else {
|
||||
@@ -40,7 +40,7 @@ function wpcf7_special_mail_tag( $output, $name, $html, $mail_tag = null ) {
|
||||
}
|
||||
}
|
||||
|
||||
if ( '_user_agent' == $name ) {
|
||||
if ( '_user_agent' === $name ) {
|
||||
if ( $user_agent = $submission->get_meta( 'user_agent' ) ) {
|
||||
return $html ? esc_html( $user_agent ) : $user_agent;
|
||||
} else {
|
||||
@@ -48,7 +48,7 @@ function wpcf7_special_mail_tag( $output, $name, $html, $mail_tag = null ) {
|
||||
}
|
||||
}
|
||||
|
||||
if ( '_url' == $name ) {
|
||||
if ( '_url' === $name ) {
|
||||
if ( $url = $submission->get_meta( 'url' ) ) {
|
||||
return $url;
|
||||
} else {
|
||||
@@ -56,14 +56,13 @@ function wpcf7_special_mail_tag( $output, $name, $html, $mail_tag = null ) {
|
||||
}
|
||||
}
|
||||
|
||||
if ( '_date' == $name
|
||||
or '_time' == $name ) {
|
||||
if ( '_date' === $name or '_time' === $name ) {
|
||||
if ( $timestamp = $submission->get_meta( 'timestamp' ) ) {
|
||||
if ( '_date' == $name ) {
|
||||
if ( '_date' === $name ) {
|
||||
return wp_date( get_option( 'date_format' ), $timestamp );
|
||||
}
|
||||
|
||||
if ( '_time' == $name ) {
|
||||
if ( '_time' === $name ) {
|
||||
return wp_date( get_option( 'time_format' ), $timestamp );
|
||||
}
|
||||
}
|
||||
@@ -71,7 +70,7 @@ function wpcf7_special_mail_tag( $output, $name, $html, $mail_tag = null ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if ( '_invalid_fields' == $name ) {
|
||||
if ( '_invalid_fields' === $name ) {
|
||||
return count( $submission->get_invalid_fields() );
|
||||
}
|
||||
|
||||
@@ -99,7 +98,7 @@ function wpcf7_post_related_smt( $output, $name, $html, $mail_tag = null ) {
|
||||
);
|
||||
}
|
||||
|
||||
if ( '_post_' != substr( $name, 0, 6 ) ) {
|
||||
if ( ! str_starts_with( $name, '_post_' ) ) {
|
||||
return $output;
|
||||
}
|
||||
|
||||
@@ -111,34 +110,33 @@ function wpcf7_post_related_smt( $output, $name, $html, $mail_tag = null ) {
|
||||
|
||||
$post_id = (int) $submission->get_meta( 'container_post_id' );
|
||||
|
||||
if ( ! $post_id
|
||||
or ! $post = get_post( $post_id ) ) {
|
||||
if ( ! $post_id or ! $post = get_post( $post_id ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if ( '_post_id' == $name ) {
|
||||
if ( '_post_id' === $name ) {
|
||||
return (string) $post->ID;
|
||||
}
|
||||
|
||||
if ( '_post_name' == $name ) {
|
||||
if ( '_post_name' === $name ) {
|
||||
return $post->post_name;
|
||||
}
|
||||
|
||||
if ( '_post_title' == $name ) {
|
||||
if ( '_post_title' === $name ) {
|
||||
return $html ? esc_html( $post->post_title ) : $post->post_title;
|
||||
}
|
||||
|
||||
if ( '_post_url' == $name ) {
|
||||
if ( '_post_url' === $name ) {
|
||||
return get_permalink( $post->ID );
|
||||
}
|
||||
|
||||
$user = new WP_User( $post->post_author );
|
||||
|
||||
if ( '_post_author' == $name ) {
|
||||
if ( '_post_author' === $name ) {
|
||||
return $user->display_name;
|
||||
}
|
||||
|
||||
if ( '_post_author_email' == $name ) {
|
||||
if ( '_post_author_email' === $name ) {
|
||||
return $user->user_email;
|
||||
}
|
||||
|
||||
@@ -168,7 +166,7 @@ function wpcf7_site_related_smt( $output, $name, $html, $mail_tag = null ) {
|
||||
|
||||
$filter = $html ? 'display' : 'raw';
|
||||
|
||||
if ( '_site_title' == $name ) {
|
||||
if ( '_site_title' === $name ) {
|
||||
$output = get_bloginfo( 'name', $filter );
|
||||
|
||||
if ( ! $html ) {
|
||||
@@ -178,7 +176,7 @@ function wpcf7_site_related_smt( $output, $name, $html, $mail_tag = null ) {
|
||||
return $output;
|
||||
}
|
||||
|
||||
if ( '_site_description' == $name ) {
|
||||
if ( '_site_description' === $name ) {
|
||||
$output = get_bloginfo( 'description', $filter );
|
||||
|
||||
if ( ! $html ) {
|
||||
@@ -188,11 +186,11 @@ function wpcf7_site_related_smt( $output, $name, $html, $mail_tag = null ) {
|
||||
return $output;
|
||||
}
|
||||
|
||||
if ( '_site_url' == $name ) {
|
||||
if ( '_site_url' === $name ) {
|
||||
return get_bloginfo( 'url', $filter );
|
||||
}
|
||||
|
||||
if ( '_site_admin_email' == $name ) {
|
||||
if ( '_site_admin_email' === $name ) {
|
||||
return get_bloginfo( 'admin_email', $filter );
|
||||
}
|
||||
|
||||
@@ -220,8 +218,7 @@ function wpcf7_user_related_smt( $output, $name, $html, $mail_tag = null ) {
|
||||
);
|
||||
}
|
||||
|
||||
if ( '_user_' != substr( $name, 0, 6 )
|
||||
or '_user_agent' == $name ) {
|
||||
if ( ! str_starts_with( $name, '_user_' ) or '_user_agent' === $name ) {
|
||||
return $output;
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -33,7 +33,4 @@ class WPCF7_SWV_DateRule extends WPCF7_SWV_Rule {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function to_array() {
|
||||
return array( 'rule' => self::rule_name ) + (array) $this->properties;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
class WPCF7_SWV_DayofweekRule extends WPCF7_SWV_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 ) {
|
||||
$field = $this->get_property( 'field' );
|
||||
|
||||
$input = isset( $_POST[$field] ) ? $_POST[$field] : '';
|
||||
|
||||
$input = wpcf7_array_flatten( $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 new WP_Error( 'wpcf7_invalid_dayofweek',
|
||||
$this->get_property( 'error' )
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -33,7 +33,4 @@ class WPCF7_SWV_EmailRule extends WPCF7_SWV_Rule {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function to_array() {
|
||||
return array( 'rule' => self::rule_name ) + (array) $this->properties;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,7 +40,4 @@ class WPCF7_SWV_EnumRule extends WPCF7_SWV_Rule {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function to_array() {
|
||||
return array( 'rule' => self::rule_name ) + (array) $this->properties;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,7 +60,4 @@ class WPCF7_SWV_FileRule extends WPCF7_SWV_Rule {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function to_array() {
|
||||
return array( 'rule' => self::rule_name ) + (array) $this->properties;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,4 @@ class WPCF7_SWV_MaxDateRule extends WPCF7_SWV_Rule {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function to_array() {
|
||||
return array( 'rule' => self::rule_name ) + (array) $this->properties;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,4 @@ class WPCF7_SWV_MaxFileSizeRule extends WPCF7_SWV_Rule {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function to_array() {
|
||||
return array( 'rule' => self::rule_name ) + (array) $this->properties;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,4 @@ class WPCF7_SWV_MaxItemsRule extends WPCF7_SWV_Rule {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function to_array() {
|
||||
return array( 'rule' => self::rule_name ) + (array) $this->properties;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,4 @@ class WPCF7_SWV_MaxLengthRule extends WPCF7_SWV_Rule {
|
||||
}
|
||||
}
|
||||
|
||||
public function to_array() {
|
||||
return array( 'rule' => self::rule_name ) + (array) $this->properties;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,4 @@ class WPCF7_SWV_MaxNumberRule extends WPCF7_SWV_Rule {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function to_array() {
|
||||
return array( 'rule' => self::rule_name ) + (array) $this->properties;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,4 @@ class WPCF7_SWV_MinDateRule extends WPCF7_SWV_Rule {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function to_array() {
|
||||
return array( 'rule' => self::rule_name ) + (array) $this->properties;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,4 @@ class WPCF7_SWV_MinFileSizeRule extends WPCF7_SWV_Rule {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function to_array() {
|
||||
return array( 'rule' => self::rule_name ) + (array) $this->properties;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,4 @@ class WPCF7_SWV_MinItemsRule extends WPCF7_SWV_Rule {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function to_array() {
|
||||
return array( 'rule' => self::rule_name ) + (array) $this->properties;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,4 @@ class WPCF7_SWV_MinLengthRule extends WPCF7_SWV_Rule {
|
||||
}
|
||||
}
|
||||
|
||||
public function to_array() {
|
||||
return array( 'rule' => self::rule_name ) + (array) $this->properties;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,4 @@ class WPCF7_SWV_MinNumberRule extends WPCF7_SWV_Rule {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function to_array() {
|
||||
return array( 'rule' => self::rule_name ) + (array) $this->properties;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,4 @@ class WPCF7_SWV_NumberRule extends WPCF7_SWV_Rule {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function to_array() {
|
||||
return array( 'rule' => self::rule_name ) + (array) $this->properties;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,4 @@ class WPCF7_SWV_RequiredRule extends WPCF7_SWV_Rule {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function to_array() {
|
||||
return array( 'rule' => self::rule_name ) + (array) $this->properties;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,4 @@ class WPCF7_SWV_RequiredFileRule extends WPCF7_SWV_Rule {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function to_array() {
|
||||
return array( 'rule' => self::rule_name ) + (array) $this->properties;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,4 @@ class WPCF7_SWV_TelRule extends WPCF7_SWV_Rule {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function to_array() {
|
||||
return array( 'rule' => self::rule_name ) + (array) $this->properties;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
class WPCF7_SWV_TimeRule extends WPCF7_SWV_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 ) {
|
||||
$field = $this->get_property( 'field' );
|
||||
$input = isset( $_POST[$field] ) ? $_POST[$field] : '';
|
||||
$input = wpcf7_array_flatten( $input );
|
||||
$input = wpcf7_exclude_blank( $input );
|
||||
|
||||
foreach ( $input as $i ) {
|
||||
if ( ! wpcf7_is_time( $i ) ) {
|
||||
return new WP_Error( 'wpcf7_invalid_time',
|
||||
$this->get_property( 'error' )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -33,7 +33,4 @@ class WPCF7_SWV_URLRule extends WPCF7_SWV_Rule {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function to_array() {
|
||||
return array( 'rule' => self::rule_name ) + (array) $this->properties;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,8 +19,10 @@ function wpcf7_swv_available_rules() {
|
||||
'tel' => 'WPCF7_SWV_TelRule',
|
||||
'number' => 'WPCF7_SWV_NumberRule',
|
||||
'date' => 'WPCF7_SWV_DateRule',
|
||||
'time' => 'WPCF7_SWV_TimeRule',
|
||||
'file' => 'WPCF7_SWV_FileRule',
|
||||
'enum' => 'WPCF7_SWV_EnumRule',
|
||||
'dayofweek' => 'WPCF7_SWV_DayofweekRule',
|
||||
'minitems' => 'WPCF7_SWV_MinItemsRule',
|
||||
'maxitems' => 'WPCF7_SWV_MaxItemsRule',
|
||||
'minlength' => 'WPCF7_SWV_MinLengthRule',
|
||||
@@ -168,7 +170,13 @@ abstract class WPCF7_SWV_Rule {
|
||||
* @return array Array of properties.
|
||||
*/
|
||||
public function to_array() {
|
||||
return (array) $this->properties;
|
||||
$properties = (array) $this->properties;
|
||||
|
||||
if ( defined( 'static::rule_name' ) and static::rule_name ) {
|
||||
$properties = array( 'rule' => static::rule_name ) + $properties;
|
||||
}
|
||||
|
||||
return $properties;
|
||||
}
|
||||
|
||||
|
||||
@@ -276,7 +284,7 @@ abstract class WPCF7_SWV_CompositeRule extends WPCF7_SWV_Rule {
|
||||
*/
|
||||
class WPCF7_SWV_Schema extends WPCF7_SWV_CompositeRule {
|
||||
|
||||
const version = 'Contact Form 7 SWV Schema 2022-10';
|
||||
const version = 'Contact Form 7 SWV Schema 2023-07';
|
||||
|
||||
public function __construct( $properties = '' ) {
|
||||
$this->properties = wp_parse_args( $properties, array(
|
||||
|
||||
@@ -1,7 +1,44 @@
|
||||
<?php
|
||||
|
||||
add_action( 'wpcf7_upgrade', 'wpcf7_upgrade_58', 10, 2 );
|
||||
|
||||
/**
|
||||
* Runs functions necessary when upgrading from old plugin versions before 5.8.
|
||||
*
|
||||
* @since 5.8.0 New `_config_validation` post meta is introduced.
|
||||
*/
|
||||
function wpcf7_upgrade_58( $new_ver, $old_ver ) {
|
||||
if ( ! version_compare( $old_ver, '5.8-dev', '<' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$posts = WPCF7_ContactForm::find( array(
|
||||
'post_status' => 'any',
|
||||
'posts_per_page' => -1,
|
||||
) );
|
||||
|
||||
foreach ( $posts as $post ) {
|
||||
$post_id = $post->id();
|
||||
|
||||
// Delete the old post meta for config-validation results.
|
||||
delete_post_meta( $post_id, '_config_errors' );
|
||||
|
||||
// Add the contact form hash.
|
||||
add_post_meta( $post_id, '_hash',
|
||||
wpcf7_generate_contact_form_hash( $post_id ),
|
||||
true // Unique
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
add_action( 'wpcf7_upgrade', 'wpcf7_convert_to_cpt', 10, 2 );
|
||||
|
||||
/**
|
||||
* Converts old data in the dedicated database table to custom posts.
|
||||
*
|
||||
* @since 3.0.0 `wpcf7_contact_form` CPT is introduced.
|
||||
*/
|
||||
function wpcf7_convert_to_cpt( $new_ver, $old_ver ) {
|
||||
global $wpdb;
|
||||
|
||||
@@ -44,18 +81,29 @@ function wpcf7_convert_to_cpt( $new_ver, $old_ver ) {
|
||||
if ( $post_id ) {
|
||||
update_post_meta( $post_id, '_old_cf7_unit_id', $row->cf7_unit_id );
|
||||
|
||||
$metas = array( 'form', 'mail', 'mail_2', 'messages', 'additional_settings' );
|
||||
$metas = array(
|
||||
'form',
|
||||
'mail',
|
||||
'mail_2',
|
||||
'messages',
|
||||
'additional_settings',
|
||||
);
|
||||
|
||||
foreach ( $metas as $meta ) {
|
||||
update_post_meta( $post_id, '_' . $meta,
|
||||
wpcf7_normalize_newline_deep( maybe_unserialize( $row->{$meta} ) ) );
|
||||
wpcf7_normalize_newline_deep( maybe_unserialize( $row->{$meta} ) )
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
add_action( 'wpcf7_upgrade', 'wpcf7_prepend_underscore', 10, 2 );
|
||||
|
||||
/**
|
||||
* Prepends an underscore to post meta keys.
|
||||
*/
|
||||
function wpcf7_prepend_underscore( $new_ver, $old_ver ) {
|
||||
if ( version_compare( $old_ver, '3.0-dev', '<' ) ) {
|
||||
return;
|
||||
|
||||
@@ -75,7 +75,11 @@ function wpcf7_is_number( $text ) {
|
||||
* @link https://html.spec.whatwg.org/multipage/input.html#date-state-(type=date)
|
||||
*/
|
||||
function wpcf7_is_date( $text ) {
|
||||
$result = preg_match( '/^([0-9]{4,})-([0-9]{2})-([0-9]{2})$/', $text, $matches );
|
||||
$result = preg_match(
|
||||
'/^([0-9]{4,})-([0-9]{2})-([0-9]{2})$/',
|
||||
$text,
|
||||
$matches
|
||||
);
|
||||
|
||||
if ( $result ) {
|
||||
$result = checkdate( $matches[2], $matches[3], $matches[1] );
|
||||
@@ -85,6 +89,32 @@ function wpcf7_is_date( $text ) {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks whether the given text is a valid time.
|
||||
*
|
||||
* @link https://html.spec.whatwg.org/multipage/input.html#time-state-(type=time)
|
||||
*/
|
||||
function wpcf7_is_time( $text ) {
|
||||
$result = preg_match(
|
||||
'/^([0-9]{2})\:([0-9]{2})(?:\:([0-9]{2}))?$/',
|
||||
$text,
|
||||
$matches
|
||||
);
|
||||
|
||||
if ( $result ) {
|
||||
$hour = (int) $matches[1];
|
||||
$minute = (int) $matches[2];
|
||||
$second = empty( $matches[3] ) ? 0 : (int) $matches[3];
|
||||
|
||||
$result = 0 <= $hour && $hour <= 23 &&
|
||||
0 <= $minute && $minute <= 59 &&
|
||||
0 <= $second && $second <= 59;
|
||||
}
|
||||
|
||||
return apply_filters( 'wpcf7_is_time', $result, $text );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks whether the given text is a well-formed mailbox list.
|
||||
*
|
||||
@@ -229,12 +259,23 @@ function wpcf7_is_file_path_in_content_dir( $path ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( 0 === strpos( $path, realpath( WP_CONTENT_DIR ) ) ) {
|
||||
if (
|
||||
str_starts_with( $path, trailingslashit( realpath( WP_CONTENT_DIR ) ) )
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( defined( 'UPLOADS' )
|
||||
and 0 === strpos( $path, realpath( ABSPATH . UPLOADS ) ) ) {
|
||||
if (
|
||||
defined( 'UPLOADS' ) and
|
||||
str_starts_with( $path, trailingslashit( realpath( ABSPATH . UPLOADS ) ) )
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (
|
||||
defined( 'WP_TEMP_DIR' ) and
|
||||
str_starts_with( $path, trailingslashit( realpath( WP_TEMP_DIR ) ) )
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ require_once WPCF7_PLUGIN_DIR . '/includes/validation.php';
|
||||
require_once WPCF7_PLUGIN_DIR . '/includes/submission.php';
|
||||
require_once WPCF7_PLUGIN_DIR . '/includes/upgrade.php';
|
||||
require_once WPCF7_PLUGIN_DIR . '/includes/integration.php';
|
||||
require_once WPCF7_PLUGIN_DIR . '/includes/config-validator.php';
|
||||
require_once WPCF7_PLUGIN_DIR . '/includes/config-validator/validator.php';
|
||||
require_once WPCF7_PLUGIN_DIR . '/includes/rest-api.php';
|
||||
require_once WPCF7_PLUGIN_DIR . '/includes/block-editor/block-editor.php';
|
||||
require_once WPCF7_PLUGIN_DIR . '/includes/html-formatter.php';
|
||||
@@ -110,10 +110,14 @@ class WPCF7 {
|
||||
* @param mixed $value Option value.
|
||||
*/
|
||||
public static function update_option( $name, $value ) {
|
||||
$option = get_option( 'wpcf7' );
|
||||
$option = ( false === $option ) ? array() : (array) $option;
|
||||
$option = array_merge( $option, array( $name => $value ) );
|
||||
update_option( 'wpcf7', $option );
|
||||
$old_option = get_option( 'wpcf7' );
|
||||
$old_option = ( false === $old_option ) ? array() : (array) $old_option;
|
||||
|
||||
update_option( 'wpcf7',
|
||||
array_merge( $old_option, array( $name => $value ) )
|
||||
);
|
||||
|
||||
do_action( 'wpcf7_update_option', $name, $value, $old_option );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -41,44 +41,43 @@ function wpcf7_akismet( $spam, $submission ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$c = array();
|
||||
|
||||
$c['comment_author'] = $params['author'];
|
||||
$c['comment_author_email'] = $params['author_email'];
|
||||
$c['comment_author_url'] = $params['author_url'];
|
||||
$c['comment_content'] = $params['content'];
|
||||
|
||||
$c['blog'] = get_option( 'home' );
|
||||
$c['blog_lang'] = get_locale();
|
||||
$c['blog_charset'] = get_option( 'blog_charset' );
|
||||
$c['user_ip'] = $_SERVER['REMOTE_ADDR'];
|
||||
$c['user_agent'] = $_SERVER['HTTP_USER_AGENT'];
|
||||
$c['referrer'] = $_SERVER['HTTP_REFERER'];
|
||||
$c['comment_type'] = 'contact-form';
|
||||
$comment = array(
|
||||
'comment_type' => 'contact-form',
|
||||
'comment_author' => $params['author'],
|
||||
'comment_author_email' => $params['author_email'],
|
||||
'comment_author_url' => $params['author_url'],
|
||||
'comment_content' => $params['content'],
|
||||
'blog' => home_url(),
|
||||
'blog_lang' => get_locale(),
|
||||
'blog_charset' => get_option( 'blog_charset' ),
|
||||
'user_ip' => $submission->get_meta( 'remote_ip' ),
|
||||
'user_agent' => $submission->get_meta( 'user_agent' ),
|
||||
'referrer' => isset( $_SERVER['HTTP_REFERER'] )
|
||||
? $_SERVER['HTTP_REFERER'] : '',
|
||||
);
|
||||
|
||||
$datetime = date_create_immutable(
|
||||
'@' . $submission->get_meta( 'timestamp' )
|
||||
);
|
||||
|
||||
if ( $datetime ) {
|
||||
$c['comment_date_gmt'] = $datetime->format( DATE_ATOM );
|
||||
$comment['comment_date_gmt'] = $datetime->format( DATE_ATOM );
|
||||
}
|
||||
|
||||
if ( $permalink = get_permalink() ) {
|
||||
$c['permalink'] = $permalink;
|
||||
$comment['permalink'] = $permalink;
|
||||
}
|
||||
|
||||
$ignore = array( 'HTTP_COOKIE', 'HTTP_COOKIE2', 'PHP_AUTH_PW' );
|
||||
$server_vars = array_diff_key(
|
||||
$_SERVER,
|
||||
array_flip( array( 'HTTP_COOKIE', 'HTTP_COOKIE2', 'PHP_AUTH_PW' ) )
|
||||
);
|
||||
|
||||
foreach ( $_SERVER as $key => $value ) {
|
||||
if ( ! in_array( $key, (array) $ignore ) ) {
|
||||
$c["$key"] = $value;
|
||||
}
|
||||
}
|
||||
$comment = array_merge( $comment, $server_vars );
|
||||
|
||||
$c = apply_filters( 'wpcf7_akismet_parameters', $c );
|
||||
$comment = apply_filters( 'wpcf7_akismet_parameters', $comment );
|
||||
|
||||
if ( wpcf7_akismet_comment_check( $c ) ) {
|
||||
if ( wpcf7_akismet_comment_check( $comment ) ) {
|
||||
$spam = true;
|
||||
|
||||
$submission->add_spam_log( array(
|
||||
|
||||
@@ -1 +1 @@
|
||||
document.addEventListener("DOMContentLoaded",(t=>{var e;wpcf7_recaptcha={...null!==(e=wpcf7_recaptcha)&&void 0!==e?e:{}};const c=wpcf7_recaptcha.sitekey,{homepage:n,contactform:a}=wpcf7_recaptcha.actions,o=t=>{const{action:e,func:n,params:a}=t;grecaptcha.execute(c,{action:e}).then((t=>{const c=new CustomEvent("wpcf7grecaptchaexecuted",{detail:{action:e,token:t}});document.dispatchEvent(c)})).then((()=>{"function"==typeof n&&n(...a)})).catch((t=>console.error(t)))};if(grecaptcha.ready((()=>{o({action:n})})),document.addEventListener("change",(t=>{o({action:a})})),"undefined"!=typeof wpcf7&&"function"==typeof wpcf7.submit){const t=wpcf7.submit;wpcf7.submit=function(e){let c=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};o({action:a,func:t,params:[e,c]})}}document.addEventListener("wpcf7grecaptchaexecuted",(t=>{const e=document.querySelectorAll('form.wpcf7-form input[name="_wpcf7_recaptcha_response"]');for(let c=0;c<e.length;c++)e[c].setAttribute("value",t.detail.token)}))}));
|
||||
document.addEventListener("DOMContentLoaded",(t=>{var e;wpcf7_recaptcha={...null!==(e=wpcf7_recaptcha)&&void 0!==e?e:{}};const c=wpcf7_recaptcha.sitekey,{homepage:n,contactform:a}=wpcf7_recaptcha.actions,o=t=>{const{action:e,func:n,params:a}=t;grecaptcha.execute(c,{action:e}).then((t=>{const c=new CustomEvent("wpcf7grecaptchaexecuted",{detail:{action:e,token:t}});document.dispatchEvent(c)})).then((()=>{"function"==typeof n&&n(...a)})).catch((t=>console.error(t)))};if(grecaptcha.ready((()=>{o({action:n})})),document.addEventListener("change",(t=>{o({action:a})})),"undefined"!=typeof wpcf7&&"function"==typeof wpcf7.submit){const t=wpcf7.submit;wpcf7.submit=function(e){o({action:a,func:t,params:[e,arguments.length>1&&void 0!==arguments[1]?arguments[1]:{}]})}}document.addEventListener("wpcf7grecaptchaexecuted",(t=>{const e=document.querySelectorAll('form.wpcf7-form input[name="_wpcf7_recaptcha_response"]');for(let c=0;c<e.length;c++)e[c].setAttribute("value",t.detail.token)}))}));
|
||||
@@ -98,7 +98,7 @@ function wpcf7_sendinblue_editor_panels( $panels ) {
|
||||
),
|
||||
wpcf7_link(
|
||||
__( 'https://contactform7.com/sendinblue-integration/', 'contact-form-7' ),
|
||||
__( 'Brevo (formerly Sendinblue) integration', 'contact-form-7' )
|
||||
__( 'Brevo integration', 'contact-form-7' )
|
||||
)
|
||||
);
|
||||
|
||||
@@ -106,7 +106,7 @@ function wpcf7_sendinblue_editor_panels( $panels ) {
|
||||
$templates = $service->get_templates();
|
||||
|
||||
?>
|
||||
<h2><?php echo esc_html( __( 'Brevo (formerly Sendinblue)', 'contact-form-7' ) ); ?></h2>
|
||||
<h2><?php echo esc_html( __( 'Brevo', 'contact-form-7' ) ); ?></h2>
|
||||
|
||||
<fieldset>
|
||||
<legend><?php echo $description; ?></legend>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
* Brevo (formerly Sendinblue) module main file
|
||||
* Brevo module main file
|
||||
*
|
||||
* @link https://contactform7.com/sendinblue-integration/
|
||||
*/
|
||||
|
||||
@@ -27,7 +27,7 @@ class WPCF7_Sendinblue extends WPCF7_Service {
|
||||
}
|
||||
|
||||
public function get_title() {
|
||||
return __( 'Brevo (formerly Sendinblue)', 'contact-form-7' );
|
||||
return __( 'Brevo', 'contact-form-7' );
|
||||
}
|
||||
|
||||
public function is_active() {
|
||||
@@ -47,7 +47,7 @@ class WPCF7_Sendinblue extends WPCF7_Service {
|
||||
|
||||
public function link() {
|
||||
echo wpcf7_link(
|
||||
'https://www.brevo.com/?tap_a=30591-fb13f0&tap_s=1031580-b1bb1d',
|
||||
'https://www.brevo.com/',
|
||||
'brevo.com'
|
||||
);
|
||||
}
|
||||
@@ -153,7 +153,7 @@ class WPCF7_Sendinblue extends WPCF7_Service {
|
||||
'<p><strong>%s</strong></p>',
|
||||
wpcf7_link(
|
||||
__( 'https://contactform7.com/sendinblue-integration/', 'contact-form-7' ),
|
||||
__( 'Brevo (formerly Sendinblue) integration', 'contact-form-7' )
|
||||
__( 'Brevo integration', 'contact-form-7' )
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
*/
|
||||
class WPCF7_Stripe_API {
|
||||
|
||||
const api_version = '2022-08-01';
|
||||
const api_version = '2022-11-15';
|
||||
const partner_id = 'pp_partner_HHbvqLh1AaO7Am';
|
||||
const app_name = 'WordPress Contact Form 7';
|
||||
const app_url = 'https://contactform7.com/stripe-integration/';
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
Contributors: takayukister
|
||||
Donate link: https://contactform7.com/donate/
|
||||
Tags: contact, form, contact form, feedback, email, ajax, captcha, akismet, multilingual
|
||||
Requires at least: 6.0
|
||||
Tested up to: 6.2
|
||||
Stable tag: 5.7.7
|
||||
Requires at least: 6.2
|
||||
Requires PHP: 7.4
|
||||
Tested up to: 6.3
|
||||
Stable tag: 5.8.1
|
||||
License: GPLv2 or later
|
||||
License URI: https://www.gnu.org/licenses/gpl-2.0.html
|
||||
|
||||
@@ -36,7 +37,7 @@ If you activate certain features in this plugin, the contact form submitter's pe
|
||||
* reCAPTCHA ([Google](https://policies.google.com/?hl=en))
|
||||
* Akismet ([Automattic](https://automattic.com/privacy/))
|
||||
* Constant Contact ([Endurance International Group](https://www.endurance.com/privacy))
|
||||
* [Brevo (formerly Sendinblue)](https://www.brevo.com/legal/privacypolicy/)
|
||||
* [Brevo](https://www.brevo.com/legal/privacypolicy/)
|
||||
* [Stripe](https://stripe.com/privacy)
|
||||
|
||||
= Recommended plugins =
|
||||
@@ -77,6 +78,14 @@ Do you have questions or issues with Contact Form 7? Use these support channels
|
||||
|
||||
For more information, see [Releases](https://contactform7.com/category/releases/).
|
||||
|
||||
= 5.8.1 =
|
||||
|
||||
[https://contactform7.com/contact-form-7-581/](https://contactform7.com/contact-form-7-581/)
|
||||
|
||||
= 5.8 =
|
||||
|
||||
[https://contactform7.com/contact-form-7-58/](https://contactform7.com/contact-form-7-58/)
|
||||
|
||||
= 5.7.7 =
|
||||
|
||||
[https://contactform7.com/contact-form-7-577/](https://contactform7.com/contact-form-7-577/)
|
||||
@@ -113,24 +122,4 @@ For more information, see [Releases](https://contactform7.com/category/releases/
|
||||
|
||||
[https://contactform7.com/contact-form-7-57/](https://contactform7.com/contact-form-7-57/)
|
||||
|
||||
= 5.6.4 =
|
||||
|
||||
[https://contactform7.com/contact-form-7-564/](https://contactform7.com/contact-form-7-564/)
|
||||
|
||||
= 5.6.3 =
|
||||
|
||||
[https://contactform7.com/contact-form-7-563/](https://contactform7.com/contact-form-7-563/)
|
||||
|
||||
= 5.6.2 =
|
||||
|
||||
[https://contactform7.com/contact-form-7-562/](https://contactform7.com/contact-form-7-562/)
|
||||
|
||||
= 5.6.1 =
|
||||
|
||||
[https://contactform7.com/contact-form-7-561/](https://contactform7.com/contact-form-7-561/)
|
||||
|
||||
= 5.6 =
|
||||
|
||||
[https://contactform7.com/contact-form-7-56/](https://contactform7.com/contact-form-7-56/)
|
||||
|
||||
== Upgrade Notice ==
|
||||
|
||||
@@ -1,18 +1,20 @@
|
||||
<?php
|
||||
/*
|
||||
Plugin Name: Contact Form 7
|
||||
Plugin URI: https://contactform7.com/
|
||||
Description: Just another contact form plugin. Simple but flexible.
|
||||
Author: Takayuki Miyoshi
|
||||
Author URI: https://ideasilo.wordpress.com/
|
||||
Text Domain: contact-form-7
|
||||
Domain Path: /languages/
|
||||
Version: 5.7.7
|
||||
*/
|
||||
* Plugin Name: Contact Form 7
|
||||
* Plugin URI: https://contactform7.com/
|
||||
* Description: Just another contact form plugin. Simple but flexible.
|
||||
* Author: Takayuki Miyoshi
|
||||
* Author URI: https://ideasilo.wordpress.com/
|
||||
* License: GPL v2 or later
|
||||
* License URI: https://www.gnu.org/licenses/gpl-2.0.html
|
||||
* Version: 5.8.1
|
||||
* Requires at least: 6.2
|
||||
* Requires PHP: 7.4
|
||||
*/
|
||||
|
||||
define( 'WPCF7_VERSION', '5.7.7' );
|
||||
define( 'WPCF7_VERSION', '5.8.1' );
|
||||
|
||||
define( 'WPCF7_REQUIRED_WP_VERSION', '6.0' );
|
||||
define( 'WPCF7_REQUIRED_WP_VERSION', '6.2' );
|
||||
|
||||
define( 'WPCF7_TEXT_DOMAIN', 'contact-form-7' );
|
||||
|
||||
|
||||
6
wp/wp-content/plugins/imagify/SECURITY.md
Normal file
6
wp/wp-content/plugins/imagify/SECURITY.md
Normal file
@@ -0,0 +1,6 @@
|
||||
# Security Policy
|
||||
|
||||
## Reporting Security Bugs
|
||||
|
||||
Please report security bugs found in the site-reviews plugin's source code through the [Patchstack Vulnerability Disclosure Program](https://patchstack.com/database/vdp/imagify). The Patchstack team will assist you with verification, CVE assignment and take care of notifying the developers of this plugin.
|
||||
---
|
||||
@@ -1125,4 +1125,15 @@ window.imagify = window.imagify || {};
|
||||
|
||||
w.imagify.bulk.init();
|
||||
|
||||
if (imagifyBulk.isOverQuota) {
|
||||
w.imagify.bulk.displayError( {
|
||||
title: imagifyBulk.labels.overQuotaTitle,
|
||||
html: $( '#tmpl-imagify-overquota-alert' ).html(),
|
||||
type: 'info',
|
||||
customClass: 'imagify-swal-has-subtitle imagify-swal-error-header',
|
||||
showConfirmButton: false
|
||||
} );
|
||||
}
|
||||
|
||||
|
||||
} )(jQuery, document, window);
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -413,13 +413,14 @@ class Bulk {
|
||||
*
|
||||
* @since 1.9
|
||||
*
|
||||
* @param string $method The method used: 'GET' (default), or 'POST'.
|
||||
* @param string $parameter The name of the parameter to look for.
|
||||
* @param string $method The method used: 'GET' (default), or 'POST'.
|
||||
* @param string $parameter The name of the parameter to look for.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_context( $method = 'GET', $parameter = 'context' ) {
|
||||
$method = 'POST' === $method ? INPUT_POST : INPUT_GET;
|
||||
$context = filter_input( $method, $parameter, FILTER_SANITIZE_STRING );
|
||||
$context = 'POST' === $method ? wp_unslash( $_POST[ $parameter ] ) : wp_unslash( $_GET[ $parameter ] ); //phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.NonceVerification.Recommended
|
||||
$context = htmlspecialchars( $context );
|
||||
|
||||
return imagify_sanitize_context( $context );
|
||||
}
|
||||
@@ -557,7 +558,7 @@ class Bulk {
|
||||
public function bulk_get_stats_callback() {
|
||||
imagify_check_nonce( 'imagify-bulk-optimize' );
|
||||
|
||||
$folder_types = filter_input( INPUT_GET, 'types', FILTER_SANITIZE_STRING, FILTER_REQUIRE_ARRAY );
|
||||
$folder_types = filter_input( INPUT_GET, 'types', FILTER_REQUIRE_ARRAY );
|
||||
$folder_types = is_array( $folder_types ) ? array_filter( $folder_types, 'is_string' ) : [];
|
||||
|
||||
if ( ! $folder_types ) {
|
||||
|
||||
@@ -95,6 +95,7 @@ class CustomFolders extends AbstractBulk {
|
||||
$files_table = Imagify_Files_DB::get_instance()->get_table_name();
|
||||
$folders_table = Imagify_Folders_DB::get_instance()->get_table_name();
|
||||
$mime_types = Imagify_DB::get_mime_types( 'image' );
|
||||
$mime_types = str_replace( ",'image/webp'", '', $mime_types );
|
||||
$webp_suffix = constant( imagify_get_optimization_process_class_name( 'custom-folders' ) . '::WEBP_SUFFIX' );
|
||||
$files = $wpdb->get_results( $wpdb->prepare( // WPCS: unprepared SQL ok.
|
||||
"
|
||||
|
||||
@@ -184,6 +184,7 @@ class WP extends AbstractBulk {
|
||||
$this->set_no_time_limit();
|
||||
|
||||
$mime_types = Imagify_DB::get_mime_types( 'image' );
|
||||
$mime_types = str_replace( ",'image/webp'", '', $mime_types );
|
||||
$statuses = Imagify_DB::get_post_statuses();
|
||||
$nodata_join = Imagify_DB::get_required_wp_metadata_join_clause();
|
||||
$nodata_where = Imagify_DB::get_required_wp_metadata_where_clause( [
|
||||
|
||||
@@ -4,6 +4,7 @@ declare(strict_types=1);
|
||||
namespace Imagify\Notices;
|
||||
|
||||
use Imagify\Traits\InstanceGetterTrait;
|
||||
use Imagify\User\User;
|
||||
|
||||
/**
|
||||
* Class that handles the admin notices.
|
||||
@@ -467,7 +468,7 @@ class Notices {
|
||||
return $display;
|
||||
}
|
||||
|
||||
$user = new \Imagify_User();
|
||||
$user = new User();
|
||||
|
||||
// Don't display the notice if the user's unconsumed quota is superior to 20%.
|
||||
if ( $user->get_percent_unconsumed_quota() > 20 ) {
|
||||
|
||||
266
wp/wp-content/plugins/imagify/classes/User/User.php
Normal file
266
wp/wp-content/plugins/imagify/classes/User/User.php
Normal file
@@ -0,0 +1,266 @@
|
||||
<?php
|
||||
namespace Imagify\User;
|
||||
|
||||
use Date;
|
||||
use Imagify_Data;
|
||||
use WP_Error;
|
||||
|
||||
/**
|
||||
* Imagify User class.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
class User {
|
||||
/**
|
||||
* The Imagify user ID.
|
||||
*
|
||||
* @since 1.0
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $id;
|
||||
|
||||
/**
|
||||
* The user email.
|
||||
*
|
||||
* @since 1.0
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $email;
|
||||
|
||||
/**
|
||||
* The plan ID.
|
||||
*
|
||||
* @since 1.0
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $plan_id;
|
||||
|
||||
/**
|
||||
* The plan label.
|
||||
*
|
||||
* @since 1.2
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $plan_label;
|
||||
|
||||
/**
|
||||
* The total quota.
|
||||
*
|
||||
* @since 1.0
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $quota;
|
||||
|
||||
/**
|
||||
* The total extra quota (Imagify Pack).
|
||||
*
|
||||
* @since 1.0
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $extra_quota;
|
||||
|
||||
/**
|
||||
* The extra quota consumed.
|
||||
*
|
||||
* @since 1.0
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $extra_quota_consumed;
|
||||
|
||||
/**
|
||||
* The current month consumed quota.
|
||||
*
|
||||
* @since 1.0
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $consumed_current_month_quota;
|
||||
|
||||
/**
|
||||
* The next month date to credit the account.
|
||||
*
|
||||
* @since 1.1.1
|
||||
*
|
||||
* @var Date
|
||||
*/
|
||||
public $next_date_update;
|
||||
|
||||
/**
|
||||
* If the account is activate or not.
|
||||
*
|
||||
* @since 1.0.1
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $is_active;
|
||||
|
||||
/**
|
||||
* Store a \WP_Error object if the request to fetch the user data failed.
|
||||
* False overwise.
|
||||
*
|
||||
* @var bool|WP_Error
|
||||
* @since 1.9.9
|
||||
*/
|
||||
private $error;
|
||||
|
||||
/**
|
||||
* The constructor.
|
||||
*
|
||||
* @since 1.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct() {
|
||||
$user = get_imagify_user();
|
||||
|
||||
if ( is_wp_error( $user ) ) {
|
||||
$this->error = $user;
|
||||
return;
|
||||
}
|
||||
|
||||
$this->id = $user->id;
|
||||
$this->email = $user->email;
|
||||
$this->plan_id = (int) $user->plan_id;
|
||||
$this->plan_label = ucfirst( $user->plan_label );
|
||||
$this->quota = $user->quota;
|
||||
$this->extra_quota = $user->extra_quota;
|
||||
$this->extra_quota_consumed = $user->extra_quota_consumed;
|
||||
$this->consumed_current_month_quota = $user->consumed_current_month_quota;
|
||||
$this->next_date_update = $user->next_date_update;
|
||||
$this->is_active = $user->is_active;
|
||||
$this->error = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the possible error returned when fetching user data.
|
||||
*
|
||||
* @return bool|WP_Error A \WP_Error object if the request to fetch the user data failed. False overwise.
|
||||
* @since 1.9.9
|
||||
*/
|
||||
public function get_error() {
|
||||
return $this->error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Percentage of consumed quota, including extra quota.
|
||||
*
|
||||
* @since 1.0
|
||||
*
|
||||
* @return float|int
|
||||
*/
|
||||
public function get_percent_consumed_quota() {
|
||||
static $done = false;
|
||||
|
||||
if ( $this->get_error() ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$quota = $this->quota;
|
||||
$consumed_quota = $this->consumed_current_month_quota;
|
||||
|
||||
if ( imagify_round_half_five( $this->extra_quota_consumed ) < $this->extra_quota ) {
|
||||
$quota += $this->extra_quota;
|
||||
$consumed_quota += $this->extra_quota_consumed;
|
||||
}
|
||||
|
||||
if ( ! $quota || ! $consumed_quota ) {
|
||||
$percent = 0;
|
||||
} else {
|
||||
$percent = 100 * $consumed_quota / $quota;
|
||||
$percent = round( $percent, 1 );
|
||||
$percent = min( max( 0, $percent ), 100 );
|
||||
}
|
||||
|
||||
$percent = (float) $percent;
|
||||
|
||||
if ( $done ) {
|
||||
return $percent;
|
||||
}
|
||||
|
||||
$previous_percent = Imagify_Data::get_instance()->get( 'previous_quota_percent' );
|
||||
|
||||
// Percent is not 100% anymore.
|
||||
if ( 100.0 === (float) $previous_percent && $percent < 100 ) {
|
||||
/**
|
||||
* Triggered when the consumed quota percent decreases below 100%.
|
||||
*
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @param float|int $percent The current percentage of consumed quota.
|
||||
*/
|
||||
do_action( 'imagify_not_over_quota_anymore', $percent );
|
||||
}
|
||||
|
||||
// Percent is not >= 80% anymore.
|
||||
if ( ( (float) $previous_percent >= 80.0 && $percent < 80 ) ) {
|
||||
/**
|
||||
* Triggered when the consumed quota percent decreases below 80%.
|
||||
*
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @param float|int $percent The current percentage of consumed quota.
|
||||
* @param float|int $previous_percent The previous percentage of consumed quota.
|
||||
*/
|
||||
do_action( 'imagify_not_almost_over_quota_anymore', $percent, $previous_percent );
|
||||
}
|
||||
|
||||
if ( (float) $previous_percent !== (float) $percent ) {
|
||||
Imagify_Data::get_instance()->set( 'previous_quota_percent', $percent );
|
||||
}
|
||||
|
||||
$done = true;
|
||||
|
||||
return $percent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Count percent of unconsumed quota.
|
||||
*
|
||||
* @since 1.0
|
||||
*
|
||||
* @return float|int
|
||||
*/
|
||||
public function get_percent_unconsumed_quota() {
|
||||
return 100 - $this->get_percent_consumed_quota();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the user has a free account.
|
||||
*
|
||||
* @since 1.1.1
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_free() {
|
||||
return 1 === $this->plan_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the user has consumed all his/her quota.
|
||||
*
|
||||
* @since 1.1.1
|
||||
* @since 1.9.9 Return false if the request to fetch the user data failed.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_over_quota() {
|
||||
if ( $this->get_error() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (
|
||||
$this->is_free()
|
||||
&&
|
||||
floatval( 100 ) === round( $this->get_percent_consumed_quota() )
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ namespace Imagify\Webp\RewriteRules;
|
||||
|
||||
use Imagify\Notices\Notices;
|
||||
use Imagify\Traits\InstanceGetterTrait;
|
||||
use Imagify\WriteFile\AbstractWriteDirConfFile;
|
||||
|
||||
/**
|
||||
* Display WebP images on the site with rewrite rules.
|
||||
@@ -12,6 +13,13 @@ use Imagify\Traits\InstanceGetterTrait;
|
||||
class Display {
|
||||
use InstanceGetterTrait;
|
||||
|
||||
/**
|
||||
* Configuration file writer.
|
||||
*
|
||||
* @var AbstractWriteDirConfFile
|
||||
*/
|
||||
protected $server_conf;
|
||||
|
||||
/**
|
||||
* Option value.
|
||||
*
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Plugin Name: Imagify
|
||||
* Plugin URI: https://wordpress.org/plugins/imagify/
|
||||
* Description: Dramatically reduce image file sizes without losing quality, make your website load faster, boost your SEO and save money on your bandwidth using Imagify, the new most advanced image optimization tool.
|
||||
* Version: 2.1.1
|
||||
* Version: 2.1.2
|
||||
* Requires at least: 5.3
|
||||
* Requires PHP: 7.0
|
||||
* Author: Imagify – Optimize Images & Convert WebP
|
||||
@@ -13,13 +13,13 @@
|
||||
* Text Domain: imagify
|
||||
* Domain Path: languages
|
||||
*
|
||||
* Copyright 2022 WP Media
|
||||
* Copyright 2023 WP Media
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || die( 'Cheatin’ uh?' );
|
||||
|
||||
// Imagify defines.
|
||||
define( 'IMAGIFY_VERSION', '2.1.1' );
|
||||
define( 'IMAGIFY_VERSION', '2.1.2' );
|
||||
define( 'IMAGIFY_SLUG', 'imagify' );
|
||||
define( 'IMAGIFY_FILE', __FILE__ );
|
||||
define( 'IMAGIFY_PATH', realpath( plugin_dir_path( IMAGIFY_FILE ) ) . '/' );
|
||||
|
||||
@@ -123,7 +123,9 @@ function _imagify_sort_attachments_by_status( $vars ) {
|
||||
),
|
||||
) );
|
||||
|
||||
$vars['post_mime_type'] = imagify_get_mime_types();
|
||||
if ( ! key_exists( 'post_mime_type', $vars ) ) {
|
||||
$vars['post_mime_type'] = imagify_get_mime_types();
|
||||
}
|
||||
|
||||
return $vars;
|
||||
}
|
||||
|
||||
@@ -18,6 +18,13 @@ abstract class Imagify_Abstract_Background_Process extends Imagify_WP_Background
|
||||
*/
|
||||
protected $prefix = 'imagify';
|
||||
|
||||
/**
|
||||
* URL to query on.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $query_url = '';
|
||||
|
||||
/**
|
||||
* Set to true to automatically displatch at the end of the page.
|
||||
*
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
use Imagify\Traits\InstanceGetterTrait;
|
||||
use Imagify\User\User;
|
||||
|
||||
/**
|
||||
* Class that handles admin ajax/post callbacks.
|
||||
@@ -220,13 +221,13 @@ class Imagify_Admin_Ajax_Post extends Imagify_Admin_Ajax_Post_Deprecated {
|
||||
$process = imagify_get_optimization_process( $media_id, $context );
|
||||
|
||||
if ( ! $process->is_valid() ) {
|
||||
return new \WP_Error( 'invalid_media', __( 'This media is not valid.', 'imagify' ) );
|
||||
return new WP_Error( 'invalid_media', __( 'This media is not valid.', 'imagify' ) );
|
||||
}
|
||||
|
||||
$data = $process->get_data();
|
||||
|
||||
if ( ! $data->is_already_optimized() ) {
|
||||
return new \WP_Error( 'not_already_optimized', __( 'This media does not have the right optimization status.', 'imagify' ) );
|
||||
return new WP_Error( 'not_already_optimized', __( 'This media does not have the right optimization status.', 'imagify' ) );
|
||||
}
|
||||
|
||||
if ( ! $process->has_webp() ) {
|
||||
@@ -237,7 +238,7 @@ class Imagify_Admin_Ajax_Post extends Imagify_Admin_Ajax_Post_Deprecated {
|
||||
$deleted = $process->delete_webp_files();
|
||||
|
||||
if ( is_wp_error( $deleted ) ) {
|
||||
return new \WP_Error( 'webp_not_deleted', __( 'Previous WebP files could not be deleted.', 'imagify' ) );
|
||||
return new WP_Error( 'webp_not_deleted', __( 'Previous WebP files could not be deleted.', 'imagify' ) );
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -841,7 +842,7 @@ class Imagify_Admin_Ajax_Post extends Imagify_Admin_Ajax_Post_Deprecated {
|
||||
imagify_die();
|
||||
}
|
||||
|
||||
$user = new Imagify_User();
|
||||
$user = new User();
|
||||
$views = Imagify_Views::get_instance();
|
||||
$unconsumed_quota = $views->get_quota_percent();
|
||||
$message = '';
|
||||
@@ -1148,7 +1149,7 @@ class Imagify_Admin_Ajax_Post extends Imagify_Admin_Ajax_Post_Deprecated {
|
||||
imagify_die();
|
||||
}
|
||||
|
||||
$notice = filter_input( INPUT_GET, 'ad', FILTER_SANITIZE_STRING );
|
||||
$notice = htmlspecialchars( wp_unslash( $_GET['ad'] ) );
|
||||
|
||||
if ( ! $notice ) {
|
||||
imagify_maybe_redirect();
|
||||
@@ -1215,8 +1216,8 @@ class Imagify_Admin_Ajax_Post extends Imagify_Admin_Ajax_Post_Deprecated {
|
||||
* @return string
|
||||
*/
|
||||
public function get_context( $method = 'GET', $parameter = 'context' ) {
|
||||
$method = 'POST' === $method ? INPUT_POST : INPUT_GET;
|
||||
$context = filter_input( $method, $parameter, FILTER_SANITIZE_STRING );
|
||||
$context = 'POST' === $method ? wp_unslash( $_POST[ $parameter ] ) : wp_unslash( $_GET[ $parameter ] ); // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.NonceVerification.Recommended
|
||||
$context = htmlspecialchars( $context );
|
||||
|
||||
return imagify_sanitize_context( $context );
|
||||
}
|
||||
@@ -1246,14 +1247,15 @@ class Imagify_Admin_Ajax_Post extends Imagify_Admin_Ajax_Post_Deprecated {
|
||||
*
|
||||
* @since 1.9
|
||||
*
|
||||
* @param string $method The method used: 'GET' (default), or 'POST'.
|
||||
* @param string $parameter The name of the parameter to look for.
|
||||
* @param string $method The method used: 'GET' (default), or 'POST'.
|
||||
* @param string $parameter The name of the parameter to look for.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_folder_type( $method = 'GET', $parameter = 'folder_type' ) {
|
||||
$method = 'POST' === $method ? INPUT_POST : INPUT_GET;
|
||||
$folder_type = 'POST' === $method ? wp_unslash( $_POST[ $parameter ] ) : wp_unslash( $_GET[ $parameter ] ); // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.NonceVerification.Recommended
|
||||
|
||||
return filter_input( $method, $parameter, FILTER_SANITIZE_STRING );
|
||||
return htmlspecialchars( $folder_type );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1261,13 +1263,14 @@ class Imagify_Admin_Ajax_Post extends Imagify_Admin_Ajax_Post_Deprecated {
|
||||
*
|
||||
* @since 1.9
|
||||
*
|
||||
* @param string $method The method used: 'GET' (default), or 'POST'.
|
||||
* @param string $parameter The name of the parameter to look for.
|
||||
* @param string $method The method used: 'GET' (default), or 'POST'.
|
||||
* @param string $parameter The name of the parameter to look for.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_imagify_action( $method = 'GET', $parameter = 'imagify_action' ) {
|
||||
$method = 'POST' === $method ? INPUT_POST : INPUT_GET;
|
||||
$action = filter_input( $method, $parameter, FILTER_SANITIZE_STRING );
|
||||
$action = 'POST' === $method ? wp_unslash( $_POST[ $parameter ] ) : wp_unslash( $_GET[ $parameter ] ); // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.NonceVerification.Recommended
|
||||
$action = htmlspecialchars( $action );
|
||||
|
||||
return $action ? $action : 'optimize';
|
||||
}
|
||||
|
||||
@@ -4,62 +4,54 @@ defined( 'ABSPATH' ) || die( 'Cheatin’ uh?' );
|
||||
/**
|
||||
* Class that display the "custom folders" files.
|
||||
*
|
||||
* @package Imagify
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
* @since 1.7
|
||||
*/
|
||||
class Imagify_Files_List_Table extends WP_List_Table {
|
||||
|
||||
/**
|
||||
* Class version.
|
||||
*
|
||||
* @var string
|
||||
* @var string
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
*/
|
||||
const VERSION = '1.1';
|
||||
|
||||
/**
|
||||
* Class version.
|
||||
*
|
||||
* @var string
|
||||
* @var string
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
*/
|
||||
const PER_PAGE_OPTION = 'imagify_files_per_page';
|
||||
|
||||
/**
|
||||
* List of the folders containing the listed files.
|
||||
*
|
||||
* @var array
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
* @var array
|
||||
* @since 1.7
|
||||
*/
|
||||
protected $folders = array();
|
||||
|
||||
/**
|
||||
* Filesystem object.
|
||||
*
|
||||
* @var object Imagify_Filesystem
|
||||
* @since 1.7.1
|
||||
* @author Grégory Viguier
|
||||
* @var Imagify_Filesystem
|
||||
* @since 1.7.1
|
||||
*/
|
||||
protected $filesystem;
|
||||
|
||||
/**
|
||||
* Views object.
|
||||
*
|
||||
* @var object Imagify_Views
|
||||
* @since 1.9
|
||||
* @author Grégory Viguier
|
||||
* @var Imagify_Views
|
||||
* @since 1.9
|
||||
*/
|
||||
protected $views;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
* @since 1.7
|
||||
*
|
||||
* @param array $args An associative array of arguments.
|
||||
*/
|
||||
@@ -80,8 +72,7 @@ class Imagify_Files_List_Table extends WP_List_Table {
|
||||
/**
|
||||
* Prepares the list of items for displaying.
|
||||
*
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
* @since 1.7
|
||||
*/
|
||||
public function prepare_items() {
|
||||
global $wpdb;
|
||||
@@ -108,8 +99,8 @@ class Imagify_Files_List_Table extends WP_List_Table {
|
||||
$file_ids = array();
|
||||
$where = '';
|
||||
|
||||
$sent_orderby = filter_input( INPUT_GET, 'orderby', FILTER_SANITIZE_STRING );
|
||||
$sent_order = filter_input( INPUT_GET, 'order', FILTER_SANITIZE_STRING );
|
||||
$sent_orderby = isset( $_GET['orderby'] ) ? htmlspecialchars( wp_unslash( $_GET['orderby'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.NonceVerification.Recommended
|
||||
$sent_order = isset( $_GET['order'] ) ? htmlspecialchars( wp_unslash( $_GET['order'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.NonceVerification.Recommended
|
||||
$folder_filter = self::get_folder_filter();
|
||||
$status_filter = self::get_status_filter();
|
||||
|
||||
@@ -227,8 +218,7 @@ class Imagify_Files_List_Table extends WP_List_Table {
|
||||
/**
|
||||
* Message to be displayed when there are no items.
|
||||
*
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
* @since 1.7
|
||||
*/
|
||||
public function no_items() {
|
||||
if ( self::get_status_filter() ) {
|
||||
@@ -295,8 +285,7 @@ class Imagify_Files_List_Table extends WP_List_Table {
|
||||
/**
|
||||
* Display views.
|
||||
*
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
* @since 1.7
|
||||
*/
|
||||
public function views() {
|
||||
global $wpdb;
|
||||
@@ -412,8 +401,7 @@ class Imagify_Files_List_Table extends WP_List_Table {
|
||||
/**
|
||||
* Get an associative array ( option_name => option_title ) with the list of bulk actions available on this table.
|
||||
*
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
* @since 1.7
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@@ -427,8 +415,7 @@ class Imagify_Files_List_Table extends WP_List_Table {
|
||||
* Get a list of columns. The format is:
|
||||
* 'internal-name' => 'Title'
|
||||
*
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
* @since 1.7
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@@ -452,8 +439,7 @@ class Imagify_Files_List_Table extends WP_List_Table {
|
||||
*
|
||||
* The second format will make the initial sorting order be descending.
|
||||
*
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
* @since 1.7
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@@ -469,8 +455,7 @@ class Imagify_Files_List_Table extends WP_List_Table {
|
||||
/**
|
||||
* Get a column contents.
|
||||
*
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
* @since 1.7
|
||||
*
|
||||
* @param string $column The column "name": "cb", "title", "optimization_level", etc.
|
||||
* @param object $item The current item. It must contain at least a $process property.
|
||||
@@ -489,8 +474,7 @@ class Imagify_Files_List_Table extends WP_List_Table {
|
||||
/**
|
||||
* Handles the checkbox column output.
|
||||
*
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
* @since 1.7
|
||||
*
|
||||
* @param object $item The current item. It must contain at least a $process property.
|
||||
*/
|
||||
@@ -505,8 +489,7 @@ class Imagify_Files_List_Table extends WP_List_Table {
|
||||
/**
|
||||
* Handles the title column output.
|
||||
*
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
* @since 1.7
|
||||
*
|
||||
* @param object $item The current item. It must contain at least a $process property.
|
||||
*/
|
||||
@@ -555,8 +538,7 @@ class Imagify_Files_List_Table extends WP_List_Table {
|
||||
/**
|
||||
* Handles the parent folder column output.
|
||||
*
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
* @since 1.7
|
||||
*
|
||||
* @param object $item The current item. It must contain at least a $process property.
|
||||
*/
|
||||
@@ -590,8 +572,7 @@ class Imagify_Files_List_Table extends WP_List_Table {
|
||||
/**
|
||||
* Handles the optimization data column output.
|
||||
*
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
* @since 1.7
|
||||
*
|
||||
* @param object $item The current item. It must contain at least a $process property.
|
||||
*/
|
||||
@@ -642,8 +623,7 @@ class Imagify_Files_List_Table extends WP_List_Table {
|
||||
/**
|
||||
* Handles the status column output.
|
||||
*
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
* @since 1.7
|
||||
*
|
||||
* @param object $item The current item. It must contain at least a $process property.
|
||||
*/
|
||||
@@ -677,8 +657,7 @@ class Imagify_Files_List_Table extends WP_List_Table {
|
||||
/**
|
||||
* Handles the optimization level column output.
|
||||
*
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
* @since 1.7
|
||||
*
|
||||
* @param object $item The current item. It must contain at least a $process property.
|
||||
*/
|
||||
@@ -693,8 +672,7 @@ class Imagify_Files_List_Table extends WP_List_Table {
|
||||
/**
|
||||
* Handles the actions column output.
|
||||
*
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
* @since 1.7
|
||||
*
|
||||
* @param object $item The current item. It must contain at least a $process property.
|
||||
*/
|
||||
@@ -730,8 +708,7 @@ class Imagify_Files_List_Table extends WP_List_Table {
|
||||
/**
|
||||
* Prints a button to optimize the file.
|
||||
*
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
* @since 1.7
|
||||
*
|
||||
* @param object $item The current item. It must contain at least a $process property.
|
||||
*/
|
||||
@@ -758,8 +735,7 @@ class Imagify_Files_List_Table extends WP_List_Table {
|
||||
/**
|
||||
* Prints a button to retry to optimize the file.
|
||||
*
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
* @since 1.7
|
||||
*
|
||||
* @param object $item The current item. It must contain at least a $process property.
|
||||
*/
|
||||
@@ -789,8 +765,7 @@ class Imagify_Files_List_Table extends WP_List_Table {
|
||||
/**
|
||||
* Prints buttons to re-optimize the file to other levels.
|
||||
*
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
* @since 1.7
|
||||
*
|
||||
* @param object $item The current item. It must contain at least a $process property.
|
||||
*/
|
||||
@@ -833,8 +808,7 @@ class Imagify_Files_List_Table extends WP_List_Table {
|
||||
/**
|
||||
* Prints a button to generate WebP versions if they are missing.
|
||||
*
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
* @since 1.7
|
||||
*
|
||||
* @param object $item The current item. It must contain at least a $process property.
|
||||
*/
|
||||
@@ -849,8 +823,7 @@ class Imagify_Files_List_Table extends WP_List_Table {
|
||||
/**
|
||||
* Prints a button to delete WebP versions when the status is "already_optimized".
|
||||
*
|
||||
* @since 1.9.6
|
||||
* @author Grégory Viguier
|
||||
* @since 1.9.6
|
||||
*
|
||||
* @param object $item The current item. It must contain at least a $process property.
|
||||
*/
|
||||
@@ -865,8 +838,7 @@ class Imagify_Files_List_Table extends WP_List_Table {
|
||||
/**
|
||||
* Prints a button to restore the file.
|
||||
*
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
* @since 1.7
|
||||
*
|
||||
* @param object $item The current item. It must contain at least a $process property.
|
||||
*/
|
||||
@@ -888,8 +860,7 @@ class Imagify_Files_List_Table extends WP_List_Table {
|
||||
/**
|
||||
* Prints a button to check if the file has been modified or not.
|
||||
*
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
* @since 1.7
|
||||
*
|
||||
* @param object $item The current item. It must contain at least a $process property.
|
||||
*/
|
||||
@@ -905,8 +876,7 @@ class Imagify_Files_List_Table extends WP_List_Table {
|
||||
/**
|
||||
* Prints a button for the comparison tool (before / after optimization).
|
||||
*
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
* @since 1.7
|
||||
*
|
||||
* @param object $item The current item. It must contain at least a $process property.
|
||||
*/
|
||||
@@ -952,8 +922,7 @@ class Imagify_Files_List_Table extends WP_List_Table {
|
||||
* Add the folder_id and folder_path properties to the $item if not set yet.
|
||||
* It may happen if the $item doesn't come from the prepare() method.
|
||||
*
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
* @since 1.7
|
||||
*
|
||||
* @param object $item The current item. It must contain at least a $process property.
|
||||
* @return object The current item.
|
||||
@@ -988,8 +957,7 @@ class Imagify_Files_List_Table extends WP_List_Table {
|
||||
/**
|
||||
* Get the name of the default primary column.
|
||||
*
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
* @since 1.7
|
||||
*
|
||||
* @return string Name of the default primary column, in this case, 'title'.
|
||||
*/
|
||||
@@ -1000,8 +968,7 @@ class Imagify_Files_List_Table extends WP_List_Table {
|
||||
/**
|
||||
* Get a list of CSS classes for the WP_List_Table table tag.
|
||||
*
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
* @since 1.7
|
||||
*
|
||||
* @return array List of CSS classes for the table tag.
|
||||
*/
|
||||
@@ -1012,8 +979,7 @@ class Imagify_Files_List_Table extends WP_List_Table {
|
||||
/**
|
||||
* Allow to save the screen options when submitted by the user.
|
||||
*
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
* @since 1.7
|
||||
*
|
||||
* @param bool|int $status Screen option value. Default false to skip.
|
||||
* @param string $option The option name.
|
||||
@@ -1031,8 +997,7 @@ class Imagify_Files_List_Table extends WP_List_Table {
|
||||
/**
|
||||
* Get the requested folder filter.
|
||||
*
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
* @since 1.7
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@@ -1050,8 +1015,7 @@ class Imagify_Files_List_Table extends WP_List_Table {
|
||||
/**
|
||||
* Get the requested status filter.
|
||||
*
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
* @since 1.7
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@@ -1067,7 +1031,7 @@ class Imagify_Files_List_Table extends WP_List_Table {
|
||||
'unoptimized' => 1,
|
||||
'errors' => 1,
|
||||
);
|
||||
$filter = trim( filter_input( INPUT_GET, 'status-filter', FILTER_SANITIZE_STRING ) );
|
||||
$filter = isset( $_GET['status-filter'] ) ? trim( htmlspecialchars( wp_unslash( $_GET['status-filter'] ) ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.NonceVerification.Recommended
|
||||
$filter = isset( $values[ $filter ] ) ? $filter : '';
|
||||
|
||||
return $filter;
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
<?php
|
||||
|
||||
use Imagify\User\User;
|
||||
|
||||
defined( 'ABSPATH' ) || die( 'Cheatin’ uh?' );
|
||||
|
||||
/**
|
||||
@@ -303,7 +306,7 @@ class Imagify_Requirements {
|
||||
return self::$supports['over_quota'];
|
||||
}
|
||||
|
||||
$user = new Imagify_User();
|
||||
$user = new User();
|
||||
|
||||
self::$supports['over_quota'] = $user->get_error() ? false : $user->is_over_quota();
|
||||
|
||||
|
||||
@@ -131,9 +131,12 @@ class Imagify_Settings {
|
||||
* @return bool
|
||||
*/
|
||||
public function is_form_submit() {
|
||||
return filter_input( INPUT_POST, 'option_page', FILTER_SANITIZE_STRING ) === $this->settings_group && filter_input( INPUT_POST, 'action', FILTER_SANITIZE_STRING ) === 'update';
|
||||
}
|
||||
if ( ! isset( $_POST['option_page'], $_POST['action'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
|
||||
return false;
|
||||
}
|
||||
|
||||
return htmlspecialchars( wp_unslash( $_POST['option_page'] ) ) === $this->settings_group && htmlspecialchars( wp_unslash( $_POST['action'] ) ) === 'update'; // phpcs:ignore WordPress.Security.NonceVerification.Missing
|
||||
}
|
||||
|
||||
/** ----------------------------------------------------------------------------------------- */
|
||||
/** ON FORM SUBMIT ========================================================================== */
|
||||
|
||||
@@ -1,18 +1,20 @@
|
||||
<?php
|
||||
|
||||
use Imagify\User\User;
|
||||
|
||||
defined( 'ABSPATH' ) || die( 'Cheatin’ uh?' );
|
||||
|
||||
/**
|
||||
* Class that handles templates and menus.
|
||||
*
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
* @since 1.7
|
||||
*/
|
||||
class Imagify_Views {
|
||||
|
||||
/**
|
||||
* Class version.
|
||||
*
|
||||
* @var string
|
||||
* @var string
|
||||
* @since 1.7
|
||||
*/
|
||||
const VERSION = '1.1';
|
||||
@@ -20,64 +22,56 @@ class Imagify_Views {
|
||||
/**
|
||||
* Slug used for the settings page URL.
|
||||
*
|
||||
* @var string
|
||||
* @since 1.7
|
||||
* @access protected
|
||||
* @var string
|
||||
* @since 1.7
|
||||
*/
|
||||
protected $slug_settings;
|
||||
|
||||
/**
|
||||
* Slug used for the bulk optimization page URL.
|
||||
*
|
||||
* @var string
|
||||
* @since 1.7
|
||||
* @access protected
|
||||
* @var string
|
||||
* @since 1.7
|
||||
*/
|
||||
protected $slug_bulk;
|
||||
|
||||
/**
|
||||
* Slug used for the "custom folders" page URL.
|
||||
*
|
||||
* @var string
|
||||
* @since 1.7
|
||||
* @access protected
|
||||
* @var string
|
||||
* @since 1.7
|
||||
*/
|
||||
protected $slug_files;
|
||||
|
||||
/**
|
||||
* A list of JS templates to print at the end of the page.
|
||||
*
|
||||
* @var array
|
||||
* @since 1.9
|
||||
* @access protected
|
||||
* @var array
|
||||
* @since 1.9
|
||||
*/
|
||||
protected $templates_in_footer = [];
|
||||
|
||||
/**
|
||||
* Stores the "custom folders" files list instance.
|
||||
*
|
||||
* @var object Imagify_Files_List_Table
|
||||
* @since 1.7
|
||||
* @access protected
|
||||
* @var Imagify_Files_List_Table
|
||||
* @since 1.7
|
||||
*/
|
||||
protected $list_table;
|
||||
|
||||
/**
|
||||
* Filesystem object.
|
||||
*
|
||||
* @var object Imagify_Filesystem
|
||||
* @since 1.7.1
|
||||
* @access protected
|
||||
* @author Grégory Viguier
|
||||
* @var Imagify_Filesystem
|
||||
* @since 1.7.1
|
||||
*/
|
||||
protected $filesystem;
|
||||
|
||||
/**
|
||||
* The single instance of the class.
|
||||
*
|
||||
* @var object
|
||||
* @since 1.7
|
||||
* @access protected
|
||||
* @var object
|
||||
* @since 1.7
|
||||
*/
|
||||
protected static $_instance;
|
||||
|
||||
@@ -89,9 +83,7 @@ class Imagify_Views {
|
||||
/**
|
||||
* The constructor.
|
||||
*
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
* @access protected
|
||||
* @since 1.7
|
||||
*/
|
||||
protected function __construct() {
|
||||
$this->slug_settings = IMAGIFY_SLUG;
|
||||
@@ -103,9 +95,7 @@ class Imagify_Views {
|
||||
/**
|
||||
* Get the main Instance.
|
||||
*
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
* @access public
|
||||
* @since 1.7
|
||||
*
|
||||
* @return object Main instance.
|
||||
*/
|
||||
@@ -120,9 +110,7 @@ class Imagify_Views {
|
||||
/**
|
||||
* Launch the hooks.
|
||||
*
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
* @access public
|
||||
* @since 1.7
|
||||
*/
|
||||
public function init() {
|
||||
// Menu items.
|
||||
@@ -152,9 +140,7 @@ class Imagify_Views {
|
||||
/**
|
||||
* Add sub-menus for all sites.
|
||||
*
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
* @access public
|
||||
* @since 1.7
|
||||
*/
|
||||
public function add_site_menus() {
|
||||
$wp_context = imagify_get_context( 'wp' );
|
||||
@@ -187,9 +173,7 @@ class Imagify_Views {
|
||||
/**
|
||||
* Add menu and sub-menus in the network admin when Imagify is network-activated.
|
||||
*
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
* @access public
|
||||
* @since 1.7
|
||||
*/
|
||||
public function add_network_menus() {
|
||||
global $submenu;
|
||||
@@ -232,9 +216,7 @@ class Imagify_Views {
|
||||
/**
|
||||
* Add links to the plugin row in the plugins list.
|
||||
*
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
* @access public
|
||||
* @since 1.7
|
||||
*
|
||||
* @param array $actions An array of action links.
|
||||
* @return array
|
||||
@@ -254,9 +236,7 @@ class Imagify_Views {
|
||||
/**
|
||||
* The main settings page.
|
||||
*
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
* @access public
|
||||
* @since 1.7
|
||||
*/
|
||||
public function display_settings_page() {
|
||||
$this->print_template( 'page-settings' );
|
||||
@@ -265,9 +245,7 @@ class Imagify_Views {
|
||||
/**
|
||||
* The bulk optimization page.
|
||||
*
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
* @access public
|
||||
* @since 1.7
|
||||
*/
|
||||
public function display_bulk_page() {
|
||||
$types = array();
|
||||
@@ -363,9 +341,7 @@ class Imagify_Views {
|
||||
/**
|
||||
* The page displaying the "custom folders" files.
|
||||
*
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
* @access public
|
||||
* @since 1.7
|
||||
*/
|
||||
public function display_files_list() {
|
||||
$this->print_template( 'page-files-list' );
|
||||
@@ -374,9 +350,7 @@ class Imagify_Views {
|
||||
/**
|
||||
* Initiate the "custom folders" list table data.
|
||||
*
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
* @access public
|
||||
* @since 1.7
|
||||
*/
|
||||
public function load_files_list() {
|
||||
// Instantiate the list.
|
||||
@@ -396,9 +370,7 @@ class Imagify_Views {
|
||||
/**
|
||||
* Get the settings page slug.
|
||||
*
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
* @access public
|
||||
* @since 1.7
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@@ -409,9 +381,7 @@ class Imagify_Views {
|
||||
/**
|
||||
* Get the bulk optimization page slug.
|
||||
*
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
* @access public
|
||||
* @since 1.7
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@@ -422,9 +392,7 @@ class Imagify_Views {
|
||||
/**
|
||||
* Get the "custom folders" files page slug.
|
||||
*
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
* @access public
|
||||
* @since 1.7
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@@ -440,16 +408,14 @@ class Imagify_Views {
|
||||
/**
|
||||
* Tell if we’re displaying the settings page.
|
||||
*
|
||||
* @since 1.9
|
||||
* @author Grégory Viguier
|
||||
* @access public
|
||||
* @since 1.9
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_settings_page() {
|
||||
global $pagenow;
|
||||
|
||||
$page = filter_input( INPUT_GET, 'page', FILTER_SANITIZE_STRING );
|
||||
$page = htmlspecialchars( wp_unslash( $_GET['page'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.NonceVerification.Recommended
|
||||
|
||||
if ( $this->get_settings_page_slug() !== $page ) {
|
||||
return false;
|
||||
@@ -465,16 +431,14 @@ class Imagify_Views {
|
||||
/**
|
||||
* Tell if we’re displaying the bulk optimization page.
|
||||
*
|
||||
* @since 1.9
|
||||
* @author Grégory Viguier
|
||||
* @access public
|
||||
* @since 1.9
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_bulk_page() {
|
||||
global $pagenow;
|
||||
|
||||
$page = filter_input( INPUT_GET, 'page', FILTER_SANITIZE_STRING );
|
||||
$page = htmlspecialchars( wp_unslash( $_GET['page'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.NonceVerification.Recommended
|
||||
|
||||
return 'upload.php' === $pagenow && $this->get_bulk_page_slug() === $page;
|
||||
}
|
||||
@@ -482,16 +446,14 @@ class Imagify_Views {
|
||||
/**
|
||||
* Tell if we’re displaying the custom files list page.
|
||||
*
|
||||
* @since 1.9
|
||||
* @author Grégory Viguier
|
||||
* @access public
|
||||
* @since 1.9
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_files_page() {
|
||||
global $pagenow;
|
||||
|
||||
$page = filter_input( INPUT_GET, 'page', FILTER_SANITIZE_STRING );
|
||||
$page = htmlspecialchars( wp_unslash( $_GET['page'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.NonceVerification.Recommended
|
||||
|
||||
return 'upload.php' === $pagenow && $this->get_files_page_slug() === $page;
|
||||
}
|
||||
@@ -499,26 +461,20 @@ class Imagify_Views {
|
||||
/**
|
||||
* Tell if we’re displaying the WP media library page.
|
||||
*
|
||||
* @since 1.9
|
||||
* @author Grégory Viguier
|
||||
* @access public
|
||||
* @since 1.9
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_wp_library_page() {
|
||||
global $pagenow;
|
||||
|
||||
$page = filter_input( INPUT_GET, 'page', FILTER_SANITIZE_STRING );
|
||||
|
||||
return 'upload.php' === $pagenow && ! $page;
|
||||
return 'upload.php' === $pagenow && ! isset( $_GET['page'] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell if we’re displaying a media page.
|
||||
*
|
||||
* @since 1.9
|
||||
* @author Grégory Viguier
|
||||
* @access public
|
||||
* @since 1.9
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
@@ -536,9 +492,7 @@ class Imagify_Views {
|
||||
/**
|
||||
* Get the remaining quota in percent.
|
||||
*
|
||||
* @since 1.8.1
|
||||
* @author Grégory Viguier
|
||||
* @access public
|
||||
* @since 1.8.1
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
@@ -549,7 +503,7 @@ class Imagify_Views {
|
||||
return $quota;
|
||||
}
|
||||
|
||||
$user = new Imagify_User();
|
||||
$user = new User();
|
||||
$quota = $user->get_percent_unconsumed_quota();
|
||||
|
||||
return $quota;
|
||||
@@ -558,9 +512,7 @@ class Imagify_Views {
|
||||
/**
|
||||
* Get the HTML class used for the quota (to change the color when out of quota for example).
|
||||
*
|
||||
* @since 1.8.1
|
||||
* @author Grégory Viguier
|
||||
* @access public
|
||||
* @since 1.8.1
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@@ -588,9 +540,7 @@ class Imagify_Views {
|
||||
/**
|
||||
* Get the HTML tag used for the quota (the weather-like icon).
|
||||
*
|
||||
* @since 1.8.1
|
||||
* @author Grégory Viguier
|
||||
* @access public
|
||||
* @since 1.8.1
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@@ -622,9 +572,7 @@ class Imagify_Views {
|
||||
/**
|
||||
* Get a template contents.
|
||||
*
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
* @access public
|
||||
* @since 1.7
|
||||
*
|
||||
* @param string $template The template name.
|
||||
* @param mixed $data Some data to pass to the template.
|
||||
@@ -648,9 +596,7 @@ class Imagify_Views {
|
||||
/**
|
||||
* Print a template.
|
||||
*
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
* @access public
|
||||
* @since 1.7
|
||||
*
|
||||
* @param string $template The template name.
|
||||
* @param mixed $data Some data to pass to the template.
|
||||
@@ -662,9 +608,7 @@ class Imagify_Views {
|
||||
/**
|
||||
* Add a template to the list of JS templates to print at the end of the page.
|
||||
*
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
* @access public
|
||||
* @since 1.7
|
||||
*
|
||||
* @param string $template The template name.
|
||||
*/
|
||||
@@ -691,9 +635,7 @@ class Imagify_Views {
|
||||
/**
|
||||
* Print the JS templates that have been added to the "queue".
|
||||
*
|
||||
* @since 1.9
|
||||
* @author Grégory Viguier
|
||||
* @access public
|
||||
* @since 1.9
|
||||
*/
|
||||
public function print_js_templates() {
|
||||
if ( ! $this->templates_in_footer ) {
|
||||
@@ -717,9 +659,7 @@ class Imagify_Views {
|
||||
/**
|
||||
* Create HTML attributes from an array.
|
||||
*
|
||||
* @since 1.9
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
* @since 1.9
|
||||
*
|
||||
* @param array $attributes A list of attribute pairs.
|
||||
* @return string HTML attributes.
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
<?php
|
||||
|
||||
use Imagify\User\User;
|
||||
|
||||
defined( 'ABSPATH' ) || die( 'Cheatin’ uh?' );
|
||||
|
||||
if ( class_exists( 'C_NextGEN_Bootstrap' ) && class_exists( 'Mixin' ) && get_site_option( 'ngg_options' ) ) :
|
||||
@@ -60,7 +63,7 @@ if ( class_exists( 'C_NextGEN_Bootstrap' ) && class_exists( 'Mixin' ) && get_sit
|
||||
|
||||
add_filter( 'imagify_count_saving_data', 'imagify_ngg_count_saving_data', 8 );
|
||||
$saving_data = imagify_count_saving_data();
|
||||
$user = new Imagify_User();
|
||||
$user = new User();
|
||||
|
||||
$response['imagify_bulk_data'] = array(
|
||||
// User account.
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user