Support

Account

Home Forums General Issues Filter field when saving

Solved

Filter field when saving

  • I have a repeater field with 2 fields. I was able to display the fields on a post.

    After pasting text directly from MS Word into the 2 fields, there are formatting codes that I want to filter out when saving the post.

    I successfully set up a PHP function to filter the body of the post:

    add_filter('wp_insert_post_data', 'filter_styles',99,2);
    function filter_styles($data, $postarr){
    	$stylecodes = array(' style=\"font-size: medium;\"',' class=\"western\"');
    	$data = str_ireplace( $stylecodes, '',$data);
    	$ms_tags = array('/<\/?st1([^>]*)>/','/<\/?o:p>/','/<\/(b|i)><\1>/');
    	$data = preg_replace($ms_tags,'',$data);
    	return $data;
    }

    When I tried to apply this function using acf/update_value, the values in existing fields were deleted. Not what I was hoping for, but hey, at least something happened.

    I looked a bit deeper and am now wondering if the acf/save_post hook is what I need. Any guidance on this would be much appreciated!

  • update value is what you’re probably looking for, but as for filtering the value to prevent ms word markup… more than likely there are some differences in what’s being submitted from what’s in the content editor. ACF may already be filtering part of the submission.

    What you’ll need to do is echo out the value that you’re trying to filter, if you do echo $value; die; in your filter you can figure out what changes you need to make to your regular expressions.

    My personal preference would be to tell the client to stop copying and pasting from word. It’s a bad habit. Trying to filter it is a never ending exercise in futility. 🙂

  • I very well understand the futility of filtering–just call me Sisyphus.

    I’m making progress–I decided to simplify, and wrote this code that works on a page with a non-repeater ACF field:

    add_filter('acf/update_value', 'my_acf_update_value', 10, 3);
    function my_acf_update_value( $value, $post_id, $field ) {
    	$value .= ' added by filter';
    	return $value;
    }
    

    Then I tried on a page with an ACF repeater–>crash with “Warning: Invalid argument supplied for foreach() in … /plugins/advanced-custom-fields-pro/pro/fields/repeater.php on line 722”

    Can you point me towards how to make this work for both single fields and repeater subfields?

    Thanks!

  • The repeater field is an array, what you’ll need to do is create loop through the repeater. You can continue to use the function your using if you create a recursive function, here’s an example: https://github.com/Hube2/acf-filters-and-functions/blob/master/acf-form-kses.php

  • Thanks for the recursive example–it was just what I needed. Here’s what I came up with that works with non-repeater fields and repeater subfields:

    add_filter('acf/update_value', 'my_acf_update_value', 10, 3);
    function my_acf_update_value( $value ) {
    	if (!is_array($value)) {
    		$value .= ' added by filter';
    		return $value;
    	}
    	$return = array();
    	foreach ($value as $index => $data) {
    		$return[$index] = my_acf_update_value ($data);
    	}
    	return $return;
    }

    There’s still something not quite right as ‘ added by filter’ appears twice on the 2 repeater subfields and saving the page is appallingly slow even on my local server. For my purposes (removing cruft from pasting text from MS Word), I can tolerate running the filter twice, but I’d like to cut the redundancy if I can. Any suggestions?

  • ACF applies filter only once for each field. It also applies it again with field names, keys and types but that should not be calling your function, but it probably applying the filter on each subfield so that’s where the duplicate is coming from. Instead of being a recursive function it might be better to simply return the original value if the field is a repeater and let the filter handle each subfield. That’s something I hadn’t thought about, should add it to my filter.

    
    add_filter('acf/update_value', 'my_acf_update_value', 10, 3);
    function my_acf_update_value( $value, $post_id=0, $field=array() ) {
      if (isset($field['type']) && ($field['type'] == 'repeater' || $field['type'] == 'flexible_content')) {
        // abort if it's a repeater
        return $value;
      }
    	if (!is_array($value)) {
    		$value .= ' added by filter';
    		return $value;
    	}
    	$return = array();
    	foreach ($value as $index => $data) {
    		$return[$index] = my_acf_update_value ($data);
    	}
    	return $return;
    }
    
  • Thanks, John, for your help on this. There’s no redundancy and saving a post goes much faster.

    Thanks!
    Tim

  • I added this change to my function as well, I honestly never thought about the fact that it would be called on every subfield of a repeater, though it’s obvious that it would be.

Viewing 8 posts - 1 through 8 (of 8 total)

The topic ‘Filter field when saving’ is closed to new replies.