Changeset 53129
- Timestamp:
- 04/11/2022 10:36:02 AM (2 years ago)
- Location:
- trunk
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/block-template-utils.php
r52923 r53129 120 120 'home' => array( 121 121 '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\'tset.' ),122 'description' => __( 'Displays posts on the homepage, or on the Posts page if a static homepage is set.' ), 123 123 ), 124 124 'front-page' => array( 125 125 'title' => _x( 'Front Page', 'Template name' ), 126 'description' => __( 'Displays as the site\'s homepage.' ),126 'description' => __( 'Displays the homepage.' ), 127 127 ), 128 128 'singular' => array( … … 163 163 ), 164 164 'attachment' => array( 165 'title' => __( ' Attachment' ),165 'title' => __( 'Media' ), 166 166 'description' => __( 'Displays individual media items or attachments.' ), 167 167 ), 168 168 'search' => array( 169 169 'title' => _x( 'Search', 'Template name' ), 170 'description' => __( ' Template used to displaysearch results.' ),170 'description' => __( 'Displays search results.' ), 171 171 ), 172 172 'privacy-policy' => array( … … 904 904 905 905 /** 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 */ 913 function 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 /** 906 925 * Creates an export of the current templates and 907 926 * template parts from the site editor at the … … 909 928 * 910 929 * @since 5.9.0 930 * @since 6.0.0 Adds the whole theme to the export archive. 911 931 * 912 932 * @return WP_Error|string Path of the ZIP file or error on failure. … … 917 937 } 918 938 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'; 921 942 922 943 $zip = new ZipArchive(); 923 if ( true !== $zip->open( $filename, ZipArchive::CREATE ) ) {944 if ( true !== $zip->open( $filename, ZipArchive::CREATE | ZipArchive::OVERWRITE ) ) { 924 945 return new WP_Error( 'unable_to_create_zip', __( 'Unable to open export file (archive) for writing.' ) ); 925 946 } 926 947 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 } 930 973 931 974 // Load templates into the zip file. … … 935 978 936 979 $zip->addFromString( 937 't heme/templates/' . $template->slug . '.html',980 'templates/' . $template->slug . '.html', 938 981 $template->content 939 982 ); … … 944 987 foreach ( $template_parts as $template_part ) { 945 988 $zip->addFromString( 946 ' theme/parts/' . $template_part->slug . '.html',989 'parts/' . $template_part->slug . '.html', 947 990 $template_part->content 948 991 ); 949 992 } 950 993 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 951 1020 // Save changes to the zip file. 952 1021 $zip->close(); -
trunk/src/wp-includes/class-wp-theme-json-resolver.php
r53072 r53129 152 152 * @since 5.8.0 153 153 * @since 5.9.0 Theme supports have been inlined and the `$theme_support_data` argument removed. 154 * @since 6.0.0 Adds a second parameter to allow the theme data to be returned without theme supports. 154 155 * 155 156 * @param array $deprecated Deprecated. Not used. 157 * @param array $options Contains a key called with_supports to determine whether to include theme supports in the data. 156 158 * @return WP_Theme_JSON Entity that holds theme data. 157 159 */ 158 public static function get_theme_data( $deprecated = array() ) {160 public static function get_theme_data( $deprecated = array(), $options = array() ) { 159 161 if ( ! empty( $deprecated ) ) { 160 162 _deprecated_argument( __METHOD__, '5.9.0' ); 161 163 } 164 165 $options = wp_parse_args( $options, array( 'with_supports' => true ) ); 166 162 167 if ( null === static::$theme ) { 163 168 $theme_json_data = static::read_json_file( static::get_file_path_from_theme( 'theme.json' ) ); … … 176 181 static::$theme = $parent_theme; 177 182 } 183 } 184 185 if ( ! $options['with_supports'] ) { 186 return static::$theme; 178 187 } 179 188 … … 209 218 } 210 219 $theme_support_data['settings']['color']['defaultGradients'] = $default_gradients; 220 221 // Classic themes without a theme.json don't support global duotone. 222 $theme_support_data['settings']['color']['defaultDuotone'] = false; 211 223 } 212 224 $with_theme_supports = new WP_Theme_JSON( $theme_support_data ); … … 478 490 return $variations; 479 491 } 492 480 493 } -
trunk/src/wp-includes/class-wp-theme-json.php
r52791 r53129 75 75 * This contains the necessary metadata to process them: 76 76 * 77 * - path => where to find the preset within the settings section 78 * - override => whether a theme preset with the same slug as a default preset 79 * can override it 77 * - path => Where to find the preset within the settings section. 78 * - prevent_override => Disables override of default presets by theme presets. 79 * The relationship between whether to override the defaults 80 * and whether the defaults are enabled is inverse: 81 * - If defaults are enabled => theme presets should not be overriden 82 * - If defaults are disabled => theme presets should be overriden 83 * For example, a theme sets defaultPalette to false, 84 * making the default palette hidden from the user. 85 * In that case, we want all the theme presets to be present, 86 * so they should override the defaults by setting this false. 80 87 * - use_default_names => whether to use the default names 81 * - value_key => the key that represents the value 82 * - value_func => optionally, instead of value_key, a function to generate 83 * the value that takes a preset as an argument 84 * (either value_key or value_func should be present) 85 * - css_vars => template string to use in generating the CSS Custom Property. 86 * Example output: "--wp--preset--duotone--blue: <value>" will generate 87 * as many CSS Custom Properties as presets defined 88 * substituting the $slug for the slug's value for each preset value. 89 * - classes => array containing a structure with the classes to 90 * generate for the presets, where for each array item 91 * the key is the class name and the value the property name. 92 * The "$slug" substring will be replaced by the slug of each preset. 93 * For example: 94 * 'classes' => array( 95 * '.has-$slug-color' => 'color', 96 * '.has-$slug-background-color' => 'background-color', 97 * '.has-$slug-border-color' => 'border-color', 98 * ) 99 * - properties => array of CSS properties to be used by kses to 100 * validate the content of each preset 101 * by means of the remove_insecure_properties method. 88 * - value_key => the key that represents the value 89 * - value_func => optionally, instead of value_key, a function to generate 90 * the value that takes a preset as an argument 91 * (either value_key or value_func should be present) 92 * - css_vars => template string to use in generating the CSS Custom Property. 93 * Example output: "--wp--preset--duotone--blue: <value>" will generate as many CSS Custom Properties as presets defined 94 * substituting the $slug for the slug's value for each preset value. 95 * - classes => array containing a structure with the classes to 96 * generate for the presets, where for each array item 97 * the key is the class name and the value the property name. 98 * The "$slug" substring will be replaced by the slug of each preset. 99 * For example: 100 * 'classes' => array( 101 * '.has-$slug-color' => 'color', 102 * '.has-$slug-background-color' => 'background-color', 103 * '.has-$slug-border-color' => 'border-color', 104 * ) 105 * - properties => array of CSS properties to be used by kses to 106 * validate the content of each preset 107 * by means of the remove_insecure_properties method. 102 108 * 103 109 * @since 5.8.0 104 110 * @since 5.9.0 Added the `color.duotone` and `typography.fontFamilies` presets, 105 111 * `use_default_names` preset key, and simplified the metadata structure. 112 * @since 6.0.0 Replaced `override` with `prevent_override` and updated the 113 * `prevent_overried` value for `color.duotone` to use `color.defaultDuotone`. 106 114 * @var array 107 115 */ … … 109 117 array( 110 118 'path' => array( 'color', 'palette' ), 111 ' override'=> array( 'color', 'defaultPalette' ),119 'prevent_override' => array( 'color', 'defaultPalette' ), 112 120 'use_default_names' => false, 113 121 'value_key' => 'color', … … 122 130 array( 123 131 'path' => array( 'color', 'gradients' ), 124 ' override'=> array( 'color', 'defaultGradients' ),132 'prevent_override' => array( 'color', 'defaultGradients' ), 125 133 'use_default_names' => false, 126 134 'value_key' => 'gradient', … … 131 139 array( 132 140 'path' => array( 'color', 'duotone' ), 133 ' override' => true,141 'prevent_override' => array( 'color', 'defaultDuotone' ), 134 142 'use_default_names' => false, 135 143 'value_func' => 'wp_get_duotone_filter_property', … … 140 148 array( 141 149 'path' => array( 'typography', 'fontSizes' ), 142 ' override' => true,150 'prevent_override' => false, 143 151 'use_default_names' => true, 144 152 'value_key' => 'size', … … 149 157 array( 150 158 'path' => array( 'typography', 'fontFamilies' ), 151 ' override' => true,159 'prevent_override' => false, 152 160 'use_default_names' => false, 153 161 'value_key' => 'fontFamily', … … 230 238 const VALID_TOP_LEVEL_KEYS = array( 231 239 'customTemplates', 240 'patterns', 232 241 'settings', 233 242 'styles', 234 243 'templateParts', 235 244 'version', 245 'title', 236 246 ); 237 247 … … 243 253 * added new properties for `border`, `color`, `spacing`, 244 254 * and `typography`, and renamed others according to the new schema. 255 * @since 6.0.0 Added `color.defaultDuotone`. 245 256 * @var array 246 257 */ … … 258 269 'customDuotone' => null, 259 270 'customGradient' => null, 271 'defaultDuotone' => null, 260 272 'defaultGradients' => null, 261 273 'defaultPalette' => null, … … 349 361 350 362 /** 363 * Options that settings.appearanceTools enables. 364 * 365 * @since 6.0.0 366 * @var array 367 */ 368 const APPEARANCE_TOOLS_OPT_INS = array( 369 array( 'border', 'color' ), 370 array( 'border', 'radius' ), 371 array( 'border', 'style' ), 372 array( 'border', 'width' ), 373 array( 'color', 'link' ), 374 array( 'spacing', 'blockGap' ), 375 array( 'spacing', 'margin' ), 376 array( 'spacing', 'padding' ), 377 array( 'typography', 'lineHeight' ), 378 ); 379 380 /** 351 381 * The latest version of the schema in use. 352 382 * … … 430 460 */ 431 461 protected static function do_opt_in_into_settings( &$context ) { 432 $to_opt_in = array( 433 array( 'border', 'color' ), 434 array( 'border', 'radius' ), 435 array( 'border', 'style' ), 436 array( 'border', 'width' ), 437 array( 'color', 'link' ), 438 array( 'spacing', 'blockGap' ), 439 array( 'spacing', 'margin' ), 440 array( 'spacing', 'padding' ), 441 array( 'typography', 'lineHeight' ), 442 ); 443 444 foreach ( $to_opt_in as $path ) { 462 foreach ( static::APPEARANCE_TOOLS_OPT_INS as $path ) { 445 463 // Use "unset prop" as a marker instead of "null" because 446 464 // "null" can be a valid value for some props (e.g. blockGap). … … 831 849 $has_block_gap_support = _wp_array_get( $this->theme_json, array( 'settings', 'spacing', 'blockGap' ) ) !== null; 832 850 if ( $has_block_gap_support ) { 833 $block_rules .= '.wp-site-blocks > * { margin- top: 0; margin-bottom: 0; }';834 $block_rules .= '.wp-site-blocks > * + * { margin- top: var( --wp--style--block-gap ); }';851 $block_rules .= '.wp-site-blocks > * { margin-block-start: 0; margin-block-end: 0; }'; 852 $block_rules .= '.wp-site-blocks > * + * { margin-block-start: var( --wp--style--block-gap ); }'; 835 853 } 836 854 } … … 1500 1518 1501 1519 return $nodes; 1520 } 1521 1522 /** 1523 * For metadata values that can either be booleans or paths to booleans, gets the value. 1524 * 1525 * ```php 1526 * $data = array( 1527 * 'color' => array( 1528 * 'defaultPalette' => true 1529 * ) 1530 * ); 1531 * 1532 * static::get_metadata_boolean( $data, false ); 1533 * // => false 1534 * 1535 * static::get_metadata_boolean( $data, array( 'color', 'defaultPalette' ) ); 1536 * // => true 1537 * ``` 1538 * 1539 * @since 6.0.0 1540 * 1541 * @param array $data The data to inspect. 1542 * @param bool|array $path Boolean or path to a boolean. 1543 * @param bool $default Default value if the referenced path is missing. 1544 * @return boolean 1545 */ 1546 protected static function get_metadata_boolean( $data, $path, $default = false ) { 1547 if ( is_bool( $path ) ) { 1548 return $path; 1549 } 1550 1551 if ( is_array( $path ) ) { 1552 $value = _wp_array_get( $data, $path ); 1553 if ( null !== $value ) { 1554 return $value; 1555 } 1556 } 1557 1558 return $default; 1502 1559 } 1503 1560 … … 1551 1608 // Replace the presets. 1552 1609 foreach ( static::PRESETS_METADATA as $preset ) { 1553 $override_preset = static::should_override_preset( $this->theme_json, $node['path'], $preset['override']);1610 $override_preset = ! static::get_metadata_boolean( $this->theme_json['settings'], $preset['prevent_override'], true ); 1554 1611 1555 1612 foreach ( static::VALID_ORIGINS as $origin ) { … … 1625 1682 * 1626 1683 * @since 5.9.0 1684 * @deprecated 6.0.0 Use {@see 'get_metadata_boolean'} instead. 1627 1685 * 1628 1686 * @param array $theme_json The theme.json like structure to inspect. 1629 * @param array $path Path to inspect.1630 * @param bool|array $override Data to compute whether to override the preset.1687 * @param array $path Path to inspect. 1688 * @param bool|array $override Data to compute whether to override the preset. 1631 1689 * @return boolean 1632 1690 */ 1633 1691 protected static function should_override_preset( $theme_json, $path, $override ) { 1692 _deprecated_function( __METHOD__, '6.0.0', 'get_metadata_boolean' ); 1693 1634 1694 if ( is_bool( $override ) ) { 1635 1695 return $override; … … 2014 2074 } 2015 2075 2076 /** 2077 * Returns the current theme's wanted patterns(slugs) to be 2078 * registered from Pattern Directory. 2079 * 2080 * @since 6.0.0 2081 * 2082 * @return string[] 2083 */ 2084 public function get_patterns() { 2085 if ( isset( $this->theme_json['patterns'] ) && is_array( $this->theme_json['patterns'] ) ) { 2086 return $this->theme_json['patterns']; 2087 } 2088 return array(); 2089 } 2090 2091 /** 2092 * Returns a valid theme.json as provided by a theme. 2093 * 2094 * Unlike get_raw_data() this returns the presets flattened, as provided by a theme. 2095 * This also uses appearanceTools instead of their opt-ins if all of them are true. 2096 * 2097 * @since 6.0.0 2098 * 2099 * @return array 2100 */ 2101 public function get_data() { 2102 $output = $this->theme_json; 2103 $nodes = static::get_setting_nodes( $output ); 2104 2105 /** 2106 * Flatten the theme & custom origins into a single one. 2107 * 2108 * For example, the following: 2109 * 2110 * { 2111 * "settings": { 2112 * "color": { 2113 * "palette": { 2114 * "theme": [ {} ], 2115 * "custom": [ {} ] 2116 * } 2117 * } 2118 * } 2119 * } 2120 * 2121 * will be converted to: 2122 * 2123 * { 2124 * "settings": { 2125 * "color": { 2126 * "palette": [ {} ] 2127 * } 2128 * } 2129 * } 2130 */ 2131 foreach ( $nodes as $node ) { 2132 foreach ( static::PRESETS_METADATA as $preset_metadata ) { 2133 $path = array_merge( $node['path'], $preset_metadata['path'] ); 2134 $preset = _wp_array_get( $output, $path, null ); 2135 if ( null === $preset ) { 2136 continue; 2137 } 2138 2139 $items = array(); 2140 if ( isset( $preset['theme'] ) ) { 2141 foreach ( $preset['theme'] as $item ) { 2142 $slug = $item['slug']; 2143 unset( $item['slug'] ); 2144 $items[ $slug ] = $item; 2145 } 2146 } 2147 if ( isset( $preset['custom'] ) ) { 2148 foreach ( $preset['custom'] as $item ) { 2149 $slug = $item['slug']; 2150 unset( $item['slug'] ); 2151 $items[ $slug ] = $item; 2152 } 2153 } 2154 $flattened_preset = array(); 2155 foreach ( $items as $slug => $value ) { 2156 $flattened_preset[] = array_merge( array( 'slug' => $slug ), $value ); 2157 } 2158 _wp_array_set( $output, $path, $flattened_preset ); 2159 } 2160 } 2161 2162 // If all of the static::APPEARANCE_TOOLS_OPT_INS are true, 2163 // this code unsets them and sets 'appearanceTools' instead. 2164 foreach ( $nodes as $node ) { 2165 $all_opt_ins_are_set = true; 2166 foreach ( static::APPEARANCE_TOOLS_OPT_INS as $opt_in_path ) { 2167 $full_path = array_merge( $node['path'], $opt_in_path ); 2168 // Use "unset prop" as a marker instead of "null" because 2169 // "null" can be a valid value for some props (e.g. blockGap). 2170 $opt_in_value = _wp_array_get( $output, $full_path, 'unset prop' ); 2171 if ( 'unset prop' === $opt_in_value ) { 2172 $all_opt_ins_are_set = false; 2173 break; 2174 } 2175 } 2176 2177 if ( $all_opt_ins_are_set ) { 2178 _wp_array_set( $output, array_merge( $node['path'], array( 'appearanceTools' ) ), true ); 2179 foreach ( static::APPEARANCE_TOOLS_OPT_INS as $opt_in_path ) { 2180 $full_path = array_merge( $node['path'], $opt_in_path ); 2181 // Use "unset prop" as a marker instead of "null" because 2182 // "null" can be a valid value for some props (e.g. blockGap). 2183 $opt_in_value = _wp_array_get( $output, $full_path, 'unset prop' ); 2184 if ( true !== $opt_in_value ) { 2185 continue; 2186 } 2187 2188 // The following could be improved to be path independent. 2189 // At the moment it relies on a couple of assumptions: 2190 // 2191 // - all opt-ins having a path of size 2. 2192 // - there's two sources of settings: the top-level and the block-level. 2193 if ( 2194 ( 1 === count( $node['path'] ) ) && 2195 ( 'settings' === $node['path'][0] ) 2196 ) { 2197 // Top-level settings. 2198 unset( $output['settings'][ $opt_in_path[0] ][ $opt_in_path[1] ] ); 2199 if ( empty( $output['settings'][ $opt_in_path[0] ] ) ) { 2200 unset( $output['settings'][ $opt_in_path[0] ] ); 2201 } 2202 } elseif ( 2203 ( 3 === count( $node['path'] ) ) && 2204 ( 'settings' === $node['path'][0] ) && 2205 ( 'blocks' === $node['path'][1] ) 2206 ) { 2207 // Block-level settings. 2208 $block_name = $node['path'][2]; 2209 unset( $output['settings']['blocks'][ $block_name ][ $opt_in_path[0] ][ $opt_in_path[1] ] ); 2210 if ( empty( $output['settings']['blocks'][ $block_name ][ $opt_in_path[0] ] ) ) { 2211 unset( $output['settings']['blocks'][ $block_name ][ $opt_in_path[0] ] ); 2212 } 2213 } 2214 } 2215 } 2216 } 2217 2218 wp_recursive_ksort( $output ); 2219 2220 return $output; 2221 } 2222 2016 2223 } -
trunk/src/wp-includes/functions.php
r53118 r53129 8441 8441 return abs( (float) $expected - (float) $actual ) <= $precision; 8442 8442 } 8443 8444 /** 8445 * Sorts the keys of an array alphabetically. 8446 * The array is passed by reference so it doesn't get returned 8447 * which mimics the behaviour of ksort. 8448 * 8449 * @since 6.0.0 8450 * 8451 * @param array $array The array to sort, passed by reference. 8452 */ 8453 function wp_recursive_ksort( &$array ) { 8454 foreach ( $array as &$value ) { 8455 if ( is_array( $value ) ) { 8456 wp_recursive_ksort( $value ); 8457 } 8458 } 8459 ksort( $array ); 8460 } -
trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-edit-site-export-controller.php
r52340 r53129 54 54 */ 55 55 public function permissions_check() { 56 if ( ! current_user_can( 'edit_theme_options' ) ) { 57 return new WP_Error( 58 'rest_cannot_export_templates', 59 __( 'Sorry, you are not allowed to export templates and template parts.' ), 60 array( 'status' => rest_authorization_required_code() ) 61 ); 56 if ( current_user_can( 'edit_theme_options' ) ) { 57 return true; 62 58 } 63 59 64 return true; 60 return new WP_Error( 61 'rest_cannot_export_templates', 62 __( 'Sorry, you are not allowed to export templates and template parts.' ), 63 array( 'status' => rest_authorization_required_code() ) 64 ); 65 65 } 66 66 … … 83 83 } 84 84 85 $theme_name = wp_get_theme()->get( 'TextDomain' ); 85 86 header( 'Content-Type: application/zip' ); 86 header( 'Content-Disposition: attachment; filename= edit-site-export.zip' );87 header( 'Content-Disposition: attachment; filename=' . $theme_name . '.zip' ); 87 88 header( 'Content-Length: ' . filesize( $filename ) ); 88 89 flush(); -
trunk/tests/phpunit/tests/block-template-utils.php
r52331 r53129 358 358 $zip = new ZipArchive(); 359 359 $zip->open( $filename ); 360 $has_theme_ dir = $zip->locateName( 'theme/' ) !== false;361 $has_block_templates_dir = $zip->locateName( 't heme/templates/' ) !== false;362 $has_block_template_parts_dir = $zip->locateName( ' theme/parts/' ) !== false;363 $this->assertTrue( $has_theme_ dir, 'theme directoryexists' );360 $has_theme_json = $zip->locateName( 'theme.json' ) !== false; 361 $has_block_templates_dir = $zip->locateName( 'templates/' ) !== false; 362 $has_block_template_parts_dir = $zip->locateName( 'parts/' ) !== false; 363 $this->assertTrue( $has_theme_json, 'theme.json exists' ); 364 364 $this->assertTrue( $has_block_templates_dir, 'theme/templates directory exists' ); 365 365 $this->assertTrue( $has_block_template_parts_dir, 'theme/parts directory exists' ); -
trunk/tests/phpunit/tests/functions.php
r53044 r53129 2174 2174 $this->assertEquals( 111, wp_filesize( $file ) ); 2175 2175 } 2176 2177 /** 2178 * @ticket 55505 2179 * @covers ::wp_recursive_ksort 2180 */ 2181 function test_wp_recursive_ksort() { 2182 // Create an array to test. 2183 $theme_json = array( 2184 'version' => 1, 2185 'settings' => array( 2186 'typography' => array( 2187 'fontFamilies' => array( 2188 'fontFamily' => 'DM Sans, sans-serif', 2189 'slug' => 'dm-sans', 2190 'name' => 'DM Sans', 2191 ), 2192 ), 2193 'color' => array( 2194 'palette' => array( 2195 array( 2196 'slug' => 'foreground', 2197 'color' => '#242321', 2198 'name' => 'Foreground', 2199 ), 2200 array( 2201 'slug' => 'background', 2202 'color' => '#FCFBF8', 2203 'name' => 'Background', 2204 ), 2205 array( 2206 'slug' => 'primary', 2207 'color' => '#71706E', 2208 'name' => 'Primary', 2209 ), 2210 array( 2211 'slug' => 'tertiary', 2212 'color' => '#CFCFCF', 2213 'name' => 'Tertiary', 2214 ), 2215 ), 2216 ), 2217 ), 2218 ); 2219 2220 // Sort the array. 2221 wp_recursive_ksort( $theme_json ); 2222 2223 // Expected result. 2224 $expected_theme_json = array( 2225 'settings' => array( 2226 'color' => array( 2227 'palette' => array( 2228 array( 2229 'color' => '#242321', 2230 'name' => 'Foreground', 2231 'slug' => 'foreground', 2232 ), 2233 array( 2234 'color' => '#FCFBF8', 2235 'name' => 'Background', 2236 'slug' => 'background', 2237 ), 2238 array( 2239 'color' => '#71706E', 2240 'name' => 'Primary', 2241 'slug' => 'primary', 2242 ), 2243 array( 2244 'color' => '#CFCFCF', 2245 'name' => 'Tertiary', 2246 'slug' => 'tertiary', 2247 ), 2248 ), 2249 ), 2250 'typography' => array( 2251 'fontFamilies' => array( 2252 'fontFamily' => 'DM Sans, sans-serif', 2253 'name' => 'DM Sans', 2254 'slug' => 'dm-sans', 2255 ), 2256 ), 2257 ), 2258 'version' => 1, 2259 ); 2260 $this->assertEquals( $theme_json, $expected_theme_json ); 2261 } 2262 2176 2263 } -
trunk/tests/phpunit/tests/theme/wpThemeJson.php
r52434 r53129 424 424 ); 425 425 426 $expected = 'body { margin: 0; }body{--wp--style--block-gap: 1em;}.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }.wp-site-blocks > * { margin- top: 0; margin-bottom: 0; }.wp-site-blocks > * + * { margin-top: var( --wp--style--block-gap ); }';427 $this->assert Same( $expected, $theme_json->get_stylesheet() );428 $this->assert Same( $expected, $theme_json->get_stylesheet( array( 'styles' ) ) );426 $expected = 'body { margin: 0; }body{--wp--style--block-gap: 1em;}.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }.wp-site-blocks > * { margin-block-start: 0; margin-block-end: 0; }.wp-site-blocks > * + * { margin-block-start: var( --wp--style--block-gap ); }'; 427 $this->assertEquals( $expected, $theme_json->get_stylesheet() ); 428 $this->assertEquals( $expected, $theme_json->get_stylesheet( array( 'styles' ) ) ); 429 429 } 430 430 … … 554 554 555 555 $variables = 'body{--wp--preset--color--grey: grey;--wp--preset--font-family--small: 14px;--wp--preset--font-family--big: 41px;}.wp-block-group{--wp--custom--base-font: 16;--wp--custom--line-height--small: 1.2;--wp--custom--line-height--medium: 1.4;--wp--custom--line-height--large: 1.8;}'; 556 $styles = 'body { margin: 0; }body{color: var(--wp--preset--color--grey);}.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }.wp-site-blocks > * { margin- top: 0; margin-bottom: 0; }.wp-site-blocks > * + * { margin-top: var( --wp--style--block-gap ); }a{background-color: #333;color: #111;}.wp-block-group{border-radius: 10px;padding: 24px;}.wp-block-group a{color: #111;}h1,h2,h3,h4,h5,h6{color: #123456;}h1 a,h2 a,h3 a,h4 a,h5 a,h6 a{background-color: #333;color: #111;font-size: 60px;}.wp-block-post-date{color: #123456;}.wp-block-post-date a{background-color: #777;color: #555;}.wp-block-image{border-top-left-radius: 10px;border-bottom-right-radius: 1em;margin-bottom: 30px;}';556 $styles = 'body { margin: 0; }body{color: var(--wp--preset--color--grey);}.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }.wp-site-blocks > * { margin-block-start: 0; margin-block-end: 0; }.wp-site-blocks > * + * { margin-block-start: var( --wp--style--block-gap ); }a{background-color: #333;color: #111;}.wp-block-group{border-radius: 10px;padding: 24px;}.wp-block-group a{color: #111;}h1,h2,h3,h4,h5,h6{color: #123456;}h1 a,h2 a,h3 a,h4 a,h5 a,h6 a{background-color: #333;color: #111;font-size: 60px;}.wp-block-post-date{color: #123456;}.wp-block-post-date a{background-color: #777;color: #555;}.wp-block-image{border-top-left-radius: 10px;border-bottom-right-radius: 1em;margin-bottom: 30px;}'; 557 557 $presets = '.has-grey-color{color: var(--wp--preset--color--grey) !important;}.has-grey-background-color{background-color: var(--wp--preset--color--grey) !important;}.has-grey-border-color{border-color: var(--wp--preset--color--grey) !important;}.has-small-font-family{font-family: var(--wp--preset--font-family--small) !important;}.has-big-font-family{font-family: var(--wp--preset--font-family--big) !important;}'; 558 558 $all = $variables . $styles . $presets; 559 $this->assert Same( $all, $theme_json->get_stylesheet() );560 $this->assert Same( $styles, $theme_json->get_stylesheet( array( 'styles' ) ) );561 $this->assert Same( $presets, $theme_json->get_stylesheet( array( 'presets' ) ) );562 $this->assert Same( $variables, $theme_json->get_stylesheet( array( 'variables' ) ) );559 $this->assertEquals( $all, $theme_json->get_stylesheet() ); 560 $this->assertEquals( $styles, $theme_json->get_stylesheet( array( 'styles' ) ) ); 561 $this->assertEquals( $presets, $theme_json->get_stylesheet( array( 'presets' ) ) ); 562 $this->assertEquals( $variables, $theme_json->get_stylesheet( array( 'variables' ) ) ); 563 563 } 564 564 … … 2385 2385 } 2386 2386 2387 /** 2388 * @ticket 55505 2389 */ 2390 function test_export_data() { 2391 $theme = new WP_Theme_JSON( 2392 array( 2393 'version' => 2, 2394 'settings' => array( 2395 'color' => array( 2396 'palette' => array( 2397 array( 2398 'slug' => 'white', 2399 'color' => 'white', 2400 'label' => 'White', 2401 ), 2402 array( 2403 'slug' => 'black', 2404 'color' => 'black', 2405 'label' => 'Black', 2406 ), 2407 ), 2408 ), 2409 ), 2410 ) 2411 ); 2412 $user = new WP_Theme_JSON( 2413 array( 2414 'version' => 2, 2415 'settings' => array( 2416 'color' => array( 2417 'palette' => array( 2418 array( 2419 'slug' => 'white', 2420 'color' => '#fff', 2421 'label' => 'User White', 2422 ), 2423 array( 2424 'slug' => 'hotpink', 2425 'color' => 'hotpink', 2426 'label' => 'hotpink', 2427 ), 2428 ), 2429 ), 2430 ), 2431 ), 2432 'custom' 2433 ); 2434 2435 $theme->merge( $user ); 2436 $actual = $theme->get_data(); 2437 $expected = array( 2438 'version' => 2, 2439 'settings' => array( 2440 'color' => array( 2441 'palette' => array( 2442 array( 2443 'slug' => 'white', 2444 'color' => '#fff', 2445 'label' => 'User White', 2446 ), 2447 array( 2448 'slug' => 'black', 2449 'color' => 'black', 2450 'label' => 'Black', 2451 ), 2452 array( 2453 'slug' => 'hotpink', 2454 'color' => 'hotpink', 2455 'label' => 'hotpink', 2456 ), 2457 ), 2458 ), 2459 ), 2460 ); 2461 2462 $this->assertEqualSetsWithIndex( $expected, $actual ); 2463 } 2464 2465 /** 2466 * @ticket 55505 2467 */ 2468 function test_export_data_deals_with_empty_user_data() { 2469 $theme = new WP_Theme_JSON( 2470 array( 2471 'version' => 2, 2472 'settings' => array( 2473 'color' => array( 2474 'palette' => array( 2475 array( 2476 'slug' => 'white', 2477 'color' => 'white', 2478 'label' => 'White', 2479 ), 2480 array( 2481 'slug' => 'black', 2482 'color' => 'black', 2483 'label' => 'Black', 2484 ), 2485 ), 2486 ), 2487 ), 2488 ) 2489 ); 2490 2491 $actual = $theme->get_data(); 2492 $expected = array( 2493 'version' => 2, 2494 'settings' => array( 2495 'color' => array( 2496 'palette' => array( 2497 array( 2498 'slug' => 'white', 2499 'color' => 'white', 2500 'label' => 'White', 2501 ), 2502 array( 2503 'slug' => 'black', 2504 'color' => 'black', 2505 'label' => 'Black', 2506 ), 2507 ), 2508 ), 2509 ), 2510 ); 2511 2512 $this->assertEqualSetsWithIndex( $expected, $actual ); 2513 } 2514 2515 /** 2516 * @ticket 55505 2517 */ 2518 function test_export_data_deals_with_empty_theme_data() { 2519 $user = new WP_Theme_JSON( 2520 array( 2521 'version' => 2, 2522 'settings' => array( 2523 'color' => array( 2524 'palette' => array( 2525 array( 2526 'slug' => 'white', 2527 'color' => '#fff', 2528 'label' => 'User White', 2529 ), 2530 array( 2531 'slug' => 'hotpink', 2532 'color' => 'hotpink', 2533 'label' => 'hotpink', 2534 ), 2535 ), 2536 ), 2537 ), 2538 ), 2539 'custom' 2540 ); 2541 2542 $actual = $user->get_data(); 2543 $expected = array( 2544 'version' => 2, 2545 'settings' => array( 2546 'color' => array( 2547 'palette' => array( 2548 array( 2549 'slug' => 'white', 2550 'color' => '#fff', 2551 'label' => 'User White', 2552 ), 2553 array( 2554 'slug' => 'hotpink', 2555 'color' => 'hotpink', 2556 'label' => 'hotpink', 2557 ), 2558 ), 2559 ), 2560 ), 2561 ); 2562 2563 $this->assertEqualSetsWithIndex( $expected, $actual ); 2564 } 2565 2566 /** 2567 * @ticket 55505 2568 */ 2569 function test_export_data_deals_with_empty_data() { 2570 $theme_v2 = new WP_Theme_JSON( 2571 array( 2572 'version' => 2, 2573 ), 2574 'theme' 2575 ); 2576 $actual_v2 = $theme_v2->get_data(); 2577 $expected_v2 = array( 'version' => 2 ); 2578 $this->assertEqualSetsWithIndex( $expected_v2, $actual_v2 ); 2579 2580 $theme_v1 = new WP_Theme_JSON( 2581 array( 2582 'version' => 1, 2583 ), 2584 'theme' 2585 ); 2586 $actual_v1 = $theme_v1->get_data(); 2587 $expected_v1 = array( 'version' => 2 ); 2588 $this->assertEqualSetsWithIndex( $expected_v1, $actual_v1 ); 2589 } 2590 2591 /** 2592 * @ticket 55505 2593 */ 2594 function test_export_data_sets_appearance_tools() { 2595 $theme = new WP_Theme_JSON( 2596 array( 2597 'version' => 2, 2598 'settings' => array( 2599 'appearanceTools' => true, 2600 'blocks' => array( 2601 'core/paragraph' => array( 2602 'appearanceTools' => true, 2603 ), 2604 ), 2605 ), 2606 ) 2607 ); 2608 2609 $actual = $theme->get_data(); 2610 $expected = array( 2611 'version' => 2, 2612 'settings' => array( 2613 'appearanceTools' => true, 2614 'blocks' => array( 2615 'core/paragraph' => array( 2616 'appearanceTools' => true, 2617 ), 2618 ), 2619 ), 2620 ); 2621 2622 $this->assertEqualSetsWithIndex( $expected, $actual ); 2623 } 2387 2624 }
Note: See TracChangeset
for help on using the changeset viewer.