diff --git a/lib/rest-api.php b/lib/rest-api.php index aa74c373f8b5b1..5cdc258c08d5ab 100644 --- a/lib/rest-api.php +++ b/lib/rest-api.php @@ -185,42 +185,79 @@ function gutenberg_auto_draft_get_sample_permalink( $permalink, $id, $title, $na add_filter( 'get_sample_permalink', 'gutenberg_auto_draft_get_sample_permalink', 10, 5 ); /** - * Filters WP_User_Query arguments when querying users via the REST API. + * Expose the custom_logo theme-mod in the settings REST API. + */ +register_setting( + 'general', + 'theme_mods_' . get_option( 'stylesheet' ), + array( + 'type' => 'object', + 'show_in_rest' => array( + 'name' => 'theme_mods_' . get_option( 'stylesheet' ), + 'schema' => array( + 'type' => 'object', + 'properties' => array( + 'custom_logo' => array( 'type' => 'integer' ), + ), + ), + ), + ) +); + +/** + * Expose the "stylesheet" setting in the REST API. + */ +register_setting( + 'general', + 'stylesheet', + array( + 'type' => 'string', + 'show_in_rest' => true, + ) +); + +/** + * Filters the value of a setting recognized by the REST API. * - * Allow using the has_published_post argument. + * Hijacks the value for custom_logo theme-mod. * - * @param array $prepared_args Array of arguments for WP_User_Query. - * @param WP_REST_Request $request The REST API request. + * @param mixed $result Value to use for the requested setting. Can be a scalar + * matching the registered schema for the setting, or null to + * follow the default get_option() behavior. + * @param string $name Setting name (as shown in REST API responses). * - * @return array Returns modified $prepared_args. + * @return null|array */ -function gutenberg_rest_user_query_has_published_posts( $prepared_args, $request ) { - if ( ! empty( $request['has_published_posts'] ) ) { - $prepared_args['has_published_posts'] = ( true === $request['has_published_posts'] ) - ? get_post_types( array( 'show_in_rest' => true ), 'names' ) - : (array) $request['has_published_posts']; +function gutenberg_rest_pre_get_setting_filter_custom_logo( $result, $name ) { + if ( 'theme_mods_' . get_option( 'stylesheet' ) === $name ) { + return array( + 'custom_logo' => get_theme_mod( 'custom_logo' ), + ); } - return $prepared_args; } -add_filter( 'rest_user_query', 'gutenberg_rest_user_query_has_published_posts', 10, 2 ); - +add_filter( 'rest_pre_get_setting', 'gutenberg_rest_pre_get_setting_filter_custom_logo', 10, 2 ); /** - * Filters REST API collection parameters for the users controller. + * Filters whether to preempt a setting value update via the REST API. + * + * Hijacks the saving method for theme-mods. * - * @param array $query_params JSON Schema-formatted collection parameters. + * @param bool $result Whether to override the default behavior for updating the + * value of a setting. + * @param string $name Setting name (as shown in REST API responses). + * @param mixed $value Updated setting value. * - * @return array Returns the $query_params with "has_published_posts". + * @return bool */ -function gutenberg_rest_user_collection_params_has_published_posts( $query_params ) { - $query_params['has_published_posts'] = array( - 'description' => __( 'Limit result set to users who have published posts.', 'gutenberg' ), - 'type' => array( 'boolean', 'array' ), - 'items' => array( - 'type' => 'string', - 'enum' => get_post_types( array( 'show_in_rest' => true ), 'names' ), - ), - ); - return $query_params; +function gutenberg_rest_pre_set_setting_filter_theme_mods( $result, $name, $value ) { + $theme_mods_setting_name = 'theme_mods_' . get_option( 'stylesheet' ); + if ( $theme_mods_setting_name === $name ) { + $value = (array) $value; + $value = wp_parse_args( $value, get_option( $theme_mods_setting_name, array() ) ); + + update_option( $theme_mods_setting_name, $value ); + return true; + } } -add_filter( 'rest_user_collection_params', 'gutenberg_rest_user_collection_params_has_published_posts' ); + +add_filter( 'rest_pre_update_setting', 'gutenberg_rest_pre_set_setting_filter_theme_mods', 10, 3 ); diff --git a/packages/block-library/src/site-logo/edit.js b/packages/block-library/src/site-logo/edit.js index 05e225513392d1..852446ed635ccf 100644 --- a/packages/block-library/src/site-logo/edit.js +++ b/packages/block-library/src/site-logo/edit.js @@ -255,33 +255,45 @@ export default function LogoEdit( { const [ logoUrl, setLogoUrl ] = useState(); const [ error, setError ] = useState(); const ref = useRef(); - const { mediaItemData, siteLogo, url } = useSelect( ( select ) => { - const siteSettings = select( coreStore ).getEditedEntityRecord( - 'root', - 'site' - ); - const mediaItem = siteSettings.site_logo - ? select( coreStore ).getEntityRecord( - 'root', - 'media', - siteSettings.site_logo - ) - : null; - return { - mediaItemData: mediaItem && { - url: mediaItem.source_url, - alt: mediaItem.alt_text, - }, - siteLogo: siteSettings.site_logo, - url: siteSettings.url, - }; - }, [] ); + const { mediaItemData, siteLogo, url, stylesheet } = useSelect( + ( select ) => { + const siteSettings = select( coreStore ).getEditedEntityRecord( + 'root', + 'site' + ); + + const themeModOptionName = `theme_mods_${ siteSettings.stylesheet }`; + + siteSettings[ themeModOptionName ] = + siteSettings[ themeModOptionName ] || {}; + const mediaItem = siteSettings[ themeModOptionName ].custom_logo + ? select( coreStore ).getEntityRecord( + 'root', + 'media', + siteSettings[ themeModOptionName ].custom_logo + ) + : null; + return { + mediaItemData: mediaItem && { + url: mediaItem.source_url, + alt: mediaItem.alt_text, + }, + siteLogo: siteSettings[ themeModOptionName ].custom_logo, + url: siteSettings.url, + stylesheet: siteSettings.stylesheet, + }; + }, + [] + ); const { editEntityRecord } = useDispatch( coreStore ); - const setLogo = ( newValue ) => - editEntityRecord( 'root', 'site', undefined, { - site_logo: newValue, - } ); + const setLogo = ( newValue ) => { + const settingsVal = {}; + settingsVal[ `theme_mods_${ stylesheet }` ] = { + custom_logo: newValue, + }; + editEntityRecord( 'root', 'site', undefined, settingsVal ); + }; let alt = null; if ( mediaItemData ) { diff --git a/packages/block-library/src/site-logo/index.php b/packages/block-library/src/site-logo/index.php index 44d63505cc4ffb..1127f4790a3a7f 100644 --- a/packages/block-library/src/site-logo/index.php +++ b/packages/block-library/src/site-logo/index.php @@ -25,8 +25,6 @@ function render_block_core_site_logo( $attributes ) { $custom_logo = get_custom_logo(); - remove_filter( 'wp_get_attachment_image_src', $adjust_width_height_filter ); - if ( empty( $custom_logo ) ) { return ''; // Return early if no custom logo is set, avoiding extraneous wrapper div. } @@ -58,27 +56,10 @@ function render_block_core_site_logo( $attributes ) { $wrapper_attributes = get_block_wrapper_attributes( array( 'class' => implode( ' ', $classnames ) ) ); $html = sprintf( '
%s
', $wrapper_attributes, $custom_logo ); + remove_filter( 'wp_get_attachment_image_src', $adjust_width_height_filter ); return $html; } -/** - * Register a core site setting for a site logo - */ -function register_block_core_site_logo_setting() { - register_setting( - 'general', - 'site_logo', - array( - 'show_in_rest' => array( - 'name' => 'site_logo', - ), - 'type' => 'integer', - 'description' => __( 'Site logo.' ), - ) - ); -} - -add_action( 'rest_api_init', 'register_block_core_site_logo_setting', 10 ); /** * Registers the `core/site-logo` block on the server. @@ -91,74 +72,4 @@ function register_block_core_site_logo() { ) ); } - add_action( 'init', 'register_block_core_site_logo' ); - -/** - * Overrides the custom logo with a site logo, if the option is set. - * - * @param string $custom_logo The custom logo set by a theme. - * - * @return string The site logo if set. - */ -function _override_custom_logo_theme_mod( $custom_logo ) { - $site_logo = get_option( 'site_logo' ); - return false === $site_logo ? $custom_logo : $site_logo; -} - -add_filter( 'theme_mod_custom_logo', '_override_custom_logo_theme_mod' ); - -/** - * Updates the site_logo option when the custom_logo theme-mod gets updated. - * - * This function is hooked on "update_option_theme_mods_$theme" and not - * "pre_set_theme_mod_custom_logo" because by hooking in `update_option` - * the function accounts for remove_theme_mod() as well. - * - * @param mixed $old_value The old option value. - * @param mixed $value The new option value. - */ -function _sync_custom_logo_to_site_logo( $old_value, $value ) { - // Delete the option when the custom logo does not exist or was removed. - // This step ensures the option stays in sync. - if ( empty( $value['custom_logo'] ) ) { - delete_option( 'site_logo' ); - } else { - remove_action( 'update_option_site_logo', '_sync_site_logo_to_custom_logo' ); - update_option( 'site_logo', $value['custom_logo'] ); - add_action( 'update_option_site_logo', '_sync_site_logo_to_custom_logo', 10, 2 ); - } -} - -/** - * Hooks `_sync_custom_logo_to_site_logo` in `update_option_theme_mods_$theme`. - * - * Runs on `setup_theme` to account for dynamically-switched themes in the Customizer. - */ -function _sync_custom_logo_to_site_logo_on_setup_theme() { - $theme = get_option( 'stylesheet' ); - add_action( "update_option_theme_mods_$theme", '_sync_custom_logo_to_site_logo', 10, 2 ); -} -add_action( 'setup_theme', '_sync_custom_logo_to_site_logo_on_setup_theme', 11 ); - -/** - * Updates the custom_logo theme-mod when the site_logo option gets updated. - * - * @param mixed $old_value The old option value. - * @param mixed $value The new option value. - * - * @return void - */ -function _sync_site_logo_to_custom_logo( $old_value, $value ) { - // Delete the option when the custom logo does not exist or was removed. - // This step ensures the option stays in sync. - if ( empty( $value ) ) { - remove_theme_mod( 'custom_logo' ); - } else { - remove_filter( 'pre_set_theme_mod_custom_logo', '_sync_custom_logo_to_site_logo' ); - set_theme_mod( 'custom_logo', $value ); - add_filter( 'pre_set_theme_mod_custom_logo', '_sync_custom_logo_to_site_logo' ); - } -} - -add_action( 'update_option_site_logo', '_sync_site_logo_to_custom_logo', 10, 2 );