What I’m trying to do:
- Add new user meta fields that can be updated when the user edits their profile
- Validate them correctly when the form is submitted
What I’ve done:
I have successfully added the fields to the user editting form and have them being updated to the options database as follows:
public function setup_user_meta() {
// Show the fields when editing or showing
add_action('show_user_profile', array($this,'show_user_meta'));
add_action('edit_user_profile', array($this,'show_user_meta'));
// Update the fields
add_action('personal_options_update', array($this,'process_option_update'));
add_action('edit_user_profile_update', array($this,'process_option_update'));
}
.
public function show_user_meta($user) {
?>
<h3>Player Information</h3>
<table class="form-table">
<tbody>
<tr>
<th><label for="cuhc-description">Description</label></th>
<td><textarea name="cuhc-description" id="cuhc-description" rows="5" cols="30"><?php echo esc_textarea(get_the_author_meta('cuhc-description', $user->ID)); ?></textarea>
</tr>
</tbody>
</table>
<?php
}
.
public function process_option_update($userid) {
update_user_meta($userid, 'cuhc-description', ( isset($_POST['cuhc-description']) ? $_POST['cuhc-description'] : '' ) );
}
What I want:
This works, however I have a number of different fields and I want to validate them in process_option_update()
, eg: checking they’re a number and if not returning an error to the user.
How do I tell WordPress there is an error and not to continue to act on the form? And where do I echo or send the error(s)? WordPress also appears to use javascript validation within the user update page – how do I piggy-back onto this instead of doing my own one?
After examining the code and much trial and error, I have a solution:
There is a filter –
user_profile_update_errors
– that is called in the filewp-admin/includes/user.php
just after WordPress does it’s own input validation. This filter allows plugins to return their own errors by adding them to a referencedWP_Error
class. If any errors exist after the filter returns, WordPress displays them and does not insert/update any data.My solution is to therefore ditch the
personal_options_update
andedit_user_profile_update
action hooks (as these are called BEFORE theuser_profile_update_errors
filter, immediately after the form is submitted) and to use theuser_profile_update_errors
filter to:$_POST
,update_user_meta($ID,
.$key, $value);
Alternatively, one could use the
profile_update
oruser_register
action hooks (these are called near the end, just after the WordPress user data has been added to the database) to add our custom data to the options database. This splits up the validation and the database insertion, but data would have to be passed between the validation and insertion functions with a globalstdClass
or array, which I considered more ugly.I hope this helps someone else!