File: /volume1/web/Marchisa-Toman/wp-content/plugins/meta-box-builder/src/LocalJson.php
<?php
namespace MBB;
use MBB\RestApi\Save;
class LocalJson {
public function __construct() {
add_action( 'mbb_after_save', [ $this, 'generate_local_json' ], 10, 3 );
}
public function generate_local_json( $parser, $post_id, $raw_data ): bool {
return self::use_database( compact( 'post_id' ) );
}
/**
* Check if the local JSON feature is enabled
*
* @return bool
*/
public static function is_enabled(): bool {
return ! empty( JsonService::get_paths() );
}
/**
* Get decoded JSON as an associative array from a .json file
*/
public static function read_file( string $file_path ): array {
if ( ! file_exists( $file_path ) || ! is_readable( $file_path ) ) {
return [];
}
$content = file_get_contents( $file_path );
$json = json_decode( $content, true );
return is_array( $json ) ? $json : [];
}
public static function write_file( string $file_path, array $data ) {
if ( ! is_writable( dirname( $file_path ) ) ) {
return false;
}
if ( ! is_dir( dirname( $file_path ) ) ) {
wp_mkdir_p( dirname( $file_path ) );
}
$output = wp_json_encode( $data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT );
return @file_put_contents( $file_path, $output );
}
/**
* Import from .json file
*
* @return \WP_Error|boolean
*/
public static function import( array $data ): bool {
return self::sync_json( $data );
}
public static function import_many( array $json ): void {
foreach ( $json as $data ) {
self::import( $data );
}
}
/**
* Use local json file and override database. Currently, its using by REST API
*
* @param array $args
* @return bool Success or not
*/
public static function use_json( array $args ): bool {
$json = JsonService::get_json( [
'id' => $args['post_name'],
'post_type' => $args['post_type'],
] );
if ( ! $json || ! is_array( $json ) ) {
return false;
}
$json = reset( $json );
return self::sync_json( $json );
}
/**
* Sync from JSON file to database.
*
* Exprected format: [ 'post_id' => 123, 'local' => [local JSON array] ]. See JsonService::get_json() for the full format.
* After unparsing: 'local' becomes:
* [
* // Post fields:
* 'post_type',
* 'post_name',
* 'post_title',
* 'post_date',
* 'post_status',
* 'post_content',
*
* // Meta keys (same as exported)
* 'settings',
* 'meta_box',
* 'fields',
* 'data',
* ]
*
* @param array $data
* @return bool Success or not
*/
public static function sync_json( array $data ): bool {
$required_keys = [ 'post_id', 'local' ];
foreach ( $required_keys as $key ) {
if ( ! array_key_exists( $key, $data ) ) {
return false;
}
}
$post_array = [ 'ID' => $data['post_id'] ];
$data = $data['local'];
$unparser = new \MBBParser\Unparsers\MetaBox( $data );
$unparser->unparse();
$data = $unparser->get_settings();
$meta_fields = Export::get_meta_keys( $data['post_type'] );
$post_array = array_merge( $post_array, [
'post_type' => $data['post_type'],
'post_name' => $data['post_name'],
'post_title' => $data['post_title'],
'post_date' => $data['post_date'],
'post_status' => $data['post_status'],
'post_content' => $data['post_content'],
] );
$post_array = Save::fix_post_date( $post_array );
$post_id = wp_insert_post( $post_array );
foreach ( $meta_fields as $meta_key ) {
if ( ! isset( $data[ $meta_key ] ) ) {
continue;
}
update_post_meta( $post_id, $meta_key, $data[ $meta_key ] );
}
// Now we need to save the modified data back to the JSON file
self::use_database( [ 'post_id' => $post_id ] );
return true;
}
/**
* Sync data from database to JSON file, overwriting existing content.
*
* @param array $args Contains either `post_id` or `post_name`.
* @return bool Success or not
*/
public static function use_database( array $args = [] ): bool {
if ( ! self::is_enabled() ) {
return false;
}
$post = null;
if ( isset( $args['post_id'] ) ) {
$post = get_post( $args['post_id'] );
} elseif ( isset( $args['post_name'] ) ) {
$post = get_page_by_path( $args['post_name'], OBJECT, 'meta-box' );
}
if ( empty( $post ) || $post->post_type !== 'meta-box' || $post->post_status !== 'publish' ) {
return false;
}
$post_data = (array) $post;
$meta_box = get_post_meta( $post->ID, 'meta_box', true ) ?: [];
$post_data['meta_box'] = $meta_box;
$settings = get_post_meta( $post->ID, 'settings', true );
$post_data['settings'] = (array) $settings;
$unparser = new \MBBParser\Unparsers\MetaBox( $post_data );
$unparser->unparse();
$post_data = $unparser->to_minimal_format();
// By default, we will save the file in the first path with {$post->post_name}.json
// however, some users might store the file name different with the meta box ID
// so we need to make an additional check if the file exists and write to that file instead
// of writing to the new file.
$files = JsonService::get_files();
$file_path = JsonService::get_paths()[0] . '/' . $post->post_name . '.json';
foreach ( $files as $file ) {
$raw_json = self::read_file( $file );
if ( empty( $raw_json ) ) {
continue;
}
$unparser = new \MBBParser\Unparsers\MetaBox( $raw_json );
$unparser->unparse();
$json = $unparser->get_settings();
if ( $json['meta_box']['id'] !== $post->post_name ) {
continue;
}
$file_path = $file;
break;
}
return (bool) self::write_file( $file_path, $post_data );
}
}