Changeset 48141
- Timestamp:
- 06/23/2020 03:43:19 PM (4 years ago)
- Location:
- trunk
- Files:
-
- 5 added
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/blocks.php
r48102 r48141 39 39 function unregister_block_type( $name ) { 40 40 return WP_Block_Type_Registry::get_instance()->unregister( $name ); 41 } 42 43 /** 44 * Removes the block asset's path prefix if provided. 45 * 46 * @since 5.5.0 47 * 48 * @param string $asset_handle_or_path Asset handle or prefixed path. 49 * @return string Path without the prefix or the original value. 50 */ 51 function remove_block_asset_path_prefix( $asset_handle_or_path ) { 52 $path_prefix = 'file:'; 53 if ( 0 !== strpos( $asset_handle_or_path, $path_prefix ) ) { 54 return $asset_handle_or_path; 55 } 56 return substr( 57 $asset_handle_or_path, 58 strlen( $path_prefix ) 59 ); 60 } 61 62 /** 63 * Generates the name for an asset based on the name of the block 64 * and the field name provided. 65 * 66 * @since 5.5.0 67 * 68 * @param string $block_name Name of the block. 69 * @param string $field_name Name of the metadata field. 70 * @return string Generated asset name for the block's field. 71 */ 72 function generate_block_asset_handle( $block_name, $field_name ) { 73 $field_mappings = array( 74 'editorScript' => 'editor-script', 75 'script' => 'script', 76 'editorStyle' => 'editor-style', 77 'style' => 'style', 78 ); 79 return str_replace( '/', '-', $block_name ) . 80 '-' . $field_mappings[ $field_name ]; 81 } 82 83 /** 84 * Finds a script handle for the selected block metadata field. It detects 85 * when a path to file was provided and finds a corresponding 86 * asset file with details necessary to register the script under 87 * automatically generated handle name. It returns unprocessed script handle 88 * otherwise. 89 * 90 * @since 5.5.0 91 * 92 * @param array $metadata Block metadata. 93 * @param string $field_name Field name to pick from metadata. 94 * @return string|bool Script handle provided directly or created through 95 * script's registration, or false on failure. 96 */ 97 function register_block_script_handle( $metadata, $field_name ) { 98 if ( empty( $metadata[ $field_name ] ) ) { 99 return false; 100 } 101 $script_handle = $metadata[ $field_name ]; 102 $script_path = remove_block_asset_path_prefix( $metadata[ $field_name ] ); 103 if ( $script_handle === $script_path ) { 104 return $script_handle; 105 } 106 107 $script_handle = generate_block_asset_handle( $metadata['name'], $field_name ); 108 $script_asset_path = realpath( 109 dirname( $metadata['file'] ) . '/' . 110 substr_replace( $script_path, '.asset.php', - strlen( '.js' ) ) 111 ); 112 if ( ! file_exists( $script_asset_path ) ) { 113 $message = sprintf( 114 /* translators: %1: field name. %2: block name */ 115 __( 'The asset file for the "%1$s" defined in "%2$s" block definition is missing.', 'default' ), 116 $field_name, 117 $metadata['name'] 118 ); 119 _doing_it_wrong( __FUNCTION__, $message, '5.5.0' ); 120 return false; 121 } 122 $script_asset = require $script_asset_path; 123 $result = wp_register_script( 124 $script_handle, 125 plugins_url( $script_path, $metadata['file'] ), 126 $script_asset['dependencies'], 127 $script_asset['version'] 128 ); 129 return $result ? $script_handle : false; 130 } 131 132 /** 133 * Finds a style handle for the block metadata field. It detects when a path 134 * to file was provided and registers the style under automatically 135 * generated handle name. It returns unprocessed style handle otherwise. 136 * 137 * @since 5.5.0 138 * 139 * @param array $metadata Block metadata. 140 * @param string $field_name Field name to pick from metadata. 141 * @return string|boolean Style handle provided directly or created through 142 * style's registration, or false on failure. 143 */ 144 function register_block_style_handle( $metadata, $field_name ) { 145 if ( empty( $metadata[ $field_name ] ) ) { 146 return false; 147 } 148 $style_handle = $metadata[ $field_name ]; 149 $style_path = remove_block_asset_path_prefix( $metadata[ $field_name ] ); 150 if ( $style_handle === $style_path ) { 151 return $style_handle; 152 } 153 154 $style_handle = generate_block_asset_handle( $metadata['name'], $field_name ); 155 $block_dir = dirname( $metadata['file'] ); 156 $result = wp_register_style( 157 $style_handle, 158 plugins_url( $style_path, $metadata['file'] ), 159 array(), 160 filemtime( realpath( "$block_dir/$style_path" ) ) 161 ); 162 return $result ? $style_handle : false; 163 } 164 165 /** 166 * Registers a block type from metadata stored in the `block.json` file. 167 * 168 * @since 5.5.0 169 * 170 * @param string $file_or_folder Path to the JSON file with metadata definition for 171 * the block or path to the folder where the `block.json` file is located. 172 * @param array $args { 173 * Optional. Array of block type arguments. Any arguments may be defined, however the 174 * ones described below are supported by default. Default empty array. 175 * 176 * @type callable $render_callback Callback used to render blocks of this block type. 177 * } 178 * @return WP_Block_Type|false The registered block type on success, or false on failure. 179 */ 180 function register_block_type_from_metadata( $file_or_folder, $args = array() ) { 181 $filename = 'block.json'; 182 $metadata_file = ( substr( $file_or_folder, -strlen( $filename ) ) !== $filename ) ? 183 trailingslashit( $file_or_folder ) . $filename : 184 $file_or_folder; 185 if ( ! file_exists( $metadata_file ) ) { 186 return false; 187 } 188 189 $metadata = json_decode( file_get_contents( $metadata_file ), true ); 190 if ( ! is_array( $metadata ) || empty( $metadata['name'] ) ) { 191 return false; 192 } 193 $metadata['file'] = $metadata_file; 194 195 $settings = array(); 196 $property_mappings = array( 197 'title' => 'title', 198 'category' => 'category', 199 'parent' => 'parent', 200 'icon' => 'icon', 201 'description' => 'description', 202 'keywords' => 'keywords', 203 'attributes' => 'attributes', 204 'providesContext' => 'provides_context', 205 'usesContext' => 'uses_context', 206 'supports' => 'supports', 207 'styles' => 'styles', 208 'example' => 'example', 209 ); 210 211 foreach ( $property_mappings as $key => $mapped_key ) { 212 if ( isset( $metadata[ $key ] ) ) { 213 $settings[ $mapped_key ] = $metadata[ $key ]; 214 } 215 } 216 217 if ( ! empty( $metadata['editorScript'] ) ) { 218 $settings['editor_script'] = register_block_script_handle( 219 $metadata, 220 'editorScript' 221 ); 222 } 223 224 if ( ! empty( $metadata['script'] ) ) { 225 $settings['script'] = register_block_script_handle( 226 $metadata, 227 'script' 228 ); 229 } 230 231 if ( ! empty( $metadata['editorStyle'] ) ) { 232 $settings['editor_style'] = register_block_style_handle( 233 $metadata, 234 'editorStyle' 235 ); 236 } 237 238 if ( ! empty( $metadata['style'] ) ) { 239 $settings['style'] = register_block_style_handle( 240 $metadata, 241 'style' 242 ); 243 } 244 245 return register_block_type( 246 $metadata['name'], 247 array_merge( 248 $settings, 249 $args 250 ) 251 ); 41 252 } 42 253 -
trunk/tests/phpunit/tests/blocks/register.php
r46586 r48141 104 104 105 105 /** 106 * @ticket 50263 107 */ 108 function test_does_not_remove_block_asset_path_prefix() { 109 $result = remove_block_asset_path_prefix( 'script-handle' ); 110 111 $this->assertSame( 'script-handle', $result ); 112 } 113 114 /** 115 * @ticket 50263 116 */ 117 function test_removes_block_asset_path_prefix() { 118 $result = remove_block_asset_path_prefix( 'file:./block.js' ); 119 120 $this->assertSame( './block.js', $result ); 121 } 122 123 /** 124 * @ticket 50263 125 */ 126 function test_generate_block_asset_handle() { 127 $block_name = 'unit-tests/my-block'; 128 129 $this->assertSame( 130 'unit-tests-my-block-editor-script', 131 generate_block_asset_handle( $block_name, 'editorScript' ) 132 ); 133 $this->assertSame( 134 'unit-tests-my-block-script', 135 generate_block_asset_handle( $block_name, 'script' ) 136 ); 137 $this->assertSame( 138 'unit-tests-my-block-editor-style', 139 generate_block_asset_handle( $block_name, 'editorStyle' ) 140 ); 141 $this->assertSame( 142 'unit-tests-my-block-style', 143 generate_block_asset_handle( $block_name, 'style' ) 144 ); 145 } 146 147 /** 148 * @ticket 50263 149 */ 150 function test_field_not_found_register_block_script_handle() { 151 $result = register_block_script_handle( array(), 'script' ); 152 153 $this->assertFalse( $result ); 154 } 155 156 /** 157 * @ticket 50263 158 */ 159 function test_empty_value_register_block_script_handle() { 160 $metadata = array( 'script' => '' ); 161 $result = register_block_script_handle( $metadata, 'script' ); 162 163 $this->assertFalse( $result ); 164 } 165 166 /** 167 * @expectedIncorrectUsage register_block_script_handle 168 * @ticket 50263 169 */ 170 function test_missing_asset_file_register_block_script_handle() { 171 $metadata = array( 172 'file' => __FILE__, 173 'name' => 'unit-tests/test-block', 174 'script' => 'file:./fixtures/missing-asset.js', 175 ); 176 $result = register_block_script_handle( $metadata, 'script' ); 177 178 $this->assertFalse( $result ); 179 } 180 181 /** 182 * @ticket 50263 183 */ 184 function test_handle_passed_register_block_script_handle() { 185 $metadata = array( 186 'editorScript' => 'test-script-handle', 187 ); 188 $result = register_block_script_handle( $metadata, 'editorScript' ); 189 190 $this->assertSame( 'test-script-handle', $result ); 191 } 192 193 /** 194 * @ticket 50263 195 */ 196 function test_success_register_block_script_handle() { 197 $metadata = array( 198 'file' => __FILE__, 199 'name' => 'unit-tests/test-block', 200 'script' => 'file:./fixtures/block.js', 201 ); 202 $result = register_block_script_handle( $metadata, 'script' ); 203 204 $this->assertSame( 'unit-tests-test-block-script', $result ); 205 } 206 207 /** 208 * @ticket 50263 209 */ 210 function test_field_not_found_register_block_style_handle() { 211 $result = register_block_style_handle( array(), 'style' ); 212 213 $this->assertFalse( $result ); 214 } 215 216 /** 217 * @ticket 50263 218 */ 219 function test_empty_value_found_register_block_style_handle() { 220 $metadata = array( 'style' => '' ); 221 $result = register_block_style_handle( $metadata, 'style' ); 222 223 $this->assertFalse( $result ); 224 } 225 226 /** 227 * @ticket 50263 228 */ 229 function test_handle_passed_register_block_style_handle() { 230 $metadata = array( 231 'style' => 'test-style-handle', 232 ); 233 $result = register_block_style_handle( $metadata, 'style' ); 234 235 $this->assertSame( 'test-style-handle', $result ); 236 } 237 238 /** 239 * @ticket 50263 240 */ 241 function test_success_register_block_style_handle() { 242 $metadata = array( 243 'file' => __FILE__, 244 'name' => 'unit-tests/test-block', 245 'style' => 'file:./fixtures/block.css', 246 ); 247 $result = register_block_style_handle( $metadata, 'style' ); 248 249 $this->assertSame( 'unit-tests-test-block-style', $result ); 250 } 251 252 /** 253 * Tests that the function returns false when the `block.json` is not found 254 * in the WordPress core. 255 * 256 * @ticket 50263 257 */ 258 function test_metadata_not_found_in_wordpress_core() { 259 $result = register_block_type_from_metadata( 'unknown' ); 260 261 $this->assertFalse( $result ); 262 } 263 264 /** 265 * Tests that the function returns false when the `block.json` is not found 266 * in the current directory. 267 * 268 * @ticket 50263 269 */ 270 function test_metadata_not_found_in_the_current_directory() { 271 $result = register_block_type_from_metadata( __DIR__ ); 272 273 $this->assertFalse( $result ); 274 } 275 276 /** 277 * Tests that the function returns the registered block when the `block.json` 278 * is found in the fixtures directory. 279 * 280 * @ticket 50263 281 */ 282 function test_block_registers_with_metadata_fixture() { 283 $result = register_block_type_from_metadata( 284 __DIR__ . '/fixtures' 285 ); 286 287 $this->assertInstanceOf( 'WP_Block_Type', $result ); 288 $this->assertSame( 'my-plugin/notice', $result->name ); 289 $this->assertSame( 'Notice', $result->title ); 290 $this->assertSame( 'common', $result->category ); 291 $this->assertEqualSets( array( 'core/group' ), $result->parent ); 292 $this->assertSame( 'star', $result->icon ); 293 $this->assertSame( 'Shows warning, error or success notices…', $result->description ); 294 $this->assertEqualSets( array( 'alert', 'message' ), $result->keywords ); 295 $this->assertEquals( 296 array( 297 'message' => array( 298 'type' => 'string', 299 'source' => 'html', 300 'selector' => '.message', 301 ), 302 ), 303 $result->attributes 304 ); 305 $this->assertEquals( 306 array( 307 'my-plugin/message' => 'message', 308 ), 309 $result->provides_context 310 ); 311 $this->assertEqualSets( array( 'groupId' ), $result->uses_context ); 312 $this->assertEquals( 313 array( 314 'align' => true, 315 'lightBlockWrapper' => true, 316 ), 317 $result->supports 318 ); 319 $this->assertEquals( 320 array( 321 array( 322 'name' => 'default', 323 'label' => 'Default', 324 'isDefault' => true, 325 ), 326 array( 327 'name' => 'other', 328 'label' => 'Other', 329 ), 330 ), 331 $result->styles 332 ); 333 $this->assertEquals( 334 array( 335 'attributes' => array( 336 'message' => 'This is a notice!', 337 ), 338 ), 339 $result->example 340 ); 341 $this->assertSame( 'my-plugin-notice-editor-script', $result->editor_script ); 342 $this->assertSame( 'my-plugin-notice-script', $result->script ); 343 $this->assertSame( 'my-plugin-notice-editor-style', $result->editor_style ); 344 $this->assertSame( 'my-plugin-notice-style', $result->style ); 345 } 346 347 /** 106 348 * @ticket 45109 107 349 */
Note: See TracChangeset
for help on using the changeset viewer.