• Services
  • About
  • Clients
  • Team
  • Careers
  • Blog
  • Contact
  • Services
  • About
  • Clients
  • Team
  • Careers
  • Blog
  • Contact
18 August, 2011

WordPress Data Validation for Dummies (Part Two)

Posted by Christopher Davis

In the first part of this series of WordPress data validation, we covered verifying intent and permissions. This article covers the other side of data validation: cleaning the data on the way in and escaping it on the way out.

Fortunately WordPress comes with a variety of built in data validation functions. We have two directions to cover: data going in, and data coming out.

Making Life Easier

You can make your life much easier by using built in WordPress functions to insert things into your database. In other words, use wp_insert_post instead of interacting directly with the database. There are many other examples as well. If you do find yourself needing to interact directly with the database, always use the wpdb class.

It happens to come built in with a few handy functions: insert and update, which work exactly like you’d think. If you need to take user data and insert it, always use prepare which handles escaping the data to prevent SQL injection attacks.

Escaping Output

WordPress comes with a variety of functions that start with esc_ followed by a data type. The esc_* family of functions is your best friend. Need to make sure a URL is really a URL? esc_url can do that. Want to encode HTML entities like quotes or double-quotes for an HTML attribute? esc_attr does that.

The codex entry on data validation is great, so I won’t rehash it all here.

To return to the “making your life easier” theme above, always escape your data late. As in right before it gets printed to the screen. This helps keep you sane: you can see right where the escaping happens and don’t have to think back to whether or not the data was escaped earlier.

// hundreds more lines of code..

echo $var;

1
2
3
4
5
6
7
// Don’t do this
$var=‘<script>alert(‘evil string’);</script>‘;
$var=esc_html($var);
// hundreds more lines of code..
echo$var;

// hundreds more lines of code

echo esc_attr( $var );

1
2
3
4
5
6
// Much better
$var=‘<script>alert(‘evil string’);</script>‘;
// hundreds more lines of code
echoesc_attr($var);

Sanitizing Input

Any of the functions above can be used to santize data on the way in. In addition, PHP, the language in which WordPress is written, has a host of functions that come in handy for cleaning and validating data. You could use strip_tags to get rid of all the HTML, or write an elaborate series of regular expressions to only remove certain values.

WordPress also provides functions like is_email (return true if the string is an email address) and balanceTags (fixes terrible HTML). wp_kses is one of the most powerful data sanitation functions in the WordPress arsenal. It a string and an array of allowed HTML tags as arguments and strips all but the allowed HTML tags from the string.

A word of caustion on some data validation functions: they’re expensive. Running through multiple regular expressions (ala wp_kses) or something similar is an intensive process. So use those sorts of functions on the data’s way in.

A Practical Example: Adding a Post Tagline

In part one we covered how verifying intent and permissions could be used in a custom meta box. Let’s take that example a step further.

Our goal: add a custom write box to page screens that allows a user to specify a page tagline. In fact, if you check out one of our pages, you’ll see such a plugin in action!

Wordpress Page Tagline Data Validation

If you’re unfamiliar with creating meta boxes, please check out this tutorial I wrote for WP Tuts+, as I’ll only gloss over the concepts here.

First step, adding our meta box. I like to write my plugin functions inside classes, which saves me from extremely long function names.

}// Add the metabox!
function meta_box()
{
add_meta_box( ‘pmg-tagline-box’, __( ‘Tagline’ ), array( &$this, ‘meta_box_cb’ ), ‘page’, ‘normal’, ‘high’ );
}// The metabox callback from the third argument of add_meta_box
function meta_box_cb( $post )
{
// get our value for later
$tagline = get_post_meta( $post->ID, ‘_pmg_page_tagline’, true );// add a nonce field
wp_nonce_field( ‘pmg_tagline_save’, ‘pmg_tagline_nonce’, false );
?>
<table class=”form-table”>
<tr>
<th scope=”row”>
<label for=”pmg_page_tagline_in”><?php _e( ‘Page Tagline’ ); ?></label>
</th>
<td>
<input type=”text” class=”widefat” id=”pmg_page_tagline_in” name=”pmg_page_tagline_in” value=”<?php echo esc_attr( $tagline ); ?>” />
</td>
</tr>
</table>
<?php
}
}
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
26
27
28
29
30
31
32
33
34
35
36
37
<?php
classpmgAddPageTagline
{
    function__construct()
    {
        add_action(‘add_meta_boxes’,array(&$this,‘meta_box’));
        
    }
    
    // Add the metabox!
    functionmeta_box()
    {
        add_meta_box(‘pmg-tagline-box’,__(‘Tagline’),array(&$this,‘meta_box_cb’),‘page’,‘normal’,‘high’);
    }
    
    // The metabox callback from the third argument of add_meta_box
    functionmeta_box_cb($post)
    {
        // get our value for later
        $tagline=get_post_meta($post->ID,‘_pmg_page_tagline’,true);
        
        // add a nonce field
        wp_nonce_field(‘pmg_tagline_save’,‘pmg_tagline_nonce’,false);
        ?>
        <table class=“form-table”>
            <tr>
                <th scope=“row”>
                    <label for=“pmg_page_tagline_in”><?php_e(‘Page Tagline’);?></label>
                </th>
                <td>
                    <input type=“text”class=“widefat”id=“pmg_page_tagline_in”name=“pmg_page_tagline_in”value=“<?phpechoesc_attr($tagline);?>“/>
                </td>
            </tr>
        </table>
        <?php
    }
}

That takes care of adding the metabox, include a nonce for use to check in our save function. To actually save the data, we have to add another function and hook it into edit_post.

// Hook into edit_post
add_action( ‘edit_post’, array( &$this, ‘save’ ) );
}

// snip snip … The meta box code from above here

function save( $post_id )
{
// make sure our nonce is set and verifies or bail
if( ! isset( $_POST[‘pmg_tagline_nonce’] ) || ! wp_verify_nonce( $_POST[‘pmg_tagline_nonce’], ‘pmg_tagline_save’ ) ) return;

// make sure the current user can edit the post, or bail
if( ! current_user_can( ‘edit_post’ ) ) return;

// make sure our tagline is set, then strip any html from it and esc all other ” and ‘ characters
if( isset( $_POST[‘pmg_page_tagline_in’] ) )
update_post_meta( $post_id, ‘_pmg_page_tagline’, esc_attr( strip_tags( $_POST[‘pmg_page_tagline_in’] ) ) );
}
} // end class

// initialize our class to add the actions
new pmgAddPageTagline();

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
26
27
28
29
<?php
classpmgAddPageTagline
{
    function__construct()
    {
        add_action(‘add_meta_boxes’,array(&$this,‘meta_box’));
        
        // Hook into edit_post
        add_action(‘edit_post’,array(&$this,‘save’));
    }
    
    // snip snip … The meta box code from above here
    
    functionsave($post_id)
    {
        // make sure our nonce is set and verifies or bail
        if(!isset($_POST[‘pmg_tagline_nonce’])||!wp_verify_nonce($_POST[‘pmg_tagline_nonce’],‘pmg_tagline_save’))return;
        
        // make sure the current user can edit the post, or bail
        if(!current_user_can(‘edit_post’))return;
        
        // make sure our tagline is set, then strip any html from it and esc all other ” and ‘ characters
        if(isset($_POST[‘pmg_page_tagline_in’]))
            update_post_meta($post_id,‘_pmg_page_tagline’,esc_attr(strip_tags($_POST[‘pmg_page_tagline_in’])));
    }
}// end class
// initialize our class to add the actions
newpmgAddPageTagline();

So a few steps from part one. First, verify the nonce in our save function. Then we check to make sure the current user can edit the post.

Once we’ve checked those two things, we check to make sure the tagline $_POST index is set then save the data, stripping out all html tags and escaping quotes and double quotes along the way.

To display the data on the front end, the code will be very similar to what was included in the meta_box_cb function:

1
2
3
4
5
6
7
8
<?php
// somewhere in the loop, get the data
$tagline=get_post_meta($post->ID,‘_pmg_page_tagline’,true);
?>
<div<?phppost_class();?>>
    <h1><?phpthe_title();?></h1>
    <h2><?phpechoesc_html($tagline);/* Escape on the way out! */?></h2>
    ...

That’s a lot of Escaping

Yes, it is. It might even be too much. Do we really even need to call esc_attr() on the way in and out? Probably not. But it’s also no hurting anything. Escape and validate everything, and you’ll always be (mostly) safe. Here’s the entire plugin from above.

Categories: Development
Tags: data validation, escaping, Sanitizing, wordpress, wordpress data
Tweet

Related Posts

WordPress Data Validation for Dummies (Part One)
Crawl Rate Tracker & Multisite WordPress Installs
Three Ways to Make Your WordPress Category Pages Better

About the author

Christopher Davis

A classical guitarist by training, Chris began creating software during grad school to learn more about managing WordPress sites. Since then he's moved on to building full fledged applications using PHP (using Silex, Symfony, and Doctrine), Python (Django, Flask, SQLAlchemy), or any tool more suited for the job. Chris is passionate about testing and software quality and helps PMG's internal tools hum along smoothly.
Read More

Search

Featured Posts

  • Why We Love Texas
  • Who are China’s E-Commerce Titans?
  • Exploring the Current Shoppable Media Opportunities
  • The European Union’s General Data Protection Regulation
  • Our Favorite Digital Audio Advertising Solutions: Spotify vs. Pandora

Categories

  • All Posts
  • Content
  • Creative Design
  • Data Analytics
  • Development
  • Display
  • Industry News
  • Local
  • Mobile
  • Paid Search
  • PMG Culture
  • SEO
  • Social Media
  • Structured Data
  • Video

Authors

Read More About Us Here »

|
2845 W 7th St
Fort Worth, TX 76107
T: 817.420.9970
info@pmg.com
Privacy Policy
© PMG Worldwide LLC. All Rights Reserved.