Home › Forums › Feature Requests › 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/
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.
The topic ‘Automatic Synchronized Json’ is closed to new replies.
Welcome to the Advanced Custom Fields community forum.
Browse through ideas, snippets of code, questions and answers between fellow ACF users
Helping others is a great way to earn karma, gain badges and help ACF development!
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 Privacy Policy. If you continue to use this site, you consent to our use of cookies.