Support

Account

Home Forums Bug Reports Backslashes in field attributes breaks ACF5 upgrade & save

Solving

Backslashes in field attributes breaks ACF5 upgrade & save

    • jsilver

    • November 2, 2014 at 8:19 am

    If you use a backslash in any field setting (append, prepend, custom, etc) then invalid serialized data is saved to the database and ACF is unable to load the field at the next request.

    During an upgrade from 4 to 5, all fields containing a backslash are broken. It is possible to manually correct in the database as the serialized length is correct, but the actual value is missing the \.

    During a save the field’s type is defaulted back to “text” and all settings are lost.

    I was able to correct this behavior without modified ACF code by using filters on content_save_pre and acf/get_valid_field.

    class ACF_Slash_Fix {
    
    	function __construct(){
    		// bug fix for acf with backslashes in the content.
    		add_filter( 'content_save_pre', array( $this, 'fix_post_content' ) );
    		add_filter( 'acf/get_valid_field', array( $this, 'fix_upgrade' ) );
    	}
    
    	function fix_upgrade( $field ){
    
    		// the $_POST will tell us if this is an upgrade
    		$is_5_upgrade = 
    			isset( $_POST['action'] ) && $_POST['action'] == 'acf/admin/data_upgrade' && 
    			isset( $_POST['version'] ) && $_POST['version'] == '5.0.0';
    
    		// if it is an upgrade recursively fix the field values
    		if ( $is_5_upgrade ){
    			$field = $this->do_recursive_slash_fix( $field );
    		}
    
    		return $field;
    	}
    
    	function do_recursive_slash_fix( $array ){
    
    		// loop through all levels of the array
    		foreach( $array as $key => &$value ){
    			if ( is_array( $value ) ){
    				// dive deeper
    				$value = $this->do_recursive_slash_fix( $value );
    			} elseif ( is_string( $value ) ){
    				// fix single backslashes to double
    				if ( preg_match( '~(?<!\\\\)\\\\(?!\\\\)~', $value ) ){
    					$value = str_replace('\\', '\\\\', $value );
    				}
    			}
    		}
    
    		return $array;
    	}
    
    	function fix_post_content( $content ){
    		global $post;
    
    		// are we saving a field group?
    		$is_field_group = get_post_type() == 'acf-field-group';
    
    		// are we upgrading to ACF 5?
    		$is_5_upgrade = 
    			isset( $_POST['action'] ) && $_POST['action'] == 'acf/admin/data_upgrade' && 
    			isset( $_POST['version'] ) && $_POST['version'] == '5.0.0';
    
    		// if we are, we need to check the values for single, but not double, backslashes and make them double
    		if ( $is_field_group || $is_5_upgrade ){
    			if ( preg_match( '~(?<!\\\\)\\\\(?!\\\\)~', $content ) ){
    				$content = str_replace('\\', '\\\\', $content);
    			}
    		}
    
    		return $content;
    	}
    }
    new ACF_Slash_Fix();
  • Great post!
    Now I wonder… how come the developer of this plugin has let this one and previous backslashes issues go on and on and on without even making an attempt to fix it, even though many of us has pointed it out in detail, to the point of indicating the exact file and line number where the offending code is placed…. It’s exasperating!

    • jsilver

    • November 4, 2014 at 4:38 am

    @sheikadv – thanks, but I think we should cut Elliot some slack too, I’m sure he is pretty busy and this is somewhat of an edge case.

    That said, it affects a lot of the fields I use (given that I am using Regex and PHP code a lot) and I ended up having to make even more changes for my Validated Field plugin. The changes are still in “beta” while I do more testing – but I could really use some help if you have time. The links to the beta version can be found here and should correct for importing and saving fields with a backslash. The extra fixes were to allow for Repeater fields, and escaping both single and double quotes in values.

    Definitely backup your database first, but any feedback you can give me would be great – even if you don’t use the Validated Field part, it should still fix the backslash issue for all fields.

  • Hi! I’m still finding this issue in ACF PRO v5.5.7, almost 3 years after this bug was reported.

    In my case, I’m trying to set a Date Picker field’s return string format to “j \d\e F” (it’s a common format in spanish, ie: “7 de julio”), however the field resets to Text every time it’s saved.

  • Wow. Thanks guys… I have the very same issue. I’ll try @jsilver‘s solution. I don’t want to be pushy… but this should have been fixed by now 😱

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

You must be logged in to reply to this topic.

We use cookies to offer you a better browsing experience, analyze site traffic and personalize content. Read about how we use cookies and how you can control them in our Cookie Policy. If you continue to use this site, you consent to our use of cookies.