Working with the WP_Error class
This article was written in 2014 👴🏼. Most of the tips here are not valid anymore and I don't recommend using any of the snippets displayed here.
I'm keeping this article here for historical reasons and to remind myself how much I've improved over the years.
Only cosmetic changes were made to this article.
Sometimes when we are coding a new feature… Actually, every time we are coding a new feature we need to know what it's happening, specifically if something it's not working the way we want to. That's the reason I tend to display lots of messages in my development environments. Even if it's not an error.
But sometimes it is an error, and when that happens it's always better to treat it like one. A simple message might not be enough, maybe we need to log it, maybe we need to stop the execution of the page. Maybe we need to use WP_Error.
In WordPress, we have a special class to work with errors, WP_Error
. it is a
pretty simple class that helps us track and log error messages, let's say we have
a contact form with two fields, Name and Email, of course we want to make sure our
visitors enter only valid email addresses and if they don't, we use WP_Error
to
let them know.
The setup
I have a simple form with only two fields, when the user submits that form,
the data will be sent through $_POST
, I will attach an action to process the form
and validate the data, like this:
1function mah_custom_shortcode( $atts, $content = null ) {2 ob_start();3?>4 <form action="" id="mah_custom_form" method="post">5 <p>6 <label for="name"><?php _e( 'Name' ); ?></label><br>7 <input type="text" id="name" name="mah_name">8 </p>9 <p>10 <label for="email"><?php _e( 'Email' ); ?></label><br>11 <input type="text" id="email" name="mah_email">12 </p>13 <?php wp_nonce_field( 'mah_nonce_action', 'mah_nonce_field' ); ?>14 <input type="submit" class="primary" name="mah_submit" value="<?php _e( 'Submit' ); ?>">15 </form>16<?php17 return apply_filters( 'mah_custom_shortcode', ob_get_clean() );18}19add_shortcode( 'mah_custom_form', 'mah_custom_shortcode' );20
This is pretty straightforward, I'm just creating a shortcode to use in my posts, that shortcode will display the form, now let's see the process function:
1function mah_process_function() {2 if ( isset( $_POST[ 'mah_submit' ] ) && wp_verify_nonce( $_POST[ 'mah_nonce_field' ], 'mah_nonce_action' ) ) {3 // Start validation and save it in a variable4 $email = is_email( $_POST[ 'mah_email' ]) // Check if it's a valid address5 ? sanitize_email( $_POST[ 'mah_email' ] ) // Is valid6 : new WP_Error( 'mah_email_error', __( 'Please enter a valid email address' ) );78 // Check if there was an error9 if ( is_wp_error( $email ) ) {10 wp_die( $email->get_error_message(), 'mah_form_error' );11 }12 }1314}15add_action( 'init', 'mah_process_function' );16
- First we check if the value for
mah_submit
is set, that means the form has been submitted, then we verify the nonce field to make sure it is still valid. - We use
is_email
to validate the email address, this function is provided by wordpress and returnstrue
if it's valid. - If the email was valid, we assign that value to the
$email
variable, after usingsanitize_email
to clean the address just in case. - If the email was not valid, the value we assign to the
$email
variable will be a new error object. -mah_email_error
is the code we use for this specific error, when we work with multiple errors it's a good idea to give them a code. - Then we can give specify the message that will be use when we display this error to the user.
Now, we have created our error, but we still need to display it to the user.
Luckily, the WP_Error
class also provides a function for this: is_wp_error
.
This function checks the data passed and if it's an error object it returns true
.
After that, it's easy to use wp_die
to display the error message.
Working with several error messages
This piece of code was useful if we only need to display one error message at a time, but what if I wanted to validate the Name field as well and display both messages in the same screen?
I could use the same approach, but then I would have two different error objects, I just want one, so I need to have ready before validating the data.
1function mah_process_function() {2 if ( isset( $_POST[ 'mah_submit' ] ) && wp_verify_nonce( $_POST[ 'mah_nonce_field' ], 'mah_nonce_action' ) ) {3 // Start error object4 $mah_error = new WP_Error();56 // Validate email7 if ( is_email( $_POST[ 'mah_email' ] ) ) { // Check if it's a valid address8 $email = sanitize_email( $_POST[ 'mah_email' ] ); // Is valid9 // Add new error to the object10 } else {11 $mah_error->add( 'mah_email_error', __( 'Please enter a valid email address' ) );12 }1314 // Validate name15 if ( ! is_numeric( $_POST[ 'mah_name' ] ) ) { // no numeric values allowed16 $name = sanitize_text_field( $_POST[ 'mah_name' ] ); // clean it up17 } else {18 $mah_error->add( 'mah_name_error', __( 'Name can not be a number') );19 }202122 // Check if there was an error23 if ( is_wp_error( $mah_error ) ) {24 wp_die( $mah_error, __( 'Form Error' ) );25 }26 }2728}29
While it's pretty similar, id does have a few differences, let's break it down:
- Now I declare
$mah_error
at the beginning, this will be empty since I haven't added any errors yet. $mah_error->add
: Instead of returningnew WP_Error
I simply use the add method to insert a new error to the list, I do the same thing with the next field.- Even if I declared
$mah_error
as aWP_Error
object at the beginning, it will not be treated as an error until I add at least one error to the list, so is_wp_error will still be valid if empty. wp_die
can except either a string like in the previous example, or the fullWP_Error
object, if I send the object it will display all the errors in the list.
This was just a simple introduction to the WP_Error
class, I recommend reading
through the codex and try to use it as often as possible and check out the rest
of methods, there's really useful stuff in there.