diff --git a/admin/class-create-block-theme-admin.php b/admin/class-create-block-theme-admin.php index 50e9b18c..471701db 100644 --- a/admin/class-create-block-theme-admin.php +++ b/admin/class-create-block-theme-admin.php @@ -28,6 +28,45 @@ function create_admin_menu() { add_theme_page( $page_title, $menu_title, 'edit_theme_options', 'create-block-theme', [ $this, 'create_admin_form_page' ] ); } + function save_theme_locally( $export_type ) { + $this->add_templates_to_local( $export_type ); + $this->add_theme_json_to_local( $export_type ); + } + + function clear_user_customizations() { + + // Clear all values in the user theme.json + $user_custom_post_type_id = WP_Theme_JSON_Resolver_Gutenberg::get_user_global_styles_post_id(); + $global_styles_controller = new Gutenberg_REST_Global_Styles_Controller(); + $update_request = new WP_REST_Request( 'PUT', '/wp/v2/global-styles/' ); + $update_request->set_param( 'id', $user_custom_post_type_id ); + $update_request->set_param( 'settings', [] ); + $update_request->set_param( 'styles', [] ); + $updated_global_styles = $global_styles_controller->update_item( $update_request ); + delete_transient( 'global_styles' ); + delete_transient( 'global_styles_' . get_stylesheet() ); + delete_transient( 'gutenberg_global_styles' ); + delete_transient( 'gutenberg_global_styles_' . get_stylesheet() ); + + //remove all user templates (they have been saved in the theme) + $templates = gutenberg_get_block_templates(); + $template_parts = gutenberg_get_block_templates( array(), 'wp_template_part' ); + foreach ( $template_parts as $template ) { + if ( $template->source !== 'custom' ) { + continue; + } + wp_delete_post($template->wp_id, true); + } + + foreach ( $templates as $template ) { + if ( $template->source !== 'custom' ) { + continue; + } + wp_delete_post($template->wp_id, true); + } + + } + /** * Export activated child theme */ @@ -233,14 +272,20 @@ function export_theme( $theme ) { } function add_theme_json_to_zip ( $zip, $export_type ) { - $theme_json = MY_Theme_JSON_Resolver::export_theme_data( $export_type ); $zip->addFromString( 'theme.json', - wp_json_encode( $theme_json, JSON_PRETTY_PRINT ) + MY_Theme_JSON_Resolver::export_theme_data( $export_type ) ); return $zip; } + function add_theme_json_to_local ( $export_type ) { + file_put_contents( + get_template_directory() . '/theme.json', + MY_Theme_JSON_Resolver::export_theme_data( $export_type ) + ); + } + function copy_theme_to_zip( $zip, $new_slug, $new_name ) { // Get real path for our folder @@ -331,30 +376,46 @@ function get_theme_slug( $new_theme_name ) { return $new_slug; } - /** - * Add block templates and parts to the zip. - * - * @since 0.0.2 - * @param object $zip The zip archive to add the templates to. - * @param string $export_type Determine the templates that should be exported. - * current = templates from currently activated theme (but not a parent theme if there is one) as well as user edited templates - * user = only user edited templates - * all = all templates no matter what + /* + * Filter a template out (return false) based on the export_type expected and the templates origin. + * Templates not filtered out are modified based on the slug information provided and cleaned up + * to have the expected exported value. */ - function add_templates_to_zip( $zip, $export_type, $new_slug ) { - - $templates = gutenberg_get_block_templates(); - $template_parts = gutenberg_get_block_templates( array(), 'wp_template_part' ); - $old_slug = wp_get_theme()->get( 'TextDomain' ); - - if ( $templates ) { - $zip->addEmptyDir( 'templates' ); + function filter_theme_template( $template, $export_type, $path, $old_slug, $new_slug ) { + if ($template->source === 'theme' && $export_type === 'user') { + return false; + } + if ( + $template->source === 'theme' && + $export_type === 'current' && + ! file_exists( $path . $template->slug . '.html' ) + ) { + return false; } - if ( $template_parts ) { - $zip->addEmptyDir( 'parts' ); + $template->content = _remove_theme_attribute_in_block_template_content( $template->content ); + + // NOTE: Dashes are encoded as \u002d in the content that we get (noteably in things like css variables used in templates) + // This replaces that with dashes again. We should consider decoding the entire string but that is proving difficult. + $template->content = str_replace( '\u002d', '-', $template->content ); + + if ( $new_slug ) { + $template->content = str_replace( $old_slug, $new_slug, $template->content ); } + return $template; + } + + /* + * Build a collection of templates and template-parts that should be exported (and modified) based on the given export_type and new slug + */ + function get_theme_templates( $export_type, $new_slug ) { + + $old_slug = wp_get_theme()->get( 'TextDomain' ); + $templates = gutenberg_get_block_templates(); + $template_parts = gutenberg_get_block_templates ( array(), 'wp_template_part' ); + $exported_templates = []; + $exported_parts = []; // build collection of templates/parts in currently activated theme $templates_paths = get_block_theme_folders(); @@ -362,49 +423,69 @@ function add_templates_to_zip( $zip, $export_type, $new_slug ) { $parts_path = get_stylesheet_directory() . '/' . $templates_paths['wp_template_part'] . '/'; foreach ( $templates as $template ) { - if ($template->source === 'theme' && $export_type === 'user') { - continue; + $template = $this->filter_theme_template( + $template, + $export_type, + $templates_path, + $old_slug, + $new_slug + ); + if ( $template ) { + $exported_templates[] = $template; } + } - if ( - $template->source === 'theme' && - $export_type === 'current' && - ! file_exists( $templates_path . $template->slug . '.html' ) - ) { - continue; + foreach ( $template_parts as $template ) { + $template = $this->filter_theme_template( + $template, + $export_type, + $parts_path, + $old_slug, + $new_slug + + ); + if ( $template ) { + $exported_parts[] = $template; } + } - $template->content = _remove_theme_attribute_in_block_template_content( $template->content ); + return (object)[ + 'templates'=>$exported_templates, + 'parts'=>$exported_parts + ]; + + } - if ( $new_slug ) { - $template->content = str_replace( $old_slug, $new_slug, $template->content ); - } + /** + * Add block templates and parts to the zip. + * + * @since 0.0.2 + * @param object $zip The zip archive to add the templates to. + * @param string $export_type Determine the templates that should be exported. + * current = templates from currently activated theme (but not a parent theme if there is one) as well as user edited templates + * user = only user edited templates + * all = all templates no matter what + */ + function add_templates_to_zip( $zip, $export_type, $new_slug ) { + + $theme_templates = $this->get_theme_templates( $export_type, $new_slug ); + if ( $theme_templates->templates ) { + $zip->addEmptyDir( 'templates' ); + } + + if ( $theme_templates->parts ) { + $zip->addEmptyDir( 'parts' ); + } + + foreach ( $theme_templates->templates as $template ) { $zip->addFromString( 'templates/' . $template->slug . '.html', $template->content ); } - foreach ( $template_parts as $template_part ) { - if ($template_part->source === 'theme' && $export_type === 'user') { - continue; - } - - if ( - $template_part->source === 'theme' && - $export_type === 'current' && - ! file_exists( $parts_path . $template_part->slug . '.html' ) - ) { - continue; - } - - $template_part->content = _remove_theme_attribute_in_block_template_content( $template_part->content ); - - if ( $new_slug ) { - $template_part->content = str_replace( $old_slug, $new_slug, $template_part->content ); - } - + foreach ( $theme_templates->parts as $template_part ) { $zip->addFromString( 'parts/' . $template_part->slug . '.html', $template_part->content @@ -414,6 +495,25 @@ function add_templates_to_zip( $zip, $export_type, $new_slug ) { return $zip; } + function add_templates_to_local( $export_type ) { + + $theme_templates = $this->get_theme_templates( $export_type, null ); + + foreach ( $theme_templates->templates as $template ) { + file_put_contents( + get_template_directory() . '/templates/' . $template->slug . '.html', + $template->content + ); + } + + foreach ( $theme_templates->parts as $template_part ) { + file_put_contents( + get_template_directory() . '/parts/' . $template_part->slug . '.html', + $template_part->content + ); + } + } + function create_zip( $filename ) { if ( ! class_exists( 'ZipArchive' ) ) { return new WP_Error( 'Zip Export not supported.' ); @@ -510,7 +610,7 @@ function create_admin_form_page() { ?>

-

+

@@ -525,6 +625,8 @@ function create_admin_form_page() {

+ +

- +
save_theme_locally( 'current' ); + } + else { + $this->save_theme_locally( 'all' ); + } + $this->clear_user_customizations(); + + add_action( 'admin_notices', [ $this, 'admin_notice_save_success' ] ); + } + + else if ( is_child_theme() ) { if ( $_GET['theme']['type'] === 'sibling' ) { $this->create_sibling_theme( $_GET['theme'] ); } else { $this->export_child_theme( $_GET['theme'] ); } - + add_action( 'admin_notices', [ $this, 'admin_notice_export_success' ] ); } else { if( $_GET['theme']['type'] === 'child' ) { $this->create_child_theme( $_GET['theme'] ); @@ -574,9 +687,9 @@ function blockbase_save_theme() { else { $this->export_theme( $_GET['theme'] ); } + add_action( 'admin_notices', [ $this, 'admin_notice_export_success' ] ); } - add_action( 'admin_notices', [ $this, 'admin_notice_success' ] ); } } @@ -587,10 +700,18 @@ function admin_notice_error() { printf( '

%2$s

', esc_attr( $class ), esc_html( $message ) ); } - function admin_notice_success() { + function admin_notice_export_success() { + ?> +
+

+
+
-

+

get_raw_data(), null); - return $data; + $theme_json = wp_json_encode( $data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE ); + return preg_replace ( '~(?:^|\G)\h{4}~m', "\t", $theme_json ); + } }