Turning WordPress into a fancy form processor

Yes, I know. Five+ years of development. An approach to open-source content management that is at the same time refreshing and inspired. One of the top blogging tools in the world.

And now, WordPress processes my forms for me.


Preempting Genius

The WordPress Plugin API provides hooks into the execution of its code via Actions. As someone views a page on your site, a chain of events is triggered until the requested page is displayed. All along this chain, WordPress notifies itself that it is completing certain Actions.

Plugin developers can use the fact that WordPress has just triggered one of its core functions and execute one of the plugin functions as well. In this way, your plugin can insinuate itself quite deeply inside the main WordPress package.

The earliest Action hook that I could find is named init. The WordPress Codex describes this Action:

Runs after WordPress has finished loading but before any headers are sent. Useful for intercepting $_GET or $_POST triggers.

Translation: Runs after WordPress loads its function environment but before it has displayed anything in the user’s browser. Use our software for your own nefarious goals.

Amazing. They suggest that you use this to turn their software into something else entirely. With a minimum of 8 lines of code, I subverted my favorite open-source software into a simple forms processor that had the power (and data set) of my entire WordPress tool behind it.

The Method

Using WordPress Actions is basically a two step process:

  1. Write a PHP function that you want to be triggered at some point in the WordPress execution chain.
  2. Use the add_action() function to inform WordPress of a) the core function you want to piggy-back on, and b) the name of the function you wrote in step 1.

Write the Function

I wanted people to be able to use my WordPress as the action URL in HTML forms. Something like:

<form action="http://3.17.80.149/?form_submit=123" method="post">

I needed a function that could check for a particular attribute each time my site is accessed, and if the attribute is there, preempt everything else WordPress does (such as loading my actual site) and instead process the form that is (hopefully) being submitted.

function form_submit() {
 $form_ID = $_REQUEST['form_submit'];
 if ( !empty($form_ID) ) {
  form_do_submit($form_ID, $_REQUEST);
  exit;
 }
}

Note: I’m only checking to see if some value got passed in “form_submit”. A well-written function would validate the information and only process the form if useful information was being passed. I could even go so far as to make sure that the origin of the submission is allowed. But that is for another post.

The form_submit() function checks to see if the query item “form_submit” was passed to WordPress. In this case, the value of the query item is the form ID number that I will use in processing. If the query item “form_submit” was submitted, I execute a the function form_do_submit() (I put it in its own function just for cleanliness of code) that actually processes the submitted $_REQUEST object (i.e., the contents of the form the user just submitted).

And here is the beautiful part: While I am processing the submitted form, I can use any WordPress function I want. I can store and retrieve data from the WordPress database. This proves quite useful.

Let WordPress in on the Secret

Now, to tell WordPress when I want it to execute this function, I use the add_action() function to my plugin’s main execution space. This ensures that I will always trigger my query check each time my plugin is loaded no matter what.

add_action('init', 'form_submit', 1);

As soon as WordPress loads its environment, my form_submit() function is executed. The ‘1’ just tells WordPress to execute my function as early as possible (a ‘10‘ would have told WordPress to execute my function as late as possible).

Jump Ship

Why does WordPress run my function and not load my website? The handy exit command I put in my form_submit() function. As soon as I’ve processed my form, I just tell WordPress to take a coffee break. And we’re done!

The Code

Here is the code in my plugin’s main file:

function form_submit() {
 $form_ID = $_REQUEST['form_submit'];
 if ( !empty($form_ID) ) {
  form_do_submit($form_ID, $_REQUEST);
  exit;
 }
}

add_action('init', 'form_submit', 1);