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

Added a 'save' option #51

Merged
merged 11 commits into from
Mar 28, 2022
241 changes: 181 additions & 60 deletions admin/class-create-block-theme-admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -331,80 +376,116 @@ 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();
$templates_path = get_stylesheet_directory() . '/' . $templates_paths['wp_template'] . '/';
$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
Expand All @@ -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.' );
Expand Down Expand Up @@ -510,7 +610,7 @@ function create_admin_form_page() {
?>
<div class="wrap">
<h2><?php _e('Create Block Theme', 'create-block-theme'); ?></h2>
<p><?php _e('Save your current block them with changes you made to Templates, Template Parts and Global Styles.', 'create-block-theme'); ?></p>
<p><?php _e('Export your current block them with changes you made to Templates, Template Parts and Global Styles.', 'create-block-theme'); ?></p>
<form method="get">

<label><input checked value="export" type="radio" name="theme[type]" class="regular-text code" onchange="document.getElementById('new_theme_metadata_form').setAttribute('hidden', null);" /><?php _e('Export ', 'create-block-theme'); echo wp_get_theme()->get('Name'); ?></label>
Expand All @@ -525,6 +625,8 @@ function create_admin_form_page() {
<label><input value="clone" type="radio" name="theme[type]" class="regular-text code" onchange="document.getElementById('new_theme_metadata_form').removeAttribute('hidden');"/><?php _e('Clone ', 'create-block-theme'); echo wp_get_theme()->get('Name'); ?>
<?php _e('[Create a new theme cloning the activated theme. The resulting theme will have all of the assets of the activated theme as well as user changes.]', 'create-block-theme'); ?></label><br /><br />
<?php endif; ?>
<label><input value="save" type="radio" name="theme[type]" class="regular-text code" onchange="document.getElementById('new_theme_metadata_form').setAttribute('hidden', null);" /><?php _e('Overwrite ', 'create-block-theme'); echo wp_get_theme()->get('Name'); ?></label>
<?php _e('[Save USER changes as THEME changes and delete the USER changes. Your changes will be saved in the theme on the folder.]', 'create-block-theme'); ?></label><br /><br />

<div hidden id="new_theme_metadata_form">
<label><?php _e('Theme Name', 'create-block-theme'); ?><br /><input type="text" name="theme[name]" class="regular-text" /></label><br /><br />
Expand All @@ -535,15 +637,14 @@ function create_admin_form_page() {
</div>
<input type="hidden" name="page" value="create-block-theme" />
<input type="hidden" name="nonce" value="<?php echo wp_create_nonce( 'create_block_theme' ); ?>" />
<input type="submit" value="<?php _e('Create block theme', 'create-block-theme'); ?>" class="button button-primary" />
<input type="submit" value="<?php _e('Export theme', 'create-block-theme'); ?>" class="button button-primary" />
</form>
</div>
<?php
}

function blockbase_save_theme() {

// I can't work out how to call the API but this works for now.
if ( ! empty( $_GET['page'] ) && $_GET['page'] === 'create-block-theme' && ! empty( $_GET['theme'] ) ) {

// Check user capabilities.
Expand All @@ -556,14 +657,26 @@ function blockbase_save_theme() {
return add_action( 'admin_notices', [ $this, 'admin_notice_error' ] );
}

if ( is_child_theme() ) {
if ( $_GET['theme']['type'] === 'save' ) {
if ( is_child_theme() ) {
$this->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'] );
Expand All @@ -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' ] );
}
}

Expand All @@ -587,10 +700,18 @@ function admin_notice_error() {
printf( '<div class="%1$s"><p>%2$s</p></div>', esc_attr( $class ), esc_html( $message ) );
}

function admin_notice_success() {
function admin_notice_export_success() {
?>
<div class="notice notice-success is-dismissible">
<p><?php _e( 'Block theme exported sucessfuly!', 'create-block-theme' ); ?></p>
</div>
<?php
}

function admin_notice_save_success() {
?>
<div class="notice notice-success is-dismissible">
<p><?php _e( 'New block theme created!', 'create-block-theme' ); ?></p>
<p><?php _e( 'Block theme saved and user customizations cleared!', 'create-block-theme' ); ?></p>
</div>
<?php
}
Expand Down
4 changes: 3 additions & 1 deletion admin/gutenberg_additions.php
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,9 @@ public static function export_theme_data( $content ) {

$data = MY_Theme_JSON_Resolver::flatten_theme_json($theme->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 );

}

}
Expand Down