Skip to content

Commit

Permalink
Make global styles data filterable (#44015)
Browse files Browse the repository at this point in the history
Use a WP_Theme_JSON_Data structure in the filters so consumers don't edit directly the theme.json array,
whose format could be updated forcing consumers to update their code if they edit directly.
  • Loading branch information
oandregal authored Sep 13, 2022
1 parent e00cd51 commit cb75861
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 3 deletions.
60 changes: 60 additions & 0 deletions lib/compat/wordpress-6.1/class-wp-theme-json-data.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php
/**
* API to update a theme.json structure.
*
* @package gutenberg
*/

/**
* Class to update with a theme.json structure.
*/
class WP_Theme_JSON_Data {

/**
* Container of the data to update.
*
* @var WP_Theme_JSON
*/
private $theme_json = null;

/**
* The origin of the data: default, theme, user, etc.
*
* @var string
*/
private $origin = null;

/**
* Constructor.
*
* @param array $data Array following the theme.json specification.
* @param string $origin The origin of the data: default, theme, user.
*/
public function __construct( $data = array(), $origin = 'theme' ) {
$this->origin = $origin;
$this->theme_json = new WP_Theme_JSON_Gutenberg( $data, $this->origin );
}

/**
* Updates the theme.json with the the given data.
*
* @param array $new_data Array following the theme.json specification.
*
* @return WP_Theme_JSON_Data the modified data.
*/
public function update_with( $new_data ) {
$this->theme_json->merge( new WP_Theme_JSON_Gutenberg( $new_data, $this->origin ) );

return $this;
}

/**
* Returns the underlying data.
*
* @return array
*/
public function get_data() {
return $this->theme_json->get_raw_data();
}

}
44 changes: 43 additions & 1 deletion lib/compat/wordpress-6.1/class-wp-theme-json-resolver-6-1.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,50 @@ public static function get_core_data() {

$config = static::read_json_file( __DIR__ . '/theme.json' );
$config = static::translate( $config );
static::$core = new WP_Theme_JSON_Gutenberg( $config, 'default' );
$config = apply_filters( 'global_styles_default', new WP_Theme_JSON_Data( $config, 'default' ) );
static::$core = new WP_Theme_JSON_Gutenberg( $config->get_data(), 'default' );

return static::$core;
}

/**
* Returns the user's origin config.
*
* @return WP_Theme_JSON_Gutenberg Entity that holds styles for user data.
*/
public static function get_user_data() {
if ( null !== static::$user ) {
return static::$user;
}

$config = array();
$user_cpt = static::get_user_data_from_wp_global_styles( wp_get_theme() );

if ( array_key_exists( 'post_content', $user_cpt ) ) {
$decoded_data = json_decode( $user_cpt['post_content'], true );

$json_decoding_error = json_last_error();
if ( JSON_ERROR_NONE !== $json_decoding_error ) {
trigger_error( 'Error when decoding a theme.json schema for user data. ' . json_last_error_msg() );
$config = apply_filters( 'global_styles_user', new WP_Theme_JSON_Data( $config, 'custom' ) );
return new WP_Theme_JSON_Gutenberg( $config->get_data(), 'custom' );
}

// Very important to verify if the flag isGlobalStylesUserThemeJSON is true.
// If is not true the content was not escaped and is not safe.
if (
is_array( $decoded_data ) &&
isset( $decoded_data['isGlobalStylesUserThemeJSON'] ) &&
$decoded_data['isGlobalStylesUserThemeJSON']
) {
unset( $decoded_data['isGlobalStylesUserThemeJSON'] );
$config = $decoded_data;
}
}

$config = apply_filters( 'global_styles_user', new WP_Theme_JSON_Data( $config, 'custom' ) );
static::$user = new WP_Theme_JSON_Gutenberg( $config->get_data(), 'custom' );

return static::$user;
}
}
8 changes: 6 additions & 2 deletions lib/experimental/class-wp-theme-json-resolver-gutenberg.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ public static function get_theme_data( $deprecated = array(), $settings = array(
$theme_json_data = static::read_json_file( static::get_file_path_from_theme( 'theme.json' ) );
$theme_json_data = static::translate( $theme_json_data, wp_get_theme()->get( 'TextDomain' ) );
$theme_json_data = gutenberg_add_registered_webfonts_to_theme_json( $theme_json_data );
static::$theme = new WP_Theme_JSON_Gutenberg( $theme_json_data );

$theme_json_data = apply_filters( 'global_styles_theme', new WP_Theme_JSON_Data( $theme_json_data, 'theme' ) );
static::$theme = new WP_Theme_JSON_Gutenberg( $theme_json_data->get_data() );

if ( wp_get_theme()->parent() ) {
// Get parent theme.json.
Expand Down Expand Up @@ -128,9 +130,11 @@ public static function get_block_data() {
}
}

$config = apply_filters( 'global_styles_blocks', new WP_Theme_JSON_Data( $config, 'core' ) );

// Core here means it's the lower level part of the styles chain.
// It can be a core or a third-party block.
return new WP_Theme_JSON_Gutenberg( $config, 'core' );
return new WP_Theme_JSON_Gutenberg( $config->get_data(), 'core' );
}

/**
Expand Down
1 change: 1 addition & 0 deletions lib/load.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ function gutenberg_is_experiment_enabled( $name ) {
require __DIR__ . '/compat/wordpress-6.1/block-editor-settings.php';
require __DIR__ . '/compat/wordpress-6.1/persisted-preferences.php';
require __DIR__ . '/compat/wordpress-6.1/get-global-styles-and-settings.php';
require __DIR__ . '/compat/wordpress-6.1/class-wp-theme-json-data.php';
require __DIR__ . '/compat/wordpress-6.1/class-wp-theme-json-6-1.php';
require __DIR__ . '/compat/wordpress-6.1/class-wp-theme-json-resolver-6-1.php';
require __DIR__ . '/compat/wordpress-6.1/block-template-utils.php';
Expand Down

0 comments on commit cb75861

Please sign in to comment.