1

I'm on a plugin, where I want to provide a way to my clients to filter data before saving. I know the best way is to provide a filter hook. So I introduced a new filter hook to filter all the post data, including post data and post meta data.

But then I found that, there's already a hook available for post data. So I realized that, it's unnecessary to introduce another hook to filter post data.

Now I'm wondering is there any such hook available for post meta data? If so, then I won't need to provide any new filter hook, I can direct my users to those filter hooks from the core.

I found an article by Igor Benic about metadata filter hook. I tried with the following code and some of its variances:

function wpse22728_meta($check, $object_id, $meta_key, $meta_value, $unique) {
    if( get_post_type($object_id) == 'mycpt' ) {
        if( $meta_key == 'mycustomkey' ) {
            // var_dump($meta_value); //value going to store is: 'old_value'
            return $meta_value = 'new_value';
        }
    }
}

add_filter('add_post_metadata', 'wpse22728_meta', 20, 5);
add_filter('update_post_metadata', 'wpse22728_meta', 20, 5);

But actually failed.

How can I filter meta data before storing them? Is there any other hook available?

2

The add_post_metadata and update_post_metadata filters are meant to allow filtering whether a specific meta data should be saved (added/updated) or not, only. The default value (of $check) is a null, and if you return anything other than exactly null (i.e. !== null), the meta data will not be saved (into the database).

However, the add_metadata() function (used by add_post_meta()) and the update_metadata() function (used by update_post_meta()), both use sanitize_meta() for sanitizing the meta value (although sanitization are done via filters and not the function itself), and the Codex says:

Applies filters that can be hooked to perform specific sanitization procedures for the particular metadata type and key. Does not sanitize anything on its own. Custom filters must be hooked in to do the work. The filter hook tag has the form "sanitize_{$meta_type}_meta_{$meta_key}".

So in your case, the $meta_type would be post, and $meta_key would be mycustomkey, and you could filter the value like so:

add_filter( 'sanitize_post_meta_mycustomkey', function( $value ){
    return 'new_value';
} );

Check also this example.

Drawback

Unfortunately, the sanitize_meta() doesn't pass the "object" (e.g. post or user) ID to the sanitization filters (i.e. functions hooked to sanitize_{$meta_type}_meta_{$meta_key}).

There's a way to overcome that, but it will depend on your code/context, so I can't explain the "how".

UPDATE

Actually, there's a tricky (or hacky?) solution, which works fine with the add_post_metadata and update_post_metadata filters. But I'm not including the code here (yet), and you can find it on Pastebin.

  • 1
    I think I should provide a custom filter hook for my meta data only. The post data will be filtered with wp_insert_post_data and meta data will be filtered using my custom hook. Otherwise it'd be too messy for my clients to do a simple filter. BTW thank you very much for the detailed answer and workaround. It surely has its merit. – Abirvab Sep 28 '18 at 12:17
  • I agreed with what you said about providing a custom filter hook (and I actually wanted to suggest that, but ended up not saying so). And, you're very welcome. =) – Sally CJ Sep 28 '18 at 13:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.