Skip to content
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

Add theme reset section #687

Merged
merged 5 commits into from
Aug 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions includes/class-create-block-theme-api.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 ) {
Expand Down Expand Up @@ -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'] ) {
Expand Down Expand Up @@ -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'] ?? '' );
Expand Down
15 changes: 10 additions & 5 deletions includes/create-theme/theme-templates.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
160 changes: 160 additions & 0 deletions src/editor-sidebar/reset-theme.js
Original file line number Diff line number Diff line change
@@ -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 (
<>
<ConfirmDialog
isOpen={ isConfirmDialogOpen }
confirmButtonText={ __( 'Reset', 'create-block-theme' ) }
onCancel={ toggleConfirmDialog }
onConfirm={ handleResetTheme }
size="medium"
>
{ __(
'Are you sure you want to reset the theme? This action cannot be undone.',
'create-block-theme'
) }
</ConfirmDialog>
<PanelBody>
<ScreenHeader
title={ __( 'Reset Theme', 'create-block-theme' ) }
/>
<VStack>
<CheckboxControl
label={ __(
'Reset theme styles',
'create-block-theme'
) }
help={ __(
'Reset customizations to theme styles and settings.',
'create-block-theme'
) }
checked={ preferences.resetStyles }
onChange={ () =>
handleTogglePreference( 'resetStyles' )
}
/>

<CheckboxControl
label={ __(
'Reset theme templates',
'create-block-theme'
) }
help={ __(
'Reset customizations to theme templates.',
'create-block-theme'
) }
checked={ preferences.resetTemplates }
onChange={ () =>
handleTogglePreference( 'resetTemplates' )
}
/>

<CheckboxControl
label={ __(
'Reset theme template-parts',
'create-block-theme'
) }
help={ __(
'Reset customizations to theme template-parts.',
'create-block-theme'
) }
checked={ preferences.resetTemplateParts }
onChange={ () =>
handleTogglePreference( 'resetTemplateParts' )
}
/>

<Button
text={ __( 'Reset Theme', 'create-block-theme' ) }
variant="primary"
icon={ trash }
disabled={
! preferences.resetStyles &&
! preferences.resetTemplates &&
! preferences.resetTemplateParts
}
onClick={ toggleConfirmDialog }
/>
</VStack>
</PanelBody>
</>
);
}

export default ResetTheme;
23 changes: 22 additions & 1 deletion src/plugin-sidebar.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import {
addCard,
blockMeta,
help,
trash,
} from '@wordpress/icons';

/**
Expand All @@ -52,8 +53,9 @@ import { ThemeMetadataEditorModal } from './editor-sidebar/metadata-editor-modal
import ScreenHeader from './editor-sidebar/screen-header';
import { downloadExportedTheme } from './resolvers';
import downloadFile from './utils/download-file';
import './plugin-styles.scss';
import AboutPlugin from './editor-sidebar/about';
import ResetTheme from './editor-sidebar/reset-theme';
import './plugin-styles.scss';

const CreateBlockThemePlugin = () => {
const [ isEditorOpen, setIsEditorOpen ] = useState( false );
Expand Down Expand Up @@ -190,6 +192,21 @@ const CreateBlockThemePlugin = () => {

<Divider />

<NavigatorButton path="/reset" icon={ trash }>
<Spacer />
<HStack>
<FlexItem>
{ __(
'Reset Theme',
'create-block-theme'
) }
</FlexItem>
<Icon icon={ chevronRight } />
</HStack>
</NavigatorButton>

<Divider />

<NavigatorButton
path="/about"
icon={ help }
Expand Down Expand Up @@ -299,6 +316,10 @@ const CreateBlockThemePlugin = () => {
<NavigatorScreen path="/about">
<AboutPlugin />
</NavigatorScreen>

<NavigatorScreen path="/reset">
<ResetTheme />
</NavigatorScreen>
</NavigatorProvider>
</PluginSidebar>

Expand Down
20 changes: 20 additions & 0 deletions src/resolvers.js
Original file line number Diff line number Diff line change
Expand Up @@ -144,3 +144,23 @@ export async function getFontFamilies() {
} );
return response.data;
}

export async function resetTheme( preferences ) {
return apiFetch( {
path: '/create-block-theme/v1/reset-theme',
method: 'PATCH',
data: preferences,
headers: {
'Content-Type': 'application/json',
},
} ).then( ( response ) => {
if ( 'SUCCESS' !== response?.status ) {
throw new Error(
`Failed to reset theme: ${
response?.message || response?.status
}`
);
}
return response;
} );
}
Loading