Posted on by

Sometimes it’s necessary to create a custom form element to handle a specific need for a UI element in a Participants Database form. The means for doing that have been set up in the plugin, you’ll  definitely need some coding skills to get this done, so this post will only briefly cover the basic steps to setting up a custom form element. You are expected to know how to make this into your own custom form element.

The first step is to register your custom element with the plugin so that it can be selected in the field definition.

pdb-set_form_element_types

This filter is used to add the new form element identifier. The full definition array of form element types is passed through, a new element should be added to the array in the form: type_handle => title. Your custom form element type will show up in the Form Element dropdown on the Manage Database Fields page.

Showing a Custom Form Element in a Form

For this, we use the pdb-form_element_build_{$type} action.

This action is triggered when a form element is instantiated. When the element is instantiated, the FormElement object will be passed to the action handler. The handler is expected to fill the ‘output’ property with the HTML string. The handler argument is passed by reference so other changes to the element object are possible in addition to defining the output HTML.

This action can also be used to override an existing element build function. If the FormElement object already has it’s output property filled with HTML, the standard build method will be skipped.

Showing the Value of a Custom Form Element

Each form element has a way to show it’s value in a non-form context, and that can be customized as well. For that, we use the pdb-before_display_form_element filter which is supplied the raw value of the field and the PDb_Field_Item object for the element. Typically, you’d test the field object to see if it was your custom form element, then return the appropriate display HTML.

An Example

Let’s say you want to create a custom form element that stores an array of 3 values. You could give the element a handle of ‘array’ and a title of ‘List.’ Your filters/actions could be added like this:

add_filter( 'pdb-form_element_types', 'my_array_register_element' );
add_action( 'pdb-form_element_build_array','my_array_element_building_function' );
add_filter( 'pdb-before_display_form_element','my_array_element_value_display_function' );

The my_array_element_building_function() should return the PDb_FormElement object with the ‘output’ property filled with the HTML needed to display the element in a form. The my_array_element_value_display_function() should return the display value of the form element.

Here is the full code for our example. This one is way too simple to be used as-is, it’s only to show you how the parts go together, you can take it from here.

Posted on by

Let’s say you have a site where you want to register two types of people. We’ll call them “Red” and “Blue.” Each of those forms is going to have some fields in common and some fields that are different for each signup form.

The first thing to do is to organize your fields into groups. Field Groups are defined on the Manage Database Fields page under the “Field Groups” tab. One or more groups would contain all the fields that are common to both registration forms: things like name, address, email, etc.

Once you’ve got your common groups set up, you’ll need to set up at least one group for each form that contains the fields for the particular type of registration the form is for.

Tracking Which Form was Used

Since all the registrations will be contained in the same database, you’ll need an easy and reliable way to tell them apart. A good way to do this is to use a hidden field that records the name of the page the form is on.

Set up a hidden field in one of the common groups. You can name it “Form Type” or whatever you want that indicates that the value determines which form was used. In the “default” value for the hidden field, put post->post_name That will be automatically filled with the name of the page the form was on.

Setting Up the Signup Shortcodes

Once you have all your groups defined, set up your shortcodes. You’ll have one shortcode for each type of registration, and they will need to be on different pages. Setting up two different forms is done using the “groups” attribute of the shortcode.

Let’s say you have 3 field groups, one common one and one group for each type of registration form. We’ll call them “common,”  “red” and “blue.” When you set up the shortcodes, you can do it like this:

Red Form: [pdb_signup groups="common,red" ]

Blue Form: [pdb_signup groups="common,blue" ]

Telling the Registrations Apart

Now, when you list the registrations, you can easily show one or the other using a filter. Let’s say you wanted to show only the “Blue” registrations.  The blue form was on a page named “blue-registration” so you’d do it like this:

[pdb_list filter="form_type=blue-registration"]

And that would show all the records that were created using the “Blue” form.

That should get you started on your project that uses more than one kind of registration form.

Posted on by

A few months ago, I wrote a tutorial on how to automatically send an email when a record is updated. I’ve gotten several requests for something very similar: how to send an email to a person who has signed up, but ONLY after their submission has been approved. This is a good way to avoid spam submissions showing up on your site if you have an open registration form, so that anyone trying to sell you “real” Gucci bags isn’t getting added as a legitimate signup.

The first thing you’ll need to do is set up an approval checkbox as an administrative field (that is, it’s in an admin field group) and set up all your frontend displays to exclude showing unapproved records.

The original tutorial steps you through the creation of a simple plugin to add that functionality to Participants Database. You should read that article if you want to learn in detail how that is done. Anyway, the tutorial ends up with a plugin script that looks like this:

To get our functionality, what we need to do to that script is add a function that checks that the previously saved record was not approved and that the record is currently getting updated with an approval. If those conditions are met, we know that we need to send out the “welcome” email. We do that by loading the saved record, check if it’s unapproved, then check the update data to see if it is getting approved. A good way to do this is to create a function that does the checking…like this:

function pdb_record_is_getting_approved( $new_record )
{
  $old_record = Participants_Db::get_participant( $new_record['id'] );
  if ( $old_record['approved'] !== 'yes' && $new_record['approved'] === 'yes' ) {
    return true;
  }
  return false;
}

We just use that function to determine if the email should be sent or not. We put that in the section of the plugin that sends the email so it will skip sending it if the record isn’t getting approved at that point:

if ( pdb_record_is_getting_approved( $post ) ) {
    PDb_Template_Email::send( $config, $post );
  }

Pretty simple, huh? You’ll notice I used a long descriptive name for the function: that’s so the code ends up being more readable. Maybe that’s not needed for such a simple script, but it’s a good coding practice that will save you time later when you’re trying to fix bugs or change how things work.

Before you activate this plugin and start using it, uncheck the “Send Signup Response Email” in the plugin settings so that the regular signup greeting is not sent.

Here is the completed plugin:

Posted on by

I sometimes get requests to have Participants Database links to locations off the website open in a new window or tab. Depending on the context, this can be inadvisable from a user experience point of view, but even so, we need to be able to set that up sometimes. So, with that caveat in mind, this is how we do it…

To alter the way database data is shown, we use the ‘pdb-before_display_form_element’ filter. It gives us the field object which contains all the data for the field, and expects the HTML in return. If we want the plugin to do it’s thing normally, we return an empty string.

This filter is applied to all fields before getting displayed, so we want to be sure to only alter the ones we want changed. We need to determine if the field is a link field and that it has a link to an external location. If not, return the empty string.

This plugin is very simple: create a new file with the name pdb_external_links.php and code below. Upload it to your plugins folder and activate.

Pro tip: click on the filename in the code window above, then download the .zip file and install it.

That’s it, all external links will open in a new tab or window when the user clicks on them.

(Note: this post was edited for better code on Nov 30, 2016)

Posted on by

Let’s say you have a list of people who have specific skills. They’ve filled in their information using a “multiselect” to indicate which skills they have. Now, you want to show a link on your site that will show all the people with a particular skill.

This is easy to do, because it’s possible to include simple search parameters in a URL to a page with the [pdb_list] shortcode.

Let’s say the name of your skills field is “skills” and you want to show all the web designers. First, take a look at the values you have defined for your Skills multiselect so you know the exact string to look for. In this case, it’s ‘web designer’. The case is not important.

In a URL, the search parameters are ‘search_field’ and ‘value’ so we tell the list which value we are seeking in which field. Now, our search term has a space in it, so because we are using the term in a URL, we need to convert that space into a URL-encoded value. The value for a space is %20, so this will be our link (assuming your list is on a page named “list-participants”):

/list-participants?search_field=skills&value=web%20designer

And that will show you all the people who checked “Web Designer” in their skills.

You can only do simple searches this way: on a single field with a single search term. If you want something more complex than that, you’ll need to create a custom WordPress template that can process a more complex search from the URL and build those into the filter attribute of the list shortcode.

Posted on by

Sometimes, you want to send a message to the person who created a record when their record is updated by an administrator. For example, let’s say you use Participants Database for a registration that requires approval by an admin before it can be used. You want to let the person who submitted the registration know when their registration was approved by sending them an email.

This is a practical application of the Template Email class included in Participants Database. Take a look at this article for some background on that:

Using the PDb_Template_Email Class 

We’re going to take the example used in that article and wrap it in a simple plugin to get our functionality.

Using the Hook

To trigger sending the email, we use the plugin filter ‘pdb_before_submit_update’ which passes in the record data that will be used to update the record. This hook is triggered both when a record is updated on the frontend (typically when a user comes to the site with their private link and edits their record) and when a record is updated in the admin section. It’s easy to tell which it is by testing whether the event takes place in the context of the admin section or not.

We set up the filter like this so that it calls our function and does it’s thing:

add_filter( 'pdb-before_submit_update', 'pdb_send_record_update_notification' );

In that statement, we set up the filter to call a function named ‘pdb_send_record_update_notification’ to add our functionality. The first thing our function does is check to see if we should send the email by making sure the event is triggered in the admin section and that there is a valid email address to send the message to. If not, return the data (so it can be saved) and we’re done.

 if ( ! is_admin() || empty( $post['email'] ) ) {
  return $post;
 }

Next, if we are going to send the email, we need to define the subject and body of the email:

 $subject = 'Your record has been updated';
 $message = 'Dear [first_name] [last_name],

Your record has been updated.';

You’ll need to modify these strings to what you want in your message email. You can use any placeholder tags you want to fill in the message, it works the same as the email setting in the main plugin. Next, define the “from” field: this is very important, it should be an email address form the same domain as your website to avoid the message looking like spam.

$from = 'Your Website <info@yourwebsite.com>';

Now, all we need to do is put it all together into a configuration array so we can use the Template Email class to send the message:

 $config = array(
   'to' => $post['email'],
   'from' => $from,
   'subject' => $subject,
   'template' => $message,
 );

The email class just needs this configuration data and the record data (so it can fill in the placeholders) and it will send the email:

PDb_Template_Email::send( $config, $post );

Putting it Into a Plugin

Wrapping all this into a plugin is a good way to go because you can easily turn it on and off by activating/deactivating the plugin. Also, if you change themes, the functionality will continue to work. To create the plugin, create a php file on your computer, name it ‘pdb_update_notify.php’ You will upload this file to the “plugins” directory in your WordPress. Once you’ve done that, you can activate it in the plugin menu.

Here is the plugin code:

That’s it. There are many variations on this plugin you can easily incorporate. For instance, you may want to ensure that this email only gets sent once. You could do that by using the ID of the incoming array to load the current record data. Now, you can check a field value in both arrays (the incoming array and the one you got for the current record) to see if a particular one was changed. That can tell you if the email should be sent or not.

Posted on by

When a Participants Database signup form is submitted, it can be checked against the database for an existing record that matches the new submission. The plugin is set up to check one field for a match, and this would typically be the “email” field. This makes a good unique identifier for a record, since most of the time only one record per email is desirable…you can’t do a private link recovery unless the email is unique to one record, for instance.

Checking Multiple Fields

If you need to check multiple fields for a match because you don’t have a single field that uniquely identifies a record, here’s how you do that.

There is a filter in the plugin called ‘pdb-incoming_record_match’ that returns a simple true or false if the incoming record matches an existing record. The filter gets two arguments, the true/false value and an array of the submitted data. The true/false value will tell you if the record already tested as a match using the plugin’s normal match test. We’re going to ignore this information and just check the database for a match.

An easy way to set up a custom filter in WordPress is with a simple plugin file. In order to set this up, you’ll need to create the plugin file, then upload it to the plugins folder in your WP site. Once that’s done, you need to activate it on the plugins page in the admin.

Custom filters in WordPress require that you create a function to handle the filtering, then register the function using the add_filter() function. A plugin file must have a header, so the first few lines of text take care of that:

/**
 * Plugin Name: PDB Multiple Field Match Check
 * Description: checks a new Participants Database submissions against 
 *              the database for a matching record using multiple fields
 */
add_filter( 'pdb-incoming_record_match', 'xnau_check_for_match', 10, 2 );

The add_action() function registers the name of the callback (the function that is triggered by the filter), the priority (10) and the number of arguments it uses…in this case that’s 2: the initial check result and the data array.

Now for our function. First, we define the fields that will be used to check for a match. Then we set a couple of empty arrays that will be used to set up the database query.

$check_fields = array( 'first_name', 'last_name' ); // change this to the names of the fields you want to check
$where = array();
$values = array();

You should change that first array to name the fields you want to check for a match.

foreach ( $check_fields as $field ) {
 if ( isset( $post[$field] ) ) {
  $where[] = '`' . $field . '` LIKE "%s"';
  $values[] = trim( $post[$field] );
 }
}

Here, we are using the check fields array to put together a list of “where clauses” so when we query the database those values will be checked for a match. We only do that for fields that are present in the submission, so it’s very important that the fields you want to check for a match are required fields in the signup form. The $values array holds the actual values, which we keep in a separate array for security reasons.

Next, we count the where clauses to see if there is anything to check…if not, we return a “false” meaning there was no match.

if ( count( $where ) === 0 ) {
 //nothing to check
 return false;
}

Now, we set up the database query and see if we find any records matching all our where clauses:

$sql = 'SELECT COUNT(*) FROM ' . Participants_Db::$participants_table . ' WHERE ' . implode( ' AND ', $where );
global $wpdb;
$result = $wpdb->get_var( $wpdb->prepare( $sql, $values ) );

This is a standard bit of code using the WordPress $wpdb object to interact with the database. The $where array is converted into a series of statements joined by an “AND” so that all have to be true to make a match. The values are added into the query using the $wpdb->prepare() method which is a necessary step to secure the query against malicious code. The resulting database query will look something like this:

SELECT COUNT(*) FROM wp_participants_database WHERE `first_name` LIKE 'John' AND `last_name` LIKE 'James'

The result of this operation will simply be the number of records that match the query. Anything more than zero here means there is a matching record in the database. The return value of the function is simply the true/false answer to checking if the result is more than zero.

return $result > 0;

To create the plugin, create a blank PHP file in the text editor of your choice. The name doesn’t matter, I named it pdb-check-multiple.php in my example. Paste in the code, upload it to the plugins folder in your WP site, activate, then test it out.

Here is the complete plugin code:

<?php
/**
 * Plugin Name: PDB Multiple Field Match Check
 * Description: checks a new Participants Database submission against 
 *              the database for a matching record using multiple fields
 */
add_filter( 'pdb-incoming_record_match', 'xnau_check_for_match', 10, 2 );

/**
 * checks the incoming submission for a match in the database
 *
 * @global object $wpdb
 * @param bool $match the current match state
 * @param array $post the new submission data
 * @return bool true if there is a match
 */
function xnau_check_for_match( $match, $post )
{
 $check_fields = array( 'first_name', 'last_name' );
 $where = array();
 $values = array();
 foreach ($check_fields as $field) {
  if ( isset( $post[$field] ) ) {
   $where[] = '`' . $field . '` LIKE "%s"';
   $values[] = trim( $post[$field] );
  }
 }
 if ( count( $where ) === 0 ) {
  //nothing to check
  return false;
 }
 $sql = 'SELECT COUNT(*) FROM ' . Participants_Db::$participants_table . ' WHERE ' . implode( ' AND ', $where );
 global $wpdb;
 $result = $wpdb->get_var( $wpdb->prepare( $sql, $values ) );

 return $result > 0;
}
Posted on by

I sometimes get requests that the regex field validation allow for a blank entry or if there is an entry, it must follow a specific pattern. Like an optional email address that you want to be valid if it’s entered. This is possible, it’s just a matter of creating a regex that allows a blank alternative. This is done using two regex techniques: alternatives and anchors.

An alternative is a way to offer several alternative regex patterns to try. You simply separate your patterns with a pipe | character, and it treats them as an “or” condition.

Anchors are a way to enforce that the pattern is applied to all of the input. (They can also be used to force a pattern to match the beginning or end of the input.) Anchors give us a way to define a pattern that matches an empty input: ^$ so, we use that as the alternative to our email validity pattern:

/^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$|^$/

And that’s it: if they enter anything, it has to be a valid email address. If they enter nothing, it still validates.