diff --git a/includes/class-create-block-theme-api.php b/includes/class-create-block-theme-api.php index 604fa75b..54d23104 100644 --- a/includes/class-create-block-theme-api.php +++ b/includes/class-create-block-theme-api.php @@ -144,6 +144,17 @@ public function register_rest_routes() { }, ), ); + register_rest_route( + 'create-block-theme/v1', + '/reset-theme', + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'rest_reset_theme' ), + 'permission_callback' => function () { + return current_user_can( 'edit_theme_options' ); + }, + ), + ); } function rest_get_theme_data( $request ) { @@ -371,6 +382,7 @@ function rest_save_theme( $request ) { } } CBT_Theme_Templates::clear_user_templates_customizations(); + CBT_Theme_Templates::clear_user_template_parts_customizations(); } if ( isset( $options['saveStyle'] ) && true === $options['saveStyle'] ) { @@ -410,6 +422,32 @@ function rest_get_font_families( $request ) { ); } + /** + * Reset the theme to the default state. + */ + function rest_reset_theme( $request ) { + $options = $request->get_params(); + + if ( isset( $options['resetStyles'] ) && true === $options['resetStyles'] ) { + CBT_Theme_Styles::clear_user_styles_customizations(); + } + + if ( isset( $options['resetTemplates'] ) && true === $options['resetTemplates'] ) { + CBT_Theme_Templates::clear_user_templates_customizations(); + } + + if ( isset( $options['resetTemplateParts'] ) && true === $options['resetTemplateParts'] ) { + CBT_Theme_Templates::clear_user_template_parts_customizations(); + } + + return rest_ensure_response( + array( + 'status' => 'SUCCESS', + 'message' => __( 'Theme Reset.', 'create-block-theme' ), + ) + ); + } + private function sanitize_theme_data( $theme ) { $sanitized_theme['name'] = sanitize_text_field( $theme['name'] ); $sanitized_theme['description'] = sanitize_text_field( $theme['description'] ?? '' ); diff --git a/includes/create-theme/theme-templates.php b/includes/create-theme/theme-templates.php index 3298e7ee..7b1ea1bf 100644 --- a/includes/create-theme/theme-templates.php +++ b/includes/create-theme/theme-templates.php @@ -106,17 +106,22 @@ public static function replace_template_namespace( $template, $new_slug ) { * This will remove all user templates from the database. */ public static function clear_user_templates_customizations() { - //remove all user templates (they have been saved in the theme) - $templates = get_block_templates(); - $template_parts = get_block_templates( array(), 'wp_template_part' ); - foreach ( $template_parts as $template ) { + $templates = get_block_templates(); + foreach ( $templates as $template ) { if ( 'custom' !== $template->source ) { continue; } wp_delete_post( $template->wp_id, true ); } + } - foreach ( $templates as $template ) { + /** + * Clear all user template-parts customizations. + * This will remove all user template-parts from the database. + */ + public static function clear_user_template_parts_customizations() { + $template_parts = get_block_templates( array(), 'wp_template_part' ); + foreach ( $template_parts as $template ) { if ( 'custom' !== $template->source ) { continue; } diff --git a/src/editor-sidebar/reset-theme.js b/src/editor-sidebar/reset-theme.js new file mode 100644 index 00000000..3ee5501b --- /dev/null +++ b/src/editor-sidebar/reset-theme.js @@ -0,0 +1,160 @@ +/** + * WordPress dependencies + */ +import { __ } from '@wordpress/i18n'; +import { useDispatch, useSelect } from '@wordpress/data'; +import { store as noticesStore } from '@wordpress/notices'; +import { + // eslint-disable-next-line @wordpress/no-unsafe-wp-apis + __experimentalConfirmDialog as ConfirmDialog, + // eslint-disable-next-line @wordpress/no-unsafe-wp-apis + __experimentalVStack as VStack, + PanelBody, + Button, + CheckboxControl, +} from '@wordpress/components'; +import { trash } from '@wordpress/icons'; +import { useState } from '@wordpress/element'; +import { store as preferencesStore } from '@wordpress/preferences'; + +/** + * Internal dependencies + */ +import ScreenHeader from './screen-header'; +import { resetTheme } from '../resolvers'; + +const PREFERENCE_SCOPE = 'create-block-theme'; +const PREFERENCE_KEY = 'reset-theme'; + +function ResetTheme() { + const preferences = useSelect( ( select ) => { + const _preference = select( preferencesStore ).get( + PREFERENCE_SCOPE, + PREFERENCE_KEY + ); + return { + resetStyles: _preference?.resetStyles ?? true, + resetTemplates: _preference?.resetTemplates ?? true, + resetTemplateParts: _preference?.resetTemplateParts ?? true, + }; + }, [] ); + + const { set: setPreferences } = useDispatch( preferencesStore ); + const { createErrorNotice } = useDispatch( noticesStore ); + const [ isConfirmDialogOpen, setIsConfirmDialogOpen ] = useState( false ); + + const handleTogglePreference = ( key ) => { + setPreferences( PREFERENCE_SCOPE, PREFERENCE_KEY, { + ...preferences, + [ key ]: ! preferences[ key ], + } ); + }; + + const toggleConfirmDialog = () => { + setIsConfirmDialogOpen( ! isConfirmDialogOpen ); + }; + + const handleResetTheme = async () => { + try { + await resetTheme( preferences ); + toggleConfirmDialog(); + // eslint-disable-next-line no-alert + window.alert( + __( + 'Theme reset successfully. The editor will now reload.', + 'create-block-theme' + ) + ); + window.location.reload(); + } catch ( error ) { + createErrorNotice( + __( + 'An error occurred while resetting the theme.', + 'create-block-theme' + ) + ); + } + }; + + return ( + <> + + { __( + 'Are you sure you want to reset the theme? This action cannot be undone.', + 'create-block-theme' + ) } + + + + + + handleTogglePreference( 'resetStyles' ) + } + /> + + + handleTogglePreference( 'resetTemplates' ) + } + /> + + + handleTogglePreference( 'resetTemplateParts' ) + } + /> + +