Support

Account

Home Forums Feature Requests Automatic Synchronized Json

Solving

Automatic Synchronized Json

  • Would be super awesome if the synchronized json (http://www.advancedcustomfields.com/resources/synchronized-json/) functionality ran automatically instead of manually having to “Sync” field groups.

    This means that the JSON becomes the single point of truth if you will.
    Merging is taken care of with GIT / insert other VCS here.

  • I needed this, as well, so I just went into the ACF code to see how the sync itself was done. I took out the code to perform the sync and added it to another function and then hooked it to admin_init.

    Below is the code, but I must encourage everyone to use at your own risk, as it will run the update regardless if it is “approved” by the user or not.

    
    /**
     * Function that will update ACF fields via JSON file update
     */
    function jp_sync_acf_fields() {
    
    	// vars
    	$groups = acf_get_field_groups();
    	$sync 	= array();
    
    	// bail early if no field groups
    	if( empty( $groups ) )
    		return;
    
    	// find JSON field groups which have not yet been imported
    	foreach( $groups as $group ) {
    		
    		// vars
    		$local 		= acf_maybe_get( $group, 'local', false );
    		$modified 	= acf_maybe_get( $group, 'modified', 0 );
    		$private 	= acf_maybe_get( $group, 'private', false );
    		
    		// ignore DB / PHP / private field groups
    		if( $local !== 'json' || $private ) {
    			
    			// do nothing
    			
    		} elseif( ! $group[ 'ID' ] ) {
    			
    			$sync[ $group[ 'key' ] ] = $group;
    			
    		} elseif( $modified && $modified > get_post_modified_time( 'U', true, $group[ 'ID' ], true ) ) {
    			
    			$sync[ $group[ 'key' ] ]  = $group;
    		}
    	}
    
    	// bail if no sync needed
    	if( empty( $sync ) )
    		return;
    
    	if( ! empty( $sync ) ) { //if( ! empty( $keys ) ) {
    		
    		// vars
    		$new_ids = array();
    		
    		foreach( $sync as $key => $v ) { //foreach( $keys as $key ) {
    			
    			// append fields
    			if( acf_have_local_fields( $key ) ) {
    				
    				$sync[ $key ][ 'fields' ] = acf_get_local_fields( $key );
    				
    			}
    			// import
    			$field_group = acf_import_field_group( $sync[ $key ] );
    		}
    	}
    }
    add_action( 'admin_init', 'jp_sync_acf_fields' );
    
  • Is this a feature yet? Can we trigger it from wp-cli?

    
    <?php
    
    if ( defined( 'WP_CLI' ) && WP_CLI && ! class_exists( 'ACF_Commands' ) ) :
    
        /**
         * ACF_Commands
         */
        class ACF_Commands extends WP_CLI_Command {
    
            /**
             * Sync ACF Fields
             *
             * ## OPTIONS
             *
             * @when init
             *
             * @example
             *
             *  wp acf sync
             *
             */
            function sync ( $args, $assoc_args ) {
    
                // vars
                $groups = acf_get_field_groups();
                $sync 	= array();
    
                // bail early if no field groups
                if( empty( $groups ) )
                    return;
    
                // find JSON field groups which have not yet been imported
                foreach( $groups as $group ) {
    
                    // vars
                    $local 		= acf_maybe_get( $group, 'local', false );
                    $modified 	= acf_maybe_get( $group, 'modified', 0 );
                    $private 	= acf_maybe_get( $group, 'private', false );
    
                    // ignore DB / PHP / private field groups
                    if( $local !== 'json' || $private ) {
    
                        // do nothing
    
                    } elseif( ! $group[ 'ID' ] ) {
    
                        $sync[ $group[ 'key' ] ] = $group;
    
                    } elseif( $modified && $modified > get_post_modified_time( 'U', true, $group[ 'ID' ], true ) ) {
    
                        $sync[ $group[ 'key' ] ]  = $group;
                    }
                }
    
                // bail if no sync needed
                if( empty( $sync ) ) {
                    WP_CLI::success( "No ACF Sync Required" );
                    return;
                }
    
                if( ! empty( $sync ) ) { //if( ! empty( $keys ) ) {
    
                    // vars
                    $new_ids = array();
    
                    foreach( $sync as $key => $v ) { //foreach( $keys as $key ) {
    
                        // append fields
                        if( acf_have_local_fields( $key ) ) {
    
                            $sync[ $key ][ 'fields' ] = acf_get_local_fields( $key );
    
                        }
                        // import
                        $field_group = acf_import_field_group( $sync[ $key ] );
                    }
                }
    
                WP_CLI::success( 'ACF SYNC SUCCESS!' );
            }
    
        }
    
        WP_CLI::add_command( 'acf', 'ACF_Commands' );
    
    endif; // ACF_Commands
  • Thanks, this works great! This seems to work only with adding fields that didn’t exist before. Is there a way to automatically delete fields in the database that were deleted via their JSON files? I am using this feature on a multisite.

  • Personally, I am not sure, and I haven’t touched ACF in months due to I am no longer developing 🙂

    When you do a manual sync does the process remove fields that have been removed from the JSON file? If not, then there’s probably a reason for it. 99% of the time developers allow the addition of data like this through imports, but not removal of the data. This is due to it is much easier to have users manually delete data then try to recover any data deleted from the database due to a bad import.

  • Thanks for the quick response! When I turn the auto syncing off it doesn’t delete the field on the backend when I run the syncing manually. It did when I used the ACF Pro JSON Sync plugin, but that didn’t have an auto sync feature like this for the syncing feature that is baked into the plugin.

  • Thank you jessepearson, it works great!

    @ACF Team: any chance a function/action like this can get into the plugin? It is very useful for automatic site deployment, especially in multisite installations.

  • “This means that the JSON becomes the single point of truth if you will.”

    I’d love such feature. I’m having issues regularly with databases out of sync, or fields deleted from JSON but still present in database and displaying on pages…

    Getting rid of the database copy of the fields and of the sync system would be ideal for me (but keeping the admin UI for creating / update fields of course).

  • With the code from jessepearson, I can’t manage the new fields in ACF (they are not visible) and they can’t be added by syncing as there’s not sync option anymore. Did this work at some point, jessepearson?

    I tried to continue on this code, but got nowhere so far. It would be great if ACF added a hook to run the complete sync process so we would be able to do something like this:

    function acf_sync_fields_complete($upgrader_object = null, $options = null) {
    	if ($options['action'] == 'update' && $options['type'] == 'theme' ) :
    		do_action('acf_sync_json_options');
    	endif;
    }
    add_action( 'upgrader_process_complete', 'acf_sync_fields_complete', 10, 2);

    Note: Above code is not working

  • The problem with code from @jessepearson was that deleted fields weren’t removed. Fields which were changed or added were handled correctly.

    At the moment I’m using a plugin named Advanced Custom Fields: Auto JSON Sync, which handles all situations fine. You can find it here: https://github.com/jawittdesigns/advanced-custom-fields-auto-json-sync/

  • I don’t have any idea about it please tell me more about this.

  • In the end I settled with only using the acf-json files (https://www.advancedcustomfields.com/resources/local-json/). In the hierarchy of ways that fields can be added, ACF prefers the acf-json files above the fields in the database.

    I don’t do any synchronisation between environments at all anymore. The JSON files are being distributed to testing and live environments through git.

    The whole ACF admin area is hidden on environments other then the local development environments. This way fields can only be added or edited on development environments, if this could also be done on other environments, the changes would be overwritten upon a git update.

  • There’s still a downside, though:
    When multiple developers are working on the same installation, they will have to sync the fields manually.

    It would be very good to have a hook to disable the database fields completely, so we would just work with acf-json files.

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

The topic ‘Automatic Synchronized Json’ is closed to new replies.