Make WordPress Core


Ignore:
Timestamp:
04/11/2022 10:36:02 AM (4 years ago)
Author:
gziolo
Message:

Editor: Add functionality required for theme export in the site editor

This bring across changes to theme export functionality, and related code, and tests. Relates issue in Gutenberg: https://github.com/WordPress/gutenberg/issues/39889.

Props scruffian, timothyblynjacobs, oandregal, ajlende, zieleadam.
See #55505.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/block-template-utils.php

    r52923 r53129  
    120120                'home'           => array(
    121121                        'title'       => _x( 'Home', 'Template name' ),
    122                         'description' => __( 'Displays as the site\'s home page, or as the Posts page when a static home page isn\'t set.' ),
     122                        'description' => __( 'Displays posts on the homepage, or on the Posts page if a static homepage is set.' ),
    123123                ),
    124124                'front-page'     => array(
    125125                        'title'       => _x( 'Front Page', 'Template name' ),
    126                         'description' => __( 'Displays as the site\'s home page.' ),
     126                        'description' => __( 'Displays the homepage.' ),
    127127                ),
    128128                'singular'       => array(
     
    163163                ),
    164164                'attachment'     => array(
    165                         'title'       => __( 'Attachment' ),
     165                        'title'       => __( 'Media' ),
    166166                        'description' => __( 'Displays individual media items or attachments.' ),
    167167                ),
    168168                'search'         => array(
    169169                        'title'       => _x( 'Search', 'Template name' ),
    170                         'description' => __( 'Template used to display search results.' ),
     170                        'description' => __( 'Displays search results.' ),
    171171                ),
    172172                'privacy-policy' => array(
     
    904904
    905905/**
     906 * Filters theme directories that should be ignored during export.
     907 *
     908 * @since 6.0.0
     909 *
     910 * @param string $path The path of the file in the theme.
     911 * @return Bool Whether this file is in an ignored directory.
     912 */
     913function wp_is_theme_directory_ignored( $path ) {
     914        $directories_to_ignore = array( '.svn', '.git', '.hg', '.bzr', 'node_modules', 'vendor' );
     915        foreach ( $directories_to_ignore as $directory ) {
     916                if ( strpos( $path, $directory ) === 0 ) {
     917                        return true;
     918                }
     919        }
     920
     921        return false;
     922}
     923
     924/**
    906925 * Creates an export of the current templates and
    907926 * template parts from the site editor at the
     
    909928 *
    910929 * @since 5.9.0
     930 * @since 6.0.0 Adds the whole theme to the export archive.
    911931 *
    912932 * @return WP_Error|string Path of the ZIP file or error on failure.
     
    917937        }
    918938
    919         $obscura  = wp_generate_password( 12, false, false );
    920         $filename = get_temp_dir() . 'edit-site-export-' . $obscura . '.zip';
     939        $obscura    = wp_generate_password( 12, false, false );
     940        $theme_name = wp_get_theme()->get( 'TextDomain' );
     941        $filename   = get_temp_dir() . $theme_name . $obscura . '.zip';
    921942
    922943        $zip = new ZipArchive();
    923         if ( true !== $zip->open( $filename, ZipArchive::CREATE ) ) {
     944        if ( true !== $zip->open( $filename, ZipArchive::CREATE | ZipArchive::OVERWRITE ) ) {
    924945                return new WP_Error( 'unable_to_create_zip', __( 'Unable to open export file (archive) for writing.' ) );
    925946        }
    926947
    927         $zip->addEmptyDir( 'theme' );
    928         $zip->addEmptyDir( 'theme/templates' );
    929         $zip->addEmptyDir( 'theme/parts' );
     948        $zip->addEmptyDir( 'templates' );
     949        $zip->addEmptyDir( 'parts' );
     950
     951        // Get path of the theme.
     952        $theme_path = wp_normalize_path( get_stylesheet_directory() );
     953
     954        // Create recursive directory iterator.
     955        $theme_files = new RecursiveIteratorIterator(
     956                new RecursiveDirectoryIterator( $theme_path ),
     957                RecursiveIteratorIterator::LEAVES_ONLY
     958        );
     959
     960        // Make a copy of the current theme.
     961        foreach ( $theme_files as $file ) {
     962                // Skip directories as they are added automatically.
     963                if ( ! $file->isDir() ) {
     964                        // Get real and relative path for current file.
     965                        $file_path     = wp_normalize_path( $file );
     966                        $relative_path = substr( $file_path, strlen( $theme_path ) + 1 );
     967
     968                        if ( ! wp_is_theme_directory_ignored( $relative_path ) ) {
     969                                $zip->addFile( $file_path, $relative_path );
     970                        }
     971                }
     972        }
    930973
    931974        // Load templates into the zip file.
     
    935978
    936979                $zip->addFromString(
    937                         'theme/templates/' . $template->slug . '.html',
     980                        'templates/' . $template->slug . '.html',
    938981                        $template->content
    939982                );
     
    944987        foreach ( $template_parts as $template_part ) {
    945988                $zip->addFromString(
    946                         'theme/parts/' . $template_part->slug . '.html',
     989                        'parts/' . $template_part->slug . '.html',
    947990                        $template_part->content
    948991                );
    949992        }
    950993
     994        // Load theme.json into the zip file.
     995        $tree = WP_Theme_JSON_Resolver::get_theme_data( array(), array( 'with_supports' => false ) );
     996        // Merge with user data.
     997        $tree->merge( WP_Theme_JSON_Resolver::get_user_data() );
     998
     999        $theme_json_raw = $tree->get_data();
     1000        // If a version is defined, add a schema.
     1001        if ( $theme_json_raw['version'] ) {
     1002                global $wp_version;
     1003                $theme_json_version = 'wp/' . substr( $wp_version, 0, 3 );
     1004                $schema         = array( '$schema' => 'https://schemas.wp.org/' . $theme_json_version . '/theme.json' );
     1005                $theme_json_raw = array_merge( $schema, $theme_json_raw );
     1006        }
     1007
     1008        // Convert to a string.
     1009        $theme_json_encoded = wp_json_encode( $theme_json_raw, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE );
     1010
     1011        // Replace 4 spaces with a tab.
     1012        $theme_json_tabbed = preg_replace( '~(?:^|\G)\h{4}~m', "\t", $theme_json_encoded );
     1013
     1014        // Add the theme.json file to the zip.
     1015        $zip->addFromString(
     1016                'theme.json',
     1017                $theme_json_tabbed
     1018        );
     1019
    9511020        // Save changes to the zip file.
    9521021        $zip->close();
Note: See TracChangeset for help on using the changeset viewer.