-
Notifications
You must be signed in to change notification settings - Fork 4.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Global styles: enable user global styles revisions #46667
Closed
Closed
Changes from all commits
Commits
Show all changes
23 commits
Select commit
Hold shift + click to select a range
ab00625
Initial commit
ramonjd 241460c
Updating test
ramonjd 0ba94e6
Sending and checking for settings as well since some style variations…
ramonjd 7dcf0d0
Added a new endpoint to the global styles rest API (/revisions)
ramonjd f56cb4e
revisions is no longer a property of the response object
ramonjd fcfed1a
Update description for rest param
ramonjd 025fcf5
There's no reason to use the stored userConfig at all if we're reinst…
ramonjd 59cb723
added a test for the revisions endpoint
ramonjd af7420e
Added text domain
ramonjd 9728372
Bumping minimum revision count until display to two:
ramonjd eeab42f
Added a very unpretty E2E test for global styles revisions. We can't …
ramonjd 75b579f
Formatting the comments in the E2E test.
ramonjd 7003d22
Fixing up things after a rebase, mainly usage of __experimentalGetCur…
ramonjd 08a3eed
Moving changes to global styles controller to 6.2 compat
ramonjd 363105d
JS LINT YO!
ramonjd a7a47df
Relocate js utils tests for isGlobalStyleConfigEqual
ramonjd 760ae90
Move rest route registration to compat 6.3
ramonjd 4b1b41d
update e2e tests so that they pass :D I was importing a non-existant …
ramonjd c1bb9f8
Testing with undo/reset buttons
ramonjd 3a6c161
Moving the revisions link so that it's under the drop down
ramonjd 461d7ad
Yoda?
ramonjd 408a755
Adding author display name and avatar to rest response
ramonjd 6445d13
Update PHP tests title > date
ramonjd File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
184 changes: 184 additions & 0 deletions
184
lib/compat/wordpress-6.3/class-gutenberg-rest-global-styles-controller-6-3.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,184 @@ | ||
<?php | ||
/** | ||
* REST API: Gutenberg_REST_Global_Styles_Controller class | ||
* | ||
* @package Gutenberg | ||
* @subpackage REST_API | ||
*/ | ||
|
||
/** | ||
* Base Global Styles REST API Controller. | ||
*/ | ||
class Gutenberg_REST_Global_Styles_Controller_6_3 extends Gutenberg_REST_Global_Styles_Controller_6_2 { | ||
/** | ||
* Registers the controllers routes. | ||
* | ||
* @since 6.3 Registers `/revisions` endpoint. | ||
* | ||
* @return void | ||
*/ | ||
public function register_routes() { | ||
register_rest_route( | ||
$this->namespace, | ||
'/' . $this->rest_base . '/(?P<id>[\/\w-]+)/revisions', | ||
array( | ||
array( | ||
'methods' => WP_REST_Server::READABLE, | ||
'callback' => array( $this, 'get_item_revisions' ), | ||
'permission_callback' => array( $this, 'get_item_permissions_check' ), | ||
'args' => array( | ||
'id' => array( | ||
'description' => __( 'The id of the global styles post.', 'gutenberg' ), | ||
'type' => 'string', | ||
'sanitize_callback' => array( $this, '_sanitize_global_styles_callback' ), | ||
), | ||
), | ||
), | ||
) | ||
); | ||
parent::register_routes(); | ||
} | ||
|
||
/** | ||
* Returns revisions of the given global styles config custom post type. | ||
* | ||
* @since 6.3 | ||
* | ||
* @param WP_REST_Request $request The request instance. | ||
* | ||
* @return WP_REST_Response|WP_Error | ||
*/ | ||
public function get_item_revisions( $request ) { | ||
$post = $this->get_post( $request['id'] ); | ||
if ( is_wp_error( $post ) ) { | ||
return $post; | ||
} | ||
$revisions = array(); | ||
$raw_config = json_decode( $post->post_content, true ); | ||
$is_global_styles_user_theme_json = isset( $raw_config['isGlobalStylesUserThemeJSON'] ) && true === $raw_config['isGlobalStylesUserThemeJSON']; | ||
|
||
if ( $is_global_styles_user_theme_json ) { | ||
$user_theme_revisions = wp_get_post_revisions( | ||
$post->ID, | ||
array( | ||
'posts_per_page' => 100, | ||
) | ||
); | ||
|
||
if ( ! empty( $user_theme_revisions ) ) { | ||
// Mostly taken from wp_prepare_revisions_for_js(). | ||
foreach ( $user_theme_revisions as $id => $revision ) { | ||
$raw_revision_config = json_decode( $revision->post_content, true ); | ||
$config = ( new WP_Theme_JSON_Gutenberg( $raw_revision_config, 'custom' ) )->get_raw_data(); | ||
$now_gmt = time(); | ||
$modified = strtotime( $revision->post_modified ); | ||
$modified_gmt = strtotime( $revision->post_modified_gmt . ' +0000' ); | ||
/* translators: %s: Human-readable time difference. */ | ||
$time_ago = sprintf( __( '%s ago', 'gutenberg' ), human_time_diff( $modified_gmt, $now_gmt ) ); | ||
$date_short = date_i18n( _x( 'j M @ H:i', 'revision date short format', 'gutenberg' ), $modified ); | ||
$revisions[] = array( | ||
'styles' => ! empty( $config['styles'] ) ? $config['styles'] : new stdClass(), | ||
'settings' => ! empty( $config['settings'] ) ? $config['settings'] : new stdClass(), | ||
'date' => array( | ||
'raw' => $revision->post_modified, | ||
/* translators: 1: Human-readable time difference, 2: short date combined to show rendered revision date. */ | ||
'rendered' => sprintf( __( '%1$s (%2$s)', 'gutenberg' ), $time_ago, $date_short ), | ||
), | ||
'id' => $id, | ||
'is_latest' => array_key_first( $user_theme_revisions ) === $id, | ||
'author' => array( | ||
'display_name' => get_the_author_meta( 'display_name', $post->post_author ), | ||
'avatar_url' => get_avatar_url( | ||
$post->post_author, | ||
array( | ||
'size' => 24, | ||
) | ||
), | ||
), | ||
); | ||
} | ||
} | ||
} | ||
return rest_ensure_response( $revisions ); | ||
} | ||
|
||
/** | ||
* Prepare a global styles config output for response. | ||
* | ||
* @since 5.9.0 | ||
* @since 6.2 Handling of style.css was added to WP_Theme_JSON. | ||
* @since 6.3 Adds version-history to the response object. | ||
* | ||
* @param WP_Post $post Global Styles post object. | ||
* @param WP_REST_Request $request Request object. | ||
* @return WP_REST_Response Response object. | ||
*/ | ||
public function prepare_item_for_response( $post, $request ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable | ||
$raw_config = json_decode( $post->post_content, true ); | ||
$is_global_styles_user_theme_json = isset( $raw_config['isGlobalStylesUserThemeJSON'] ) && true === $raw_config['isGlobalStylesUserThemeJSON']; | ||
$config = array(); | ||
if ( $is_global_styles_user_theme_json ) { | ||
$config = ( new WP_Theme_JSON_Gutenberg( $raw_config, 'custom' ) )->get_raw_data(); | ||
} | ||
|
||
// Base fields for every post. | ||
$data = array(); | ||
$fields = $this->get_fields_for_response( $request ); | ||
|
||
if ( rest_is_field_included( 'id', $fields ) ) { | ||
$data['id'] = $post->ID; | ||
} | ||
|
||
if ( rest_is_field_included( 'title', $fields ) ) { | ||
$data['title'] = array(); | ||
} | ||
if ( rest_is_field_included( 'title.raw', $fields ) ) { | ||
$data['title']['raw'] = $post->post_title; | ||
} | ||
if ( rest_is_field_included( 'title.rendered', $fields ) ) { | ||
add_filter( 'protected_title_format', array( $this, 'protected_title_format' ) ); | ||
|
||
$data['title']['rendered'] = get_the_title( $post->ID ); | ||
|
||
remove_filter( 'protected_title_format', array( $this, 'protected_title_format' ) ); | ||
} | ||
|
||
if ( rest_is_field_included( 'settings', $fields ) ) { | ||
$data['settings'] = ! empty( $config['settings'] ) && $is_global_styles_user_theme_json ? $config['settings'] : new stdClass(); | ||
} | ||
|
||
if ( rest_is_field_included( 'styles', $fields ) ) { | ||
$data['styles'] = ! empty( $config['styles'] ) && $is_global_styles_user_theme_json ? $config['styles'] : new stdClass(); | ||
} | ||
|
||
$context = ! empty( $request['context'] ) ? $request['context'] : 'view'; | ||
$data = $this->add_additional_fields_to_object( $data, $request ); | ||
$data = $this->filter_response_by_context( $data, $context ); | ||
|
||
// Wrap the data in a response object. | ||
$response = rest_ensure_response( $data ); | ||
|
||
if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { | ||
$links = $this->prepare_links( $post->ID ); | ||
if ( $is_global_styles_user_theme_json ) { | ||
$revisions = wp_get_latest_revision_id_and_total_count( $post->ID ); | ||
$revisions_count = ! is_wp_error( $revisions ) ? $revisions['count'] : 0; | ||
$revisions_base = sprintf( '/%s/%s/%d/revisions', $this->namespace, $this->rest_base, $post->ID ); | ||
$links['version-history'] = array( | ||
'href' => rest_url( $revisions_base ), | ||
'count' => $revisions_count, | ||
); | ||
} | ||
$response->add_links( $links ); | ||
if ( ! empty( $links['self']['href'] ) ) { | ||
$actions = $this->get_available_actions(); | ||
$self = $links['self']['href']; | ||
foreach ( $actions as $rel ) { | ||
$response->add_link( $rel, $self ); | ||
} | ||
} | ||
} | ||
|
||
return $response; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reason why I'm returning the entire global style object instead of just the ID is so we can access the revisions url.
E.g.:
currentGlobalStyles?._links?.[ 'version-history' ]?.[ 0 ]?.href;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seemed a waste not to repurpose this method since it was fetching what we wanted anyway and only returning the id.
Plus it's experimental so I didn't see much harm in changing it.