[Create Your Own Short Code]

April 16th, 2013 Leave a comment Go to comments

If the available short codes are not giving you what you want, try creating your own.

You can achieve this by using a plugin that allows you to create short codes that include PHP code that you provide and using an API provided by this plugin to retrieve saved form data from the database.

To get set up to do this

  1. Install the plugin Shortcode Exec PHP. This plugin provides a page in your WP administration area that allows you to create a short code and provide it with PHP code to execute.
  2. Have a look at the FAQ on Accessing Form Data via PHP for some information on the API.

To create your own short code with your own code:

  1. Go to your WP Admin, Tools -> Shortcode Exec PHP
  2. Scroll to the bottom where there is an empty box to create a new shortcode
  3. Give it a name it the top box (like “myshortcode”). Name it whatever you want (but no spaces in the name)
  4. Copy the template code below, and paste into the code section
  5. Click Add, just to get it saved
  6. Replace “// Add your stuff here!” with your code (see below)
  7. Save it.
  8. Clicking Test will not help you because there are no input $atts (like form name)
  9. The best way to test is to create a new draft unpublished post, put your code in there minimally with a form name [myshortcode form="myform"] then preview the post to see what is displays.
  10. Use the shortcode on any pages/posts you like. Use : show, hide, limit, orderby, search, and filter just as you would for other short codes.

Template code: copy this code and paste in this code:

1
2
3
4
5
6
require_once(ABSPATH . 'wp-content/plugins/contact-form-7-to-database-extension/CFDBFormIterator.php');
$exp = new CFDBFormIterator();
$exp->export($atts['form'], $atts);
while ($row = $exp->nextRow()) {
 // Add your stuff here!
}

 

Add your stuff here!” Delete this line and replace with PHP code that outputs the HTML you want to see for one entry. Use PHP “echo” to output text, reference form values using $row['field-name'] where field-name is the name of the field or column. Let’s look at a real user’s example:

Example: One user was trying to use [cfdb-html] but it didn’t quite give him what he wanted. For one of his fields, “url”, he only wanted it to output an HTML link for that url but only if it was not blank. Unfortunately, [cfdb-html] outputs each form submission exactly the same, so it would make empty links for empty url fields. More generally speaking, [cfdb-html] can’t change its output based on what data is (or is not) in the form submission.

So he created his own shortcode named ‘bios’ like this:

1
2
3
4
5
6
7
8
9
10
require_once(ABSPATH . 'wp-content/plugins/contact-form-7-to-database-extension/CFDBFormIterator.php');
$exp = new CFDBFormIterator();
$exp->export($atts['form'], $atts);
while ($row = $exp->nextRow()) {
    echo '<h2>' . $row['name'] . '</h2>';
    echo '<p>' . $row['bio'] . '</p>';
    if ($row['url'] != null) {
        echo '<p><a href="' . $row['url'] . '">Website</a></p>';
    }
}

Notice how the code outputs a new paragraph <p> with a link <a> ONLY for only those submissions that have a URL entry.

Since he named his shortcode ‘bios‘, and his form name was “people“, he can use use the following shortcode on a page or post:

[bios form="people"]

 

Hard-coding ‘form’: But in this case, the shortcode is only for the “people” form since only that form has the ‘name’, ‘bio’ and ‘url’ columns. If he wanted to, he could hard-code the form name in the short code’s PHP code by changing:

$exp->export($atts['form'], $atts);

to:

$exp->export('people', $atts);

then on his page/post, he could just use:

[bios]

And of course, if he wanted to just show only 10 submissions sorted by name, he could use:

[bios limit="10" orderby="name"]

 

Warning about “extract”: OK, so you know PHP, you looked at the code above and said, “I don’t want to use the verbose $row['field-name'] syntax, I’m going to the PHP extract function to make my fields into variables then I can use actual field names as variables and embed them into double-quoted strings.” Kind of like this:

1
2
3
4
5
6
7
8
9
10
11
require_once(ABSPATH . 'wp-content/plugins/contact-form-7-to-database-extension/CFDBFormIterator.php');
$exp = new CFDBFormIterator();
$exp->export($atts['form'], $atts);
while ($row = $exp->nextRow()) {
    extract($row);
    echo "<h2>$name</h2>";
    echo "<p>$bio</p>";
    if ($url != null) {
        echo "<p><a href='$url'>Website</a></p>";
    } 
}

Seems a bit more concise, right? It is and it works in this example but only because the field names (“name”, “bio”, “url”) can be PHP variable names. When you create a form using Contact Form 7, it’s default/generated form has fields names have a dash in them (like “your-name”, “text-157″, “textarea-553″). The PHP extract will not work right as coded above because you can’t have a PHP variable with a dash in it ($your-name not allowed!). So you either have to

  1. Use the $row['your-name'] to refer to a value (and consequently can’t embed that in a PHP double-quoted string) or
  2. You have to ensure all form field names are suitable to be PHP variable names, then you can use ‘extract’ as in the above example.

 

About $atts: the $atts variable is an associative array of all the “attributes” of the shortcode.  In this code, we are passing $atts to $exp->export(). That mean that all of this plugin’s standard short code options can be used. They are: show, hide, limit, orderby, search, and filter. Thus, you could write a short code like: [myshortcode form="Contact form 1" show="col1,col2" search="Mike" limit="10"].

Add your own attributes: you can add your own attributes simply by adding them to your shortcode call and referencing them in the PHP via $atts['attribute-name']. For example, you might add an “email_user” field like this:

[myshortcode form="Contact form 1" show="col1,col2" search="Mike" limit="10" email_user="true"]

And have code like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
require_once(ABSPATH . 'wp-content/plugins/contact-form-7-to-database-extension/CFDBFormIterator.php');
$exp = new CFDBFormIterator();
$exp->export($atts['form'], $atts);
while ($row = $exp->nextRow()) {
    echo '<p>';
    foreach ($row as $name => $value) {
    	echo "$name=$value<br/>";
    }
    if ($atts['email_user'] == 'true') {
       wp_mail($row['email'], 'Hello ' . $row['name'], 'How are you doing?');
}
 echo '</p>';
}

 

Issue with line breaks inside fields

You may have a field that contains text with line breaks. This comes from text area type form fields. But when you echo it out, you don’t see the line breaks. This is because you need to convert regular line break characters (which browsers ignore) to HTML line break tags (<br/>). To do this, use the PHP nl2br function, like this (assuming you had a “description” field that might have line breaks in it):

1
2
3
4
5
6
require_once(ABSPATH . 'wp-content/plugins/contact-form-7-to-database-extension/CFDBFormIterator.php');
$exp = new CFDBFormIterator();
$exp->export($atts['form'], $atts);
while ($row = $exp->nextRow()) {
    echo nl2br($row['description']);
}

 

Links to uploaded files

(Since version 2.5.5) In cases where you have uploaded files in your form you may want to have a link to the file or embed it if it is an image. In these cases, the $row array will include an additional entry with the URL for each field. For example, if your form had a field called “upload” for uploading a file, then you will have the file name as $row['upload'] and the URL to that file as $row['upload_URL']. By convention, for any field “x” that is a file, you will have a “x_URL” entry in $row. (Be sure not to name form fields that conflict with this).

Example: where a form has an ‘upload’ field that contains a file

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
require_once(ABSPATH . 'wp-content/plugins/contact-form-7-to-database-extension/CFDBFormIterator.php');
 
$exp = new CFDBFormIterator();
 
// $atts is the array of short code attributes in Shortcode Exec PHP
$formName = $atts['form'];
 
// Name of the field that is a file uploaded from a form
$fieldName = 'upload'; // change to name of your form's field that has a file
 
// Pseudo field name that is the URL to the uploaded file
$fieldNameUrl = $fieldName . '_URL';
 
$exp->export($formName, $atts);
while ($row = $exp->nextRow()) {
    $fileName = $row[$fieldName];
    if (isset($row[$fieldNameUrl])) {
        $fileUrl = $row[$fieldNameUrl];
 
        // Make a link to the file
        printf('<a href="%s">%s</a><br/>', $fileUrl, $fileName);
   	// or embed file image
   	//printf('<img alt="%s" src="%s"/><br/>', $fileName, $fileUrl);
    }
}

 


Adding Security
You may wish to limit what kind of user can see the results of your short code. The short codes that are provided by this plugin such as cfdb-table are all controlled by the plugin setting: in the admin page, Database Options => Can See Submission when using shortcodes. This can be set to values such as “Anyone”, “Subscriber”, “Editor”, etc.

By default, your custom short code does is NOT controlled by this setting. You may wish to make it be, or you might want to have it controlled independently.

If you wish to have your custom short code be restricted based on the “Can See Submission when using shortcodes” setting, then put at the top of your short code PHP code:

1
2
3
require_once(ABSPATH . 'wp-content/plugins/contact-form-7-to-database-extension/CF7DBPlugin.php');
$plugin = new CF7DBPlugin;
if (!$plugin->canUserDoRoleOption('CanSeeSubmitDataViaShortcode')) return;

Instead, if you wish to restrict your short code to only those uses with ‘Editor’ role, then put in this code at the top of your short code:

1
2
3
require_once(ABSPATH . 'wp-content/plugins/contact-form-7-to-database-extension/CF7DBPlugin.php');
$plugin = new CF7DBPlugin;
if (!$plugin->isUserRoleEqualOrBetterThan('Editor')) return;

Replace ‘Editor’ with any of:

  • Administrator
  • Editor
  • Author
  • Contributor
  • Subscriber
  • Anyone

Misc Note:

As of version 1.8.8, there is a ‘submit_time’ value (that is $row['submit_time']) which contains the submit time-stamp in the form of seconds since 1970 with miliseconds (e.g. “1308521822.8621″) which can be used for comparing the submit time to a similar unformatted value. It can also be used as a DB key value to identify all the fields of a form submission.

 

Shortcode Exec PHP

  1. ~Tim
    February 28th, 2012 at 05:14 | #1

    Is it possible to add datatable functions to this?

    Using the cfdb-datatable shortcode is inadequate because I want to combine data from two columns into one. Those columns have a title and a link. I want to display the title as a clickable link such as:


    $titleVal = '' . $row['FF-Title'] . '';

    I can get everything into a table the way I want it. From the docs on WordPress.org and Datatables.net it looks like I should just be able to put something like


    on the page, but it doesn’t work. I’ve tried it with and without the and I’ve tried putting it into the shortcode instead of on the page. I know datatables can work on my site because the cfbd-datatable shortcode works, so I don’t see how it could be a conflict with the theme or another plugin.

    In one of the forums (I didn’t save the link) you suggested you might make a shortcode that just adds datatable functions to an existing table. That might work for me too if that’s easier than adding the functions to this.

    • Michael Simpson
      February 28th, 2012 at 06:55 | #2

      Are you setting the table id attribute to match the jQuery selector (my_data_table), i.e.

      to match jQuery(‘#my_data_table’).dataTable();
  2. ~Tim
    February 28th, 2012 at 05:17 | #3

    Aargh. I thought I could put code tags around my examples instead of hard-coding, but it looks like everything got stripped out anyway. @~Tim

  3. ~Tim
    February 29th, 2012 at 17:19 | #4

    @Michael Simpson

    Yes, the table id attribute matches the jQuery selector. I did a copy/paste to make sure I had it the same both places.

    The table also has thead and tbody sections declared as instructed on Datatables.net.

  4. Naveen
    March 31st, 2012 at 02:04 | #5

    I am trying to use a variable to filter the results. But I m unable to get it. Please help. Here is what I am trying to do:

    I am storing the post ID in a variable ($jid). I am then using this variable to filter the database which also has the JobID (See filter that I used in the below code).

    require_once(ABSPATH . ‘wp-content/plugins/contact-form-7-to-database-extension/CFDBFormIterator.php’);
    $exp = new CFDBFormIterator();
    $jid=the_ID();
    echo $jid;
    $exp->export(‘contact form 1′, array(‘show’ => ‘JobID,your-name,your-email’, ‘filter’ => ‘JobID=$jid’));
    while ($row = $exp->nextRow()) {
    echo $row['JobID'];
    echo $row['your-name'];
    echo $row['your-email'];
    }

  5. Michael Simpson
    March 31st, 2012 at 11:13 | #6

    @Naveen
    Try double quotes instead of single quotes around “JobID=$jid” to let PHP know to substitute the value of $jid in the string.

  6. September 2nd, 2012 at 12:07 | #7

    I have a question about downloading the database to an excel spread sheet. Anytime I download the data, the fields at the top of the spreadsheet says extra fields, but I want to name the fields the same as the fields that are in the database. What kind of code do I need to add to change this information? Does it have something to do with the attributes?

    I am a newbie so please help.

    • Michael Simpson
      September 2nd, 2012 at 16:17 | #8

      The excel export should give you the same columns that are in the DB. If you want to choose which columns to get and in which order, use the Database Short Code page be instead of creating a short code, choose an Export File and let it generate a link that for the Excel download.

  7. AJ
    September 7th, 2012 at 04:57 | #9

    Michael, any help would be greatly appreciated. I am just trying to filter the results of the database view by he user id

  8. Michael Simpson
    September 8th, 2012 at 19:18 | #10

    @AJ
    Use the short code builder page but use it to create an export link. Set filter or search criteria there an it will be embedded in the link.

  9. babs
    October 29th, 2012 at 11:49 | #11

    I want to use contact form as registration form i have done it and it works but the only issue is i want it to be use for login after registering on the site u should be able to login using username and password that you specified in the registration form

    • Michael Simpson
      October 29th, 2012 at 18:35 | #12

      You would need to create a filter hook described here and in that function call WP functions to create the user.

  10. TheMic
    December 11th, 2012 at 19:36 | #13

    Hi! I have a question:
    What can I do if I need to create a personal ‘Short Code’ and also need to have results divided into pages?

    thanks in advance!

  11. February 24th, 2013 at 13:21 | #14

    Dear all,

    I’ve tried to use the code in the post to get the image and print those within a Jquery slider.. unfortunately I got a bunchload of errors.
    Now my friend created a new piece of code to get the images from the database which are submitted within the form.

    see the code here: https://dylandamsma.snipt.net/get-image-from-contact-form-db-and-print/
    demo: http://www.vrijmispo.nl (the logo carousel on the homepage)

  12. Sam S.
    February 24th, 2013 at 20:05 | #15

    @Naveen Did Michael’s response help – what code did you use that worked?

    Thanks,

  13. jasnon
    September 10th, 2013 at 19:10 | #16

    Hi Michael,

    I attempted to create my own shortcode, and was successful for the most part, but have ran into a little roadblock at the moment. I’m trying to pass the results from my custom function as the inputs to another function. Curently my custom function is as follows:

    function custom_CFDB_function() {
    require_once(ABSPATH . ‘wp-content/plugins/contact-form-7-to-database-extension/CFDBFormIterator.php’);
    $exp = new CFDBFormIterator();
    $exp->export(‘Test Form’, array(‘show’ => ‘City’, ‘filter’ => ‘Year=2013&&Name=$user_login’));
    while ($row = $exp->nextRow()) {
    extract($row);
    echo “preg_match (‘/$City/i’, $city)||”;
    }
    echo “preg_match (‘/Placeholder/i’, $city)”;
    }

    And the other function looks like:

    function is_city($city){
    if(
    custom_CFDB_function();
    ){
    return false;
    }else{
    return true;
    }
    }

    What I’m hoping to achieve is that the results from my custom function will dynamically populate into the other function based on which user is logged in and would populate something like this:

    function is_city($city){
    if(
    preg_match (‘/Los Angeles/i’, $city)||
    preg_match (‘/San Francisco/i’, $city)||
    preg_match (‘/Sacramento/i’, $city)||
    preg_match (‘/San Diego/i’, $city)||
    preg_match (‘/Placeholder/i’, $city)

    ){
    return false;
    }else{
    return true;
    }
    }

    Sorry for the long post but this one’s really bugging me!

    Thanks,
    Jon

  14. Michael Simpson
    September 11th, 2013 at 11:31 | #17

    @jasnon
    Sounds like you just want to call is_city($city) from inside custom_CFDB_function(). I don’t follow what the problem is that you are experiencing. Thought: you might need to define the “is_city” function in the file before your define custom_CFDB_function() so that the parser recognizes the call to is_city() inside custom_CFDB_function().

  15. jasnon
    September 13th, 2013 at 12:28 | #18

    Hi Michael,

    I actually just found my answer in the “Preventing Duplicate Submissions from CF7″! Ultimately what I was trying to explain above was checking the database for previous submissions to support custom validation in CF7. I’ve moved my discussion over to that thread as I have another question specific to the custom validation.

    Thanks!

  1. November 6th, 2011 at 10:32 | #1
  2. November 26th, 2011 at 21:36 | #2
  3. April 29th, 2012 at 12:33 | #3
You must be logged in to post a comment.