WordPress provides filters for sanitizing and authenticating your custom post meta. These filters have been around since 3.3 — and until now — were unknown to me. I happened to be reading Tadlock’s content-type-standards repository on Github and noticed some references to register_meta().
What Is register_meta?
The register_meta() function was added in WordPress 3.3 and will simplify adding sanitize and authentication callbacks for your custom meta. By calling this function and providing callbacks, it will handle appending your callbacks to the appropriate filters.
Let’s take a look at the function.
// WordPress core function: wp-includes/meta.php
/**
* Register meta key
*
* @since 3.3.0
*
* @param string $meta_type Type of meta
* @param string $meta_key Meta key
* @param string|array $sanitize_callback A function or method to call when sanitizing the value of $meta_key.
* @param string|array $auth_callback Optional. A function or method to call when performing edit_post_meta, add_post_meta, and delete_post_meta capability checks.
*/
function register_meta( $meta_type, $meta_key, $sanitize_callback, $auth_callback = null ) {
if ( is_callable( $sanitize_callback ) ) {
add_filter( "sanitize_{$meta_type}_meta_{$meta_key}", $sanitize_callback, 10, 3 );
}
if ( empty( $auth_callback ) ) {
if ( is_protected_meta( $meta_key, $meta_type ) ) {
$auth_callback = '__return_false';
} else {
$auth_callback = '__return_true';
}
}
if ( is_callable( $auth_callback ) ) {
add_filter( "auth_{$meta_type}_meta_{$meta_key}", $auth_callback, 10, 6 );
}
}
The function has four parameters; One being optional.
- $meta_type This is the type of meta. Most of the time this will be `post`, unless you are working with a custom meta table.
- $meta_key The meta key.
- $sanitize_callback The meta value will run through the sanitize callback function before saving.
- $auth_callback If provided, the meta will be hidden from Custom Fields meta box with the post editor. This has the same affect as pre-pending the meta key name with an underscore.
A simple example
Here is a simple example for registering a meta key.
add_action( 'init', 'register_my_sample_meta' );
/**
* Callback for WordPress 'init' action.
*
* Register the post meta.
*
* @uses register_meta()
* @see https://codex.wordpress.org/Function_Reference/register_meta
*/
function register_my_sample_meta() {
register_meta(
'post',
'sample_count',
'sanitize_sample_count_meta',
'auth_sample_count_meta'
);
}
Simply calling register_meta()
within a callback for init
will suffice. My sample meta key will be sample_count
.
Optional sanitize callback
I wish I had knowledge of this filter as it would have saved me time. If you save post meta in more than one place, there is a good chance you have duplicate code. Using this filter allows meta value to be sanitized in once place and reduce that sneaky duplicate code.
/**
* Callback for WordPress register_meta() sanitize parameter.
*
* Sanitize the 'sample_count' meta value before saved to the database.
*
* @see https://codex.wordpress.org/Function_Reference/register_meta
*
* @uses absint()
* @see https://codex.wordpress.org/Function_Reference/absint
*
* @param mixed $meta_value The meta value.
* @param string $meta_key The meta key.
* @param string $meta_type The meta type.
*
* @return mixed The meta value.
*/
function sanitize_sample_count_meta( $meta_value, $meta_key, $meta_type ) {
return absint( $meta_value );
}
Optional authentication callback
In WordPress, you can pre-pend your meta keys with an underscore to prevent them from being visible within the Custom Fields meta box. This prevents all users from the ability to see the meta values in the Custom Fields meta box.
This callback determines who sees what within the Custom Fields meta box. This allows your meta keys to not have the pre-pended underscore. My example allows administrators to see the meta value.
/**
* Callback for WordPress register_meta() sanitize parameter.
*
* Determine if the current meta key and value should be visible within the
* WordPress post editor Custom Fields meta box.
*
* @see https://codex.wordpress.org/Function_Reference/register_meta
*
* @uses current_user_can()
* @see https://codex.wordpress.org/Function_Reference/current_user_can
*
* @param boolean $allowed True if allowed to view the meta field by default, false if else.
* @param string $meta_key The meta key.
* @param integer $post_ID The post ojbect ID.
* @param integer $user_id The user ID.
* @param string $cap The meta capability.
* @param array $caps An array of capabilities.
*
* @return boolean True if allowed to view the meta field by default, false if else.
*/
function auth_sample_count_meta( $allowed, $meta_key, $post_ID, $user_id, $cap, $caps ) {
if ( ! current_user_can( 'edit_others_posts' ) ) {
$allowed = false;
}
return $allowed;
}
Remember, this is optional.
All Together Now
Here is the full example. The sanitize callback is what I find to be the biggest advantage here. The custom authentication is your choice.
add_action( 'init', 'register_my_sample_meta' );
/**
* Callback for WordPress 'init' action.
*
* Register the post meta.
*
* @uses register_meta()
* @see https://codex.wordpress.org/Function_Reference/register_meta
*/
function register_my_sample_meta() {
register_meta(
'post',
'sample_count',
'sanitize_sample_count_meta',
'auth_sample_count_meta'
);
}
/**
* Callback for WordPress register_meta() sanitize parameter.
*
* Sanitize the 'sample_count' meta value before saved to the database.
*
* @see https://codex.wordpress.org/Function_Reference/register_meta
*
* @uses absint()
* @see https://codex.wordpress.org/Function_Reference/absint
*
* @param mixed $meta_value The meta value.
* @param string $meta_key The meta key.
* @param string $meta_type The meta type.
*
* @return mixed The meta value.
*/
function sanitize_sample_count_meta( $meta_value, $meta_key, $meta_type ) {
return absint( $meta_value );
}
/**
* Callback for WordPress register_meta() sanitize parameter.
*
* Determine if the current meta key and value should be visible within the
* WordPress post editor Custom Fields meta box.
*
* @see https://codex.wordpress.org/Function_Reference/register_meta
*
* @uses current_user_can()
* @see https://codex.wordpress.org/Function_Reference/current_user_can
*
* @param boolean $allowed True if allowed to view the meta field by default, false if else.
* @param string $meta_key The meta key.
* @param integer $post_ID The post ojbect ID.
* @param integer $user_id The user ID.
* @param string $cap The meta capability.
* @param array $caps An array of capabilities.
*
* @return boolean True if allowed to view the meta field by default, false if else.
*/
function auth_sample_count_meta( $allowed, $meta_key, $post_ID, $user_id, $cap, $caps ) {
if ( ! current_user_can( 'edit_others_posts' ) ) {
$allowed = false;
}
return $allowed;
}