• About Us
    • New York
  • Work
  • Capabilities
  • Careers
  • Technology
  • Blog
  • Contact Us
  • About Us
    • New York
  • Work
  • Capabilities
  • Careers
  • Technology
  • Blog
  • Contact Us
August 18, 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.

data validationescapingSanitizingwordpresswordpress data
Previous
Next

Latest White Papers

  • Shifting Plans for 2020 & Beyond
  • Game On: How Brands Can Log Into A Diverse Multi-Billion Dollar Industry
  • What CCPA Means For Brands
  • How Google is Improving Consumer Data Privacy
  • Ways to Prepare for the Cookieless Future
  • See all White Papers

Featured Posts

  • Ad Age Names PMG #1 Best Place to Work in 2021
  • Hindsight 2020 & Looking Ahead to 2021
  • Preparing for Streaming’s Growth & The Future of TV Buying
  • MediaPost Names PMG Independent Agency of the Year
  • PMG Client Portfolio Trends During Amazon Prime Day 2020

Categories

  • Consumer Insights
  • Content
  • Creative Design
  • Data Analytics
  • Development
  • Digital TV & Video
  • Ecommerce
  • Industry News
  • Local
  • Mobile
  • Paid Search
  • PMG Culture
  • Programmatic & Display
  • SEO
  • Social Media
  • Structured Data
Fort Worth

2845 West 7th Street
Fort Worth, TX 76107

Dallas

3102 Oak Lawn Avenue
Suite 650
Dallas, TX 75219

Austin

823 Congress Avenue
Suite 800
Austin, TX 78701

London

33 Broadwick Street
London
W1F 0DQ

New York

120 East 23rd Street
New York, NY 10010

Get in touch

(817) 420 9970
info@pmg.com

Subscribe to the PMG Newsletter
© 2021 PMG Worldwide, LLC, All Rights Reserved
  • Contact
  • Privacy Policy
 Tweet
 Share
 Tweet
 Share
 Tweet
 Share
 LinkedIn
We and our partners use cookies to personalize content, analyze traffic, and deliver ads. By using our website, you agree to the use of cookies as described in our Cookie Policy.