CF7 Data source plugin allows to populate the common "Contact Form 7" fields (text, email, URL, drop-down menu, ...) with data stored in external data sources, like a database, CSV file, URL parameters, users information, post data, taxonomies, Advanced Custom Fields (ACF), Server Side functions, and JSON objects.
CF7 Data source includes two new controls in the controls bar of Contact Form 7, recordset and recordset field link. The "recordset" control reads the information from the external data source (a database, a CSV file, or any other of data sources supported), and the "recordset field link" control for linking the recordsets and form fields to populate them with the recordset data.
To install the WordPress plugin follow these steps:
To activate the commercial features of "CF7 - Data Source" plugin:
CF7 Data source includes two new controls in the controls bar of Contact Form 7, recordset and recordset field link.
The recordset control reads the information from the external data source and makes it available on the form. A recordset field can read one or many records from the data source.
To insert a recordset field in the form, press the "recordset" button in the controls bar. This action opens a dialog to define the recordset.
The recordset insertion dialog box includes some attributes that are common to all data sources and attributes that are specific to the selected data source.
The common attributes are:
The data source attributes are described in the Data Source section.
The "recordset field link" control links a recordset field to other fields in the form to populate them with the recordset data.
To insert a link field in the form, press the "recordset field link" button in the controls bar. This action opens a dialog to define the relationship between a recordset and a form's field.
The recordset field link insertion dialog box includes a set of attributes to define the relationship between the recordset field and the form's fields. These attributes are:
The complexity of this attribute deserves its own section.
The "conditions for filtering" attribute allows selecting those records in the recordset field to use to populate the form field. As I said many times a recordset field contains a list of records, and every record consists of attributes.
To refer to an attribute in the records for filtering you should use the piece of code record['attribute name']
. The "conditions for filtering" are pieces of valid JavaScript code. Where it is possible the use of comparison operators, like equality (==), less than (<), less than or equal (<=), great than (>), greater than or equal (>=) and not equal (!=), and connector operators like AND (&&), OR (||)
Ex.
record['ID'] == 123
record['post_status'] == 'publish'
record['first_name'] == 'John' && record['last_name'] == 'Doe'
record['first_name'] == 'John' || record['last_name'] == 'Doe'
record['post_status'] == 'publish' && (record['post_type'] == 'product' || record['post_type'] == 'download') && record['post_title'].indexOf('music') != -1
Important Note: the plugin encodes some characters when the field is inserted in the form
[
for [
]
for ]
<
for <
>
for >
"
for "
The plugin allows using other fields' values in the conditions for filtering. To access the values of other fields in the conditions for filtering use the structure {field.field-name}
Case of use: assuming the form includes three fields. The email field user-email, the text field first-name and the text field last-name.
<label>Enter your email
[email user-email]</label>
<label> Enter your first name
[text first-name]</label>
<label> Enter your last name
[text last-name]</label>
Now, I'll insert a recordset field to read the emails, first_name and last_name of the website's users:
[cf7-recordset id="users-list" type="user" attributes="user_email,first_name,last_name"]
And finally, I'll insert two link fields in the contact form to populate the first name and last name fields from the recordset field based on the email address entered by the user into the "user-email" field:
[cf7-link-field recordset="users-list" field="first-name" value="first_name" condition="record['user_email'] == '{field.user-email}'"]
[cf7-link-field recordset="users-list" field="last-name" value="last_name" condition="record['user_email'] == '{field.user-email}'"]
Pay attention to the use of {field.user-email}
in the piece of code above.
Complete form's structure:
<label>Enter your email
[email user-email]</label>
<label> Enter your first name
[text first-name]</label>
<label> Enter your last name
[text last-name]</label>
[cf7-recordset id="users-list" type="user" attributes="user_email,first_name,last_name"]
[cf7-link-field recordset="users-list" field="first-name" value="first_name" condition="record['user_email'] == '{field.user-email}'"]
[cf7-link-field recordset="users-list" field="last-name" value="last_name" condition="record['user_email'] == '{field.user-email}'"]
Similar to the use of other fields in the conditions for filtering it is possible to use JavaScript variables with the structure {var.variable-name}
Continuing with the previous case of use, if there is a JavaScript variable in the page the user's email <script>var email="johndoe@mail.com";</script>
the link fields would be:
[cf7-link-field recordset="users-list" field="first-name" value="first_name" condition="record['user_email'] == '{var.email}'"]
[cf7-link-field recordset="users-list" field="last-name" value="last_name" condition="record['user_email'] == '{var.email}'"]
There are situations where we need to populate a field with a complex data structure that includes multiple attributes in the recordset records or a combination of the record attributes and HTML. For example, fill a text field with the user's logged first name and last name.
In these cases, we need to use templates. A template is represented by a <template> tag with an id attribute, whose content will be combined with the recordset records to generate the fields' texts and values. Ex. <template id="user-name"></template>
To use a template to generate the field's text or value, you should use the structure: {template.template-id} where template-id must be replaced with the id attribute in the template tag. Ex. [cf7-link-field recordset="user-info" field="user-name" value="{template.user-name}"]
To refer the records' attributes from the template you should use the structure: {attribute.attribute-name} where attribute-name must be replaced by the attribute's name in the record. Ex.<template id="user-name">{attribute.first_name} {attribute.last_name}</template>
The complete example code:
<label> User name (first name and last name)
[text user-name]</label>
[cf7-recordset id="user-info" type="user" attributes="first_name,last_name" logged="1"]
[cf7-link-field recordset="user-info" field="user-name" value="{template.user-name}"]
<template id="user-name">{attribute.first_name} {attribute.last_name}</template>
The "recordset" control reads information from external data sources (a database, a CSV file, or any other of data sources supported) and makes it available on the form. The data source is selected from the "Recordset insertion dialog", and based on the data source selected there are enabled a new set of fields:
The next sections describe the different data sources' attributes.
Creates a recordset with the parameters received by GET. The URL Parameters data source does not require any configuration or attributes.
<label>First Parameter
[email parameter-1]</label>
<label> Second Parameter
[text parameter-2]</label>
[cf7-recordset id="get-parameters" type="url-parameters"]
[cf7-link-field recordset="get-parameters" field="parameter-1" value="param1"]
[cf7-link-field recordset="get-parameters" field="parameter-2" value="param2"]
After inserting the form, visit the page with param1 and param2 parameters:
?param1=value-a¶m2=value-b
The User Information data source allows getting the users' information. The data source attributes are:
user_login='info'
to return the information of the user whose login is info.
<label>Enter your email
[email user-email]</label>
<label> Enter your first name
[text first-name]</label>
<label> Enter your last name
[text last-name]</label>
[cf7-recordset id="users-list" type="user" attributes="user_email,first_name,last_name"]
[cf7-link-field recordset="users-list" field="first-name" value="first_name" condition="record['user_email'] == '{field.user-email}'"]
[cf7-link-field recordset="users-list" field="last-name" value="last_name" condition="record['user_email'] == '{field.user-email}'"]
The Posts Data data source allows getting the information of posts (posts, pages, products, or any other custom post type), like their ids, titles, excerpts, contents, or any other column of wp_posts database's table. The data source attributes are:
post_status='publish' AND post_type='product'
to return the list of published WooCommerce products.
<label>Products List
[select products-list]</label>
[cf7-recordset id="products-recordset" type="post" attributes="ID,post_title" condition="post_status='publish' AND post_type='product'"]
[cf7-link-field recordset="products-recordset" field="products-list" value="ID" text="post_title"]
The Advanced Custom Fields (ACF) data source allows getting the information from custom fields in posts, users, comments, taxonomies, widgets, and options. The data source requires the Advanced Custom Fields plugin be installed on WordPress. The data source attributes are:
For user, the interface includes a checkbox to load the custom field from logged user.
The Taxonomies data source allows accessing the taxonomies terms data (term_id, name, slug). The data source attributes are:
name LIKE '%trip%'
to get all terms that include trip text in their names.{post.id}
constant for the current post id.
<label>Tours
[select tours-category]</label>
[cf7-recordset id="category-terms" type="taxonomy" taxonomy="category" attributes="term_id,name" condition="name LIKE '%trip%'" in="{post.id}"]
[cf7-link-field recordset="category-terms" field="tours-category" value="term_id" text="name"]
The Database data source allows reading the data from databases. This data source covers the functionalities of the Users, Posts, and Taxonomies data sources.
The database data source allows to read the information from the following database engines:
MySQL
MS SQL Server
Oracle
PostgreSQL
SQLite
IBM
Firebird
Informix
ODBC and DB2
CUBRID
4D
The database connection can be configured by its components or DNS.
To read the data from the website's database, leave empty the database connection attributes.
Database data source attributes:
The query attribute looks complex, but it is the most powerful tool of the plugin. Its value would be a valid SQL query.
In the query, it is possible to use constants for the table names, users' data, or blog information.
Here are some sample queries with their descriptions:
List of users with their ids, emails, and logins
SELECT ID, user_email, user_login FROM {wpdb.users}
In WordPress, the prefix of database tables is defined into the wp-config.php file. So, the name of the "users" table can be different by website, wp_users, wp2_users, or any other prefix. Use the {wpdb.users}
constant for the name of the "users" table in the current website. The use of constants avoids the necessity to know the prefix.
First name and last name of logged user:
SELECT t1.meta_value as first_name, t2.meta_value as last_name FROM {wpdb.usermeta} t1, {wpdb.usermeta} t2 WHERE t1.meta_key = 'first_name' AND t2.meta_key = 'last_name' AND t1.user_id = t2.user_id AND t1.user_id = {user.id}
The {wpdb.usermeta}
constant corresponds to the wp_usermeta table name, and the {user.id}
constant is replaced by the id of the logged user.
List of ids and titles of published posts:
SELECT ID, post_title FROM {wpdb.posts} WHERE post_status='publish' AND post_type='post'
The {wpdb.posts}
constant corresponds to the wp_posts database's table.
Into the queries, it is possible to use the values of other fields in the form. In the following example, the web form contains the drop-down menu named users-list where the options' values are the users' ids and their texts the users' names. This query returns the list of posts written by the selected user:
SELECT ID, post_title FROM {wpdb.posts} WHERE post_status='publish' AND post_author={field.users-list}
The {wpdb.posts}
constant corresponds to the wp_posts database's table. To access the values of other fields in the query use the structure {field.field-name}
In this case {field.users-list}
refers to the value of the users-list field.
The complete list of constants is described in the "Constants" section.
The CSV File data source reads a CSV file and makes its records available for the form. The data source attributes are:
tab
word.It populates the drop-down menu field with the list of countries read from a CSV file.
<label>Country
[select country]</label>
[cf7-recordset id="country-list" type="csv" url="https://pkgstore.datahub.io/core/country-list/data_csv/data/d7c9d7cfb42cb69f4422dec222dbbaa8/data_csv.csv" headline="1" delimiter=","]
[cf7-link-field recordset="country-list" field="country" value="Name" text="Name"]
The JSON File data source reads a JSON file and makes its records available for the form. The data source attributes are:
<label>Country
[select country]</label>
[cf7-recordset id="country-list" type="json" url="https://pkgstore.datahub.io/core/country-list/data_json/data/8c458f2d15d9f2119654b29ede6e45b8/data_json.json"]
[cf7-link-field recordset="country-list" field="country" value="Name" text="Name"]
The Javascript Function data source reads the records list from a javascript function. The data source attributes are:
{field.field-name}
, variables {var.variable-name}
, and values {value.text-or-number}
.The Server Side data source reads the records list from server side functions implemented via the "Server Side" add-on. The data source attributes are:
{field.field-name}
, variables {var.variable-name}
, and values {value.text-or-number}
.List of constants to use with the recordset fields:
The plugin includes some constants you can use with the queries in the Database Data Source. The constants are enclosed between curly brackets like {wpdb.prefix}
{wpdb.prefix}
prefix used by WordPress in the name of database's tables, for example, the text "wp_" into the table's name "wp_posts"
{wpdb.comments}
the name of Comments table
{wpdb.commentmeta}
the name of Comment Metadata table
{wpdb.links}
the name of Links table
{wpdb.options}
the name of Options table
{wpdb.postmeta}
the name of Post Metadata table
{wpdb.posts}
the name of Posts table
{wpdb.terms}
the name of Terms table
{wpdb.term_relationships}
the name of Term Relationships table
{wpdb.term_taxonomy}
the name of Term Taxonomy table
{wpdb.termmeta}
the name of Term Meta table
{wpdb.usermeta}
name of User Metadata table
{wpdb.users}
the name of Users table
{wpdb.blogs}
the name of Multisite Blogs table
{wpdb.blog_versions}
the name of Multisite Blog Versions table
{wpdb.site}
the name of Multisite Sites table
{wpdb.sitecategories}
the name of Multisite Sitewide Terms table
{wpdb.sitemeta}
the name of Multisite Site Metadata table
{blog.id}
the id of the current blog (Helpful in multisite WordPress installations)
{user.id}
the id of the current user
{user.login}
the username of the current user
{user.nicename}
the URL-friendly name for the current user
{user.email}
the email address of the current user
{user.url}
the URL associated to the current user
{user.display_name}
the user's name that is shown on the site for the current user
{user.first_name}
the first name of current user
{user.last_name}
the last name of current user
Allows access to the post information where the contact form is inserted.
{post.id}
unique number assigned to each post
{post.post_author}
the user ID who created it
{post.post_date}
time and date of post creation
{post.post_date_gmt}
GMT time and date of creation
{post.post_content}
holds all the content for the post, including HTML, shortcodes and other content
{post.post_title}
title of the post
{post.post_excerpt}
custom intro or short version of the content
{post.post_status}
status of the post, e.g. draft, pending, private, publish
{post.comment_status}
if comments are allowed
{post.ping_status}
if the post allows ping and trackbacks
{post.post_password}
optional password used to view the post
{post.post_name}
URL friendly slug of the post title
{post.to_ping}
a list of URLs WordPress should send pingbacks to when updated
{post.pinged}
a list of URLs WordPress has sent pingbacks to when updated
{post.post_modified}
time and date of last modification
{post.post_modified_gmt}
GMT time and date of last modification
{post.guid}
Global Unique Identifier, the permanent URL to the post, not the permalink version
{post.menu_order}
holds the display number for pages and other non-post types
{post.post_type}
the content type identifier
{post.comment_count}
total number of comments, pingbacks and trackbacks
{record.index}
record's index to use in the condition attribute of [cf7-link-field] shortcode. Ex. The records indexes begin at zero. If you want to access the attributes in the second record, you can enter the following condition in the [cf7-link-field] shortcode {record.index} == 1
The plugin triggers cf7-recordset javascript events after reading the data from data sources. This behavior allows using the data received from your blocks of code.
I'll try to describe the process with a practical example.
Assuming the contact form includes a recordset field with id="user-data". This field reads the information of the logged user with the "first_name" and "last_name" attributes. And I want to include a DIV tag after the <body> tag with a text similar to "Hello John Doe"
Insert a script block in the page where the contact form is insert, or directly into the contact form with the code:
<script>
document.addEventListener('cf7-recordset', function(evt){
if(evt.detail['recordset-id'] == 'user-data')
{
jQuery('body').prepend('Hello '+evt.detail['recordset-data'][0]['first_name']+' '+evt.detail['recordset-data'][0]['last_name']);
}
});
</script>
The piece of code above sets a listener for the "cf7-recordset" event triggered by the plugin.
The event "detail" property includes two attributes, "recordset-id" with the id of the recordset field that triggered the event and "recordset-data" with the information received from the data source.
The code of the listener checks if the field that triggered the event was the "user-data":
if(evt.detail['recordset-id'] == 'user-data')
And the code inside it accesses the information of the first record in the recordset field: evt.detail['recordset-data'][0]['first_name']
and evt.detail['recordset-data'][0]['last_name']
Another example
In addition, the plugin triggers an onchange event with the cf7-ds-fill parameter when it fills the form fields with the recordset data.
Ex. In the following piece of code, the plugin display an alert when fills the country field.
<label>Country
[select country]</label>
[cf7-recordset id="country-list" type="csv" url="https://pkgstore.datahub.io/core/country-list/data_csv/data/d7c9d7cfb42cb69f4422dec222dbbaa8/data_csv.csv" headline="1" delimiter=","]
[cf7-link-field recordset="country-list" field="country" value="Name" text="Name"]
<script>
jQuery(document).on('change', '[name="country"]', function(evt, attr){
if(attr == 'cf7-ds-fill') alert('The country list is available');
});
</script>
The plugin implementes some javascript functions you can call from your code.
cf7_datasource_get_recordset_data, receives recordset id as its parameter and returns an array with the records list.
cf7_datasource_set_recordset_data, populates the recordset records. It requires two parameters, the recordset id, and an array with the records list.
cf7_datasource_recordset_reload, calls the routine that loads the recordset records. It requires the recordset id as its parameter.
cf7_datasource_field_reload, refresh the value of a field linked to a recordset via [cf7-link-field] tag. The function receives two parameters, the field's name and recordset id.