is_enabled() ) { return false; } // Append fields. $field_group['fields'] = acf_get_fields( $field_group ); // Save to file. $this->save_file( $field_group['key'], $field_group ); } /** * Writes ACF posts to the JSON file. * * @since 6.1 * * @param array $post The main ACF post array. * @return bool */ public function update_internal_post_type( $post ) { if ( ! $this->is_enabled() ) { return false; } /** * Filters the ACF post before saving it to the file. * * @since 6.1 * * @param array $post The main ACF post array */ $post = apply_filters( 'acf/pre_save_json_file', $post ); return $this->save_file( $post['key'], $post ); } /** * Deletes a field group JSON file. * * @date 14/4/20 * @since 5.9.0 * * @param array $field_group The field group. * @return bool */ public function delete_field_group( $field_group ) { return $this->delete_internal_post_type( $field_group ); } /** * Deletes an ACF JSON file. * * @since 6.1 * * @param array $post The main ACF post array. * @return bool */ public function delete_internal_post_type( $post ) { if ( ! $this->is_enabled() ) { return false; } // WP appends '__trashed' to the end of 'key' (post_name). $key = str_replace( '__trashed', '', $post['key'] ); return $this->delete_file( $key, $post ); } /** * Includes all local JSON fields. * * @date 14/4/20 * @since 5.9.0 * * @param void * @return void */ public function include_fields() { // Bail early if disabled. if ( ! $this->is_enabled() ) { return false; } // Get load paths. $files = $this->scan_files( 'acf-field-group' ); foreach ( $files as $key => $file ) { $json = json_decode( file_get_contents( $file ), true ); $json['local'] = 'json'; $json['local_file'] = $file; acf_add_local_field_group( $json ); } } /** * Includes all local JSON post types. * * @since 6.1 * * @return void */ public function include_post_types() { // Bail early if disabled. if ( ! $this->is_enabled() ) { return false; } // Get load paths. $files = $this->scan_files( 'acf-post-type' ); foreach ( $files as $key => $file ) { $json = json_decode( file_get_contents( $file ), true ); $json['local'] = 'json'; $json['local_file'] = $file; acf_add_local_internal_post_type( $json, 'acf-post-type' ); } } /** * Includes all local JSON taxonomies. * * @since 6.1 * * @return void */ public function include_taxonomies() { // Bail early if disabled. if ( ! $this->is_enabled() ) { return false; } // Get load paths. $files = $this->scan_files( 'acf-taxonomy' ); foreach ( $files as $key => $file ) { $json = json_decode( file_get_contents( $file ), true ); $json['local'] = 'json'; $json['local_file'] = $file; acf_add_local_internal_post_type( $json, 'acf-taxonomy' ); } } /** * Scans for JSON field groups. * * @date 14/4/20 * @since 5.9.0 * * @return array */ function scan_field_groups() { return $this->scan_files( 'acf-field-group' ); } /** * Scans for JSON files. * * @since 6.1 * * @param string $post_type The ACF post type to scan for. * @return array */ function scan_files( $post_type = 'acf-field-group' ) { $json_files = array(); // Loop over "local_json" paths and parse JSON files. foreach ( $this->get_load_paths() as $path ) { if ( is_dir( $path ) ) { $files = scandir( $path ); if ( $files ) { foreach ( $files as $filename ) { // Ignore hidden files. if ( $filename[0] === '.' ) { continue; } // Ignore sub directories. $file = untrailingslashit( $path ) . '/' . $filename; if ( is_dir( $file ) ) { continue; } // Ignore non JSON files. $ext = pathinfo( $filename, PATHINFO_EXTENSION ); if ( $ext !== 'json' ) { continue; } // Read JSON data. $json = json_decode( file_get_contents( $file ), true ); if ( ! is_array( $json ) || ! isset( $json['key'] ) ) { continue; } // Append data. $json_files[ $json['key'] ] = $file; } } } } // Store data and return. $this->files = $json_files; return $this->get_files( $post_type ); } /** * Returns an array of found JSON files. * * @date 14/4/20 * @since 5.9.0 * * @param string $post_type The ACF post type to get files for. * @return array */ public function get_files( $post_type = 'acf-field-group' ) { $files = array(); foreach ( $this->files as $key => $path ) { $internal_post_type = acf_determine_internal_post_type( $key ); if ( $internal_post_type === $post_type ) { $files[ $key ] = $path; } elseif ( 'acf-field-group' === $post_type ) { // If we can't figure out the ACF post type, make an educated guess that it's a field group. $json = json_decode( file_get_contents( $path ), true ); if ( ! is_array( $json ) ) { continue; } if ( isset( $json['fields'] ) ) { $files[ $key ] = $path; } } } return $files; } /** * Saves an ACF JSON file. * * @date 17/4/20 * @since 5.9.0 * * @param string $key The ACF post key. * @param array $post The main ACF post array. * @return bool */ public function save_file( $key, $post ) { $paths = $this->get_save_paths( $key, $post ); $file = false; $first_writable = false; $load_path = ''; if ( is_array( $this->files ) && isset( $this->files[ $key ] ) ) { $load_path = $this->files[ $key ]; } /** * Filters the filename used when saving JSON. * * @since 6.2 * * @param string $filename The default filename. * @param array $post The main post array for the item being saved. * @param string $load_path The path that the item was loaded from. */ $filename = apply_filters( 'acf/json/save_file_name', $key . '.json', $post, $load_path ); if ( ! is_string( $filename ) ) { return false; } $filename = sanitize_file_name( $filename ); // sanitize_file_name() can potentially remove all characters. if ( empty( $filename ) ) { return false; } foreach ( $paths as $path ) { if ( ! is_writable( $path ) ) { continue; } if ( false === $first_writable ) { $first_writable = $path; } $file_to_check = trailingslashit( $path ) . $filename; if ( is_file( $file_to_check ) ) { $file = $file_to_check; } } if ( ! $file ) { if ( $first_writable ) { $file = trailingslashit( $first_writable ) . $filename; } else { return false; } } // Make sure this is a valid ACF post type. $post_type = acf_determine_internal_post_type( $key ); if ( ! $post_type ) { return false; } // Append modified time. if ( $post['ID'] ) { $post['modified'] = get_post_modified_time( 'U', true, $post['ID'] ); } else { $post['modified'] = strtotime( 'now' ); } // Prepare for export and save the file. $post = acf_prepare_internal_post_type_for_export( $post, $post_type ); $result = file_put_contents( $file, acf_json_encode( $post ) . apply_filters( 'acf/json/eof_newline', PHP_EOL ) ); // Return true if bytes were written. return is_int( $result ); } /** * Deletes an ACF JSON file. * * @date 17/4/20 * @since 5.9.0 * * @param string $key The ACF post key. * @param array $post The main ACF post array. * @return bool */ public function delete_file( $key, $post = array() ) { $paths = $this->get_save_paths( $key, $post ); foreach ( $paths as $path_to_check ) { $file = untrailingslashit( $path_to_check ) . '/' . $key . '.json'; if ( is_writable( $file ) ) { wp_delete_file( $file ); } } return true; } /** * Includes all local JSON files. * * @date 10/03/2014 * @since 5.0.0 * @deprecated 5.9.0 * * @param void * @return void */ public function include_json_folders() { _deprecated_function( __METHOD__, '5.9.0', 'ACF_Local_JSON::include_fields()' ); $this->include_fields(); } /** * Includes local JSON files within a specific folder. * * @date 01/05/2017 * @since 5.5.13 * @deprecated 5.9.0 * * @param string $path The path to a specific JSON folder. * @return void */ public function include_json_folder( $path = '' ) { _deprecated_function( __METHOD__, '5.9.0' ); // Do nothing. } } // Initialize. acf_new_instance( 'ACF_Local_JSON' ); endif; // class_exists check /** * Returns an array of found JSON field group files. * * @date 14/4/20 * @since 5.9.0 * * @param string $post_type The ACF post type to get files for. * @return array */ function acf_get_local_json_files( $post_type = 'acf-field-group' ) { return acf_get_instance( 'ACF_Local_JSON' )->get_files( $post_type ); } /** * Saves a field group JSON file. * * @date 5/12/2014 * @since 5.1.5 * * @param array $field_group The field group. * @return bool */ function acf_write_json_field_group( $field_group ) { return acf_get_instance( 'ACF_Local_JSON' )->save_file( $field_group['key'], $field_group ); } /** * Deletes a field group JSON file. * * @date 5/12/2014 * @since 5.1.5 * * @param string $key The field group key. * @return bool True on success. */ function acf_delete_json_field_group( $key ) { return acf_get_instance( 'ACF_Local_JSON' )->delete_file( $key ); }