Roblog

home about me text processing with ruby

Accessing WordPress from Ruby: Part III

10 November 2013

Background

In part one of this series I looked at using ruby-wpdb to access a WordPress database from Ruby. In part two, I gave some examples of how you might achieve some common tasks with ruby-wpdb. Now, in part three, I’m going to look at some plugin-specific functionality that ruby-wpdb provides: integration with Gravity Forms.

Gravity Forms is a hugely popular add-on for WordPress which gives you, in essence, a way to create custom forms, displayed on your website, that store the data submitted to them. But they can be much more powerful than that: they can giving you integration with CRM systems, communicate with payment gateways like PayPal, register users for your site, and more — cutting a lot of the CRUD drudge work out of adding new functionality to your WordPress site.

The drawbacks

One of the drawbacks of Gravity Forms’ flexibility, though, is that its database structure has to be very abstract to cope with the infinite variety of form structures you might throw at it.

If you want to look at entries, then, you’re required to construct hefty database queries containing large numbers of JOIN statements, one for each field in your table. For example, to fetch the entries in a typical contact form, you might have to write the following query:

SELECT
	l.date_created,
	ld1.value AS first_name,
	ld2.value AS last_name,
	ld3.value AS email,
	ld4.value AS message

FROM wp_rg_lead l

JOIN wp_rg_lead_detail ld1 ON l.id = ld1.lead_id AND ld1.field_number = 1
JOIN wp_rg_lead_detail ld2 ON l.id = ld2.lead_id AND ld2.field_number = 2
JOIN wp_rg_lead_detail ld3 ON l.id = ld3.lead_id AND ld3.field_number = 3
JOIN wp_rg_lead_detail ld4 ON l.id = ld4.lead_id AND ld4.field_number = 4

WHERE l.form_id = 1

That’s just for a relatively simple four-field form; already things are getting hairy, and it’s clear that things are only going to get more painful from here on in.

ruby-wpdb’s approach

ruby-wpdb approaches this by modelling GravityForms entries as though they were first-class data structures, the sort of thing that normally get their own database tables.

So, it gives you a class for each of your forms, allows you to query for entries based on whatever criteria you like, and allows you to access fields as though they were regular properties.

Let’s take a look at how you can use this.

Accessing your forms

For each of your forms, ruby-wpdb creates a model. Models are named after your form, with non-alphanumeric characters removed, leading numbers removed, and CamelCased. So, some sample transformations would be:

Contact Form      => ContactForm
Rob's signup form => RobsSignupForm
Form #2           => Form2
1. Registration   => Registration

…hopefully you get the picture from there!

These classes are within WPDB::GravityForms, so the “Contact Form” example above would be accessible as WPDB::GravityForms.ContactForm.

Filtering entries

Just like ruby-wpdb allows you to do with posts, comments, and other objects, you can filter entries to your forms by whatever criteria you like.

So, sticking with our contact form example, you might want to filter based on who the messages are from. To print all of the messages that come from bob@example.com, then, you could write:

from_bob = WPDB::GravityForms.ContactForm.where(email: "bob@example.com").all

You can also filter on data attached to the lead itself. For example, to fetch only messages sent in 2013, you’d simply call:

recent = WPDB::GravityForms.ContactForm.where { date_created >= DateTime.new(2013, 1, 1) }.all

Accessing fields

ruby-wpdb will take care of mapping fields to properties for you. You can see that above; we were able to filter on a property called email, even though that referred to the value of one of the fields in the form.

ruby-wpdb names these fields according to the labels they have within GravityForms: so, if your field is called “First name:”, this becomes first_name; if it’s called “Email” it becomes email; and so on.

So, to completely display the last five entries from our contact form, we could use the following code:

WPDB::GravityForms.ContactForm.limit(5).each do |entry|
  puts "Message from #{entry.first_name} #{entry.last_name} <#{entry.email}>:"
  puts entry.message
  puts "==\n\n"
end

That’s it! You can obviously combine this with the filtering to drill down into your GravityForms data, pulling out only the specific fields from only the specific entries that you want.


Hopefully this illustrates how ruby-wpdb can help make exploring and analysing — or just exporting — your GravityForms data a cinch.

It’s something I find myself doing a lot. I either want a quick insight into data and don’t want to write something and deploy it to the live site; or else I want to examine something in detail, and don’t want to slow down the live site while I’m running it; or else I want to run it regularly on a cron job, and don’t want the overhead of the whole website with it.

In those situations, and lots more I’m sure, ruby-wpdb’s GravityForms functionality can help make your life a little bit easier.