global function to apply filter to custom field

I have an action hook which works perfectly for the_content.
I would like to apply the same hook anytime a handful of custom_fields are requested.

The custom fields are 1) myfieldone 2) myfieldart 3) myfieldestion
So lets just take one of those – “myfieldone”
Is there a way – where anytime “myfieldone” custom field is requested, that I could filter the value (the_content) of THAT custom field?

Read More

I would assume it would be as simple as

add_filter('myfieldone', 'my_add_a_class_function', 10,8);
//or 
add_action('myfieldone', 'my_add_a_class_function');

However neither of those have any effect.

I’ve also tried to globally apply it to all get_meta, get_meta_key

add_filter('get_meta', 'my_add_a_class_function', 10,8);
add_filter('get_meta_key', 'my_add_a_class_function', 10,8);
//no such luck. What am I missing?

So I basically want to do

$which_meta_key = 'myfieldone';
add_action($which_meta_key, 'my_add_a_class_function');

Here’s how I’m doing it with the_content.

add_action('the_content', 'my_add_a_class_function');
function my_add_a_class_function($content){

    $sample_html = $content;    

// grab all the matches for img tags and exit if there aren't any
if(!preg_match_all('/<img.*/>/i', $sample_html, $matches))
  exit("Found no img tags that need fixingn");

// check out all the image tags we found (stored in index 0)
//print_r($matches);

// iterate through the results and run replaces where needed
foreach($matches[0] as $string){
    // keep this for later so that we can replace the original with the fixed one
    $original_string = $string;

    // preg_replace only replaces stuff when it matches a pattern so it's safe to
    // just run even if it wont do anything.

    $classes = 'TEST'; // separated by spaces, e.g. 'img image-link'
    // check if there are already classes assigned to the anchor
    if ( preg_match('/<img.*? class=".*?">/', $string) ) {
      $string = preg_replace('/(<img.*? class=".*?)(".*?>)/', '$1 ' . $classes . '$2', $string);
    } else {
      $string = preg_replace('/(<img.*?)>/', '$1 class="' . $classes . '" >', $string);
    }

    // now replace the original occurence in the html with the fix
    $sample_html = str_replace($original_string, $string, $sample_html);  

} 

return $sample_html;    
}

UPDATE:
The below custom meta key call appears to work well.
However – I am getting the “found no img tags that need fixing” {if /EXIT} message

... // pass the custom_meta content to my filter. 
$sample_content = $content
print_r($sample_content);

//YIELDS
    <p><img class="alignleft" width="175" height="175" src="/wp-content/uploads/2013/04/brother-in-law.gif" alt="">
Peter, My brother-in-law informed me that he has a new job at IBM.</p>

However before I apply the filter – I check to see that there are images to filter. and exist if not.
Apparently, no images are being found – although by the print_r – – an image tag clearly exists.

if(!preg_match_all('/<img.*/>/i', $sample_html, $matches))
  exit("Found no img tags that need fixingn");

// YIELDS:
Found no img tags that need fixing

//however it does echo out my custom field html code, the image and paragraph text display - - because thats part of the get_meta_data - where I initially request the custom field.

SO – QUESTION – is this a simple regex issue? Do I have mal-formed regex for my

preg_match_all ('/<img.*/>/i'...

OR – do I need to apply a “to_string” filter to the content so it finds an image as an image rather than just text

Related posts

Leave a Reply

2 comments

  1. I have no experience with the get_{$meta_type}_metadata filter either, hence all I can offer is a further approach to a possible workaround:

    Iff you don’t need to satisfy third parties using get_post_meta, but only want to use the filter in your own code, you could write a custom wrapper for get_post_meta, which in turn will accept a filter:

    function wpse94639_get_post_meta( $post_id, $key = '', $single = false ) {
        $metadata = get_post_meta( $post_id, $key, $single );
        return apply_filters( 'wpse94639', $metadata );
    }
    

    Now you could use add_filter( 'wpse94639', 'my_add_a_class_function' );.

    This is only a viable solution, iff you don’t need to filter results when some other theme/plugin is using the original get_post_meta, obviously.

  2. How would I apply the same filter to meta key value?

    What you are trying to do– add_filter('myfieldone', 'my_add_a_class_function', 10,8);— won’t work. You can’t just make up a hook. They have to be implemented somewhere in the source with apply_filters or do_action.

    The easiest way is to call the function.

    $meta_value = get_post_meta($post_id,'key');
    $meta_value = my_add_a_class_function($meta_value);
    

    There is not template tag/hook like the_content to which you can attach that function, as far as I am aware.

    There is a filter on get_metadata, which is used by get_post_meta and get_post_custom (indirectly), that is constructed like get_{$meta_type}_metadata, but honestly I can’t get that filter to work in any way that makes sense to me.

    Something like if( is_page_template(‘enews_template.php’){ //filter
    all custom fields generated in this template

    Probably not. Custom fields aren’t “generated” in a template, and aren’t associated with any template in particular but with posts/pages/CPTs. If you managed to make that work it would be complicated and convoluted– unless someone can get that get_{$meta_type}_metadata filter working, at which I have sadly failed.