- Timestamp:
- 10/20/2023 07:06:46 PM (14 months ago)
- Location:
- trunk
- Files:
-
- 3 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/block-patterns.php
r56931 r56978 342 342 343 343 foreach ( $themes as $theme ) { 344 $patterns = _wp_get_block_patterns( $theme);344 $patterns = $theme->get_block_patterns(); 345 345 $dirpath = $theme->get_stylesheet_directory() . '/patterns/'; 346 346 $text_domain = $theme->get( 'TextDomain' ); … … 388 388 } 389 389 add_action( 'init', '_register_theme_block_patterns' ); 390 391 /**392 * Gets block pattern data for a specified theme.393 * Each pattern is defined as a PHP file and defines394 * its metadata using plugin-style headers. The minimum required definition is:395 *396 * /**397 * * Title: My Pattern398 * * Slug: my-theme/my-pattern399 * *400 *401 * The output of the PHP source corresponds to the content of the pattern, e.g.:402 *403 * <main><p><?php echo "Hello"; ?></p></main>404 *405 * If applicable, this will collect from both parent and child theme.406 *407 * Other settable fields include:408 *409 * - Description410 * - Viewport Width411 * - Inserter (yes/no)412 * - Categories (comma-separated values)413 * - Keywords (comma-separated values)414 * - Block Types (comma-separated values)415 * - Post Types (comma-separated values)416 * - Template Types (comma-separated values)417 *418 * @since 6.4.0419 * @access private420 *421 * @param WP_Theme $theme Theme object.422 * @return array Block pattern data.423 */424 function _wp_get_block_patterns( WP_Theme $theme ) {425 $can_use_cached = ! wp_is_development_mode( 'theme' );426 427 $pattern_data = $theme->get_pattern_cache();428 if ( is_array( $pattern_data ) ) {429 if ( $can_use_cached ) {430 return $pattern_data;431 }432 // If in development mode, clear pattern cache.433 $theme->delete_pattern_cache();434 }435 436 $dirpath = $theme->get_stylesheet_directory() . '/patterns/';437 $pattern_data = array();438 439 if ( ! file_exists( $dirpath ) ) {440 if ( $can_use_cached ) {441 $theme->set_pattern_cache( $pattern_data );442 }443 return $pattern_data;444 }445 $files = glob( $dirpath . '*.php' );446 if ( ! $files ) {447 if ( $can_use_cached ) {448 $theme->set_pattern_cache( $pattern_data );449 }450 return $pattern_data;451 }452 453 $default_headers = array(454 'title' => 'Title',455 'slug' => 'Slug',456 'description' => 'Description',457 'viewportWidth' => 'Viewport Width',458 'inserter' => 'Inserter',459 'categories' => 'Categories',460 'keywords' => 'Keywords',461 'blockTypes' => 'Block Types',462 'postTypes' => 'Post Types',463 'templateTypes' => 'Template Types',464 );465 466 $properties_to_parse = array(467 'categories',468 'keywords',469 'blockTypes',470 'postTypes',471 'templateTypes',472 );473 474 foreach ( $files as $file ) {475 $pattern = get_file_data( $file, $default_headers );476 477 if ( empty( $pattern['slug'] ) ) {478 _doing_it_wrong(479 __FUNCTION__,480 sprintf(481 /* translators: 1: file name. */482 __( 'Could not register file "%s" as a block pattern ("Slug" field missing)' ),483 $file484 ),485 '6.0.0'486 );487 continue;488 }489 490 if ( ! preg_match( '/^[A-z0-9\/_-]+$/', $pattern['slug'] ) ) {491 _doing_it_wrong(492 __FUNCTION__,493 sprintf(494 /* translators: 1: file name; 2: slug value found. */495 __( 'Could not register file "%1$s" as a block pattern (invalid slug "%2$s")' ),496 $file,497 $pattern['slug']498 ),499 '6.0.0'500 );501 }502 503 // Title is a required property.504 if ( ! $pattern['title'] ) {505 _doing_it_wrong(506 __FUNCTION__,507 sprintf(508 /* translators: 1: file name. */509 __( 'Could not register file "%s" as a block pattern ("Title" field missing)' ),510 $file511 ),512 '6.0.0'513 );514 continue;515 }516 517 // For properties of type array, parse data as comma-separated.518 foreach ( $properties_to_parse as $property ) {519 if ( ! empty( $pattern[ $property ] ) ) {520 $pattern[ $property ] = array_filter( wp_parse_list( (string) $pattern[ $property ] ) );521 } else {522 unset( $pattern[ $property ] );523 }524 }525 526 // Parse properties of type int.527 $property = 'viewportWidth';528 if ( ! empty( $pattern[ $property ] ) ) {529 $pattern[ $property ] = (int) $pattern[ $property ];530 } else {531 unset( $pattern[ $property ] );532 }533 534 // Parse properties of type bool.535 $property = 'inserter';536 if ( ! empty( $pattern[ $property ] ) ) {537 $pattern[ $property ] = in_array(538 strtolower( $pattern[ $property ] ),539 array( 'yes', 'true' ),540 true541 );542 } else {543 unset( $pattern[ $property ] );544 }545 546 $key = str_replace( $dirpath, '', $file );547 548 $pattern_data[ $key ] = $pattern;549 }550 551 if ( $can_use_cached ) {552 $theme->set_pattern_cache( $pattern_data );553 }554 555 return $pattern_data;556 } -
trunk/src/wp-includes/class-wp-theme.php
r56943 r56978 846 846 847 847 /** 848 * Gets block pattern cache.849 *850 * @since 6.4.0851 *852 * @return array|false Returns an array of patterns if cache is found, otherwise false.853 */854 public function get_pattern_cache() {855 if ( ! $this->exists() ) {856 return false;857 }858 $pattern_data = get_transient( 'wp_theme_patterns_' . $this->stylesheet );859 if ( is_array( $pattern_data ) && $pattern_data['version'] === $this->get( 'Version' ) ) {860 return $pattern_data['patterns'];861 }862 return false;863 }864 865 /**866 * Sets block pattern cache.867 *868 * @since 6.4.0869 *870 * @param array $patterns Block patterns data to set in cache.871 */872 public function set_pattern_cache( array $patterns ) {873 $pattern_data = array(874 'version' => $this->get( 'Version' ),875 'patterns' => $patterns,876 );877 set_transient( 'wp_theme_patterns_' . $this->stylesheet, $pattern_data );878 }879 880 /**881 * Clears block pattern cache.882 *883 * @since 6.4.0884 */885 public function delete_pattern_cache() {886 delete_transient( 'wp_theme_patterns_' . $this->stylesheet );887 }888 889 /**890 848 * Gets a raw, unformatted theme header. 891 849 * … … 1842 1800 1843 1801 /** 1802 * Gets block pattern data for a specified theme. 1803 * Each pattern is defined as a PHP file and defines 1804 * its metadata using plugin-style headers. The minimum required definition is: 1805 * 1806 * /** 1807 * * Title: My Pattern 1808 * * Slug: my-theme/my-pattern 1809 * * 1810 * 1811 * The output of the PHP source corresponds to the content of the pattern, e.g.: 1812 * 1813 * <main><p><?php echo "Hello"; ?></p></main> 1814 * 1815 * If applicable, this will collect from both parent and child theme. 1816 * 1817 * Other settable fields include: 1818 * 1819 * - Description 1820 * - Viewport Width 1821 * - Inserter (yes/no) 1822 * - Categories (comma-separated values) 1823 * - Keywords (comma-separated values) 1824 * - Block Types (comma-separated values) 1825 * - Post Types (comma-separated values) 1826 * - Template Types (comma-separated values) 1827 * 1828 * @since 6.4.0 1829 * 1830 * @return array Block pattern data. 1831 */ 1832 public function get_block_patterns() { 1833 $can_use_cached = ! wp_is_development_mode( 'theme' ); 1834 1835 $pattern_data = $this->get_pattern_cache(); 1836 if ( is_array( $pattern_data ) ) { 1837 if ( $can_use_cached ) { 1838 return $pattern_data; 1839 } 1840 // If in development mode, clear pattern cache. 1841 $this->delete_pattern_cache(); 1842 } 1843 1844 $dirpath = $this->get_stylesheet_directory() . '/patterns/'; 1845 $pattern_data = array(); 1846 1847 if ( ! file_exists( $dirpath ) ) { 1848 if ( $can_use_cached ) { 1849 $this->set_pattern_cache( $pattern_data ); 1850 } 1851 return $pattern_data; 1852 } 1853 $files = glob( $dirpath . '*.php' ); 1854 if ( ! $files ) { 1855 if ( $can_use_cached ) { 1856 $this->set_pattern_cache( $pattern_data ); 1857 } 1858 return $pattern_data; 1859 } 1860 1861 $default_headers = array( 1862 'title' => 'Title', 1863 'slug' => 'Slug', 1864 'description' => 'Description', 1865 'viewportWidth' => 'Viewport Width', 1866 'inserter' => 'Inserter', 1867 'categories' => 'Categories', 1868 'keywords' => 'Keywords', 1869 'blockTypes' => 'Block Types', 1870 'postTypes' => 'Post Types', 1871 'templateTypes' => 'Template Types', 1872 ); 1873 1874 $properties_to_parse = array( 1875 'categories', 1876 'keywords', 1877 'blockTypes', 1878 'postTypes', 1879 'templateTypes', 1880 ); 1881 1882 foreach ( $files as $file ) { 1883 $pattern = get_file_data( $file, $default_headers ); 1884 1885 if ( empty( $pattern['slug'] ) ) { 1886 _doing_it_wrong( 1887 __FUNCTION__, 1888 sprintf( 1889 /* translators: 1: file name. */ 1890 __( 'Could not register file "%s" as a block pattern ("Slug" field missing)' ), 1891 $file 1892 ), 1893 '6.0.0' 1894 ); 1895 continue; 1896 } 1897 1898 if ( ! preg_match( '/^[A-z0-9\/_-]+$/', $pattern['slug'] ) ) { 1899 _doing_it_wrong( 1900 __FUNCTION__, 1901 sprintf( 1902 /* translators: 1: file name; 2: slug value found. */ 1903 __( 'Could not register file "%1$s" as a block pattern (invalid slug "%2$s")' ), 1904 $file, 1905 $pattern['slug'] 1906 ), 1907 '6.0.0' 1908 ); 1909 } 1910 1911 // Title is a required property. 1912 if ( ! $pattern['title'] ) { 1913 _doing_it_wrong( 1914 __FUNCTION__, 1915 sprintf( 1916 /* translators: 1: file name. */ 1917 __( 'Could not register file "%s" as a block pattern ("Title" field missing)' ), 1918 $file 1919 ), 1920 '6.0.0' 1921 ); 1922 continue; 1923 } 1924 1925 // For properties of type array, parse data as comma-separated. 1926 foreach ( $properties_to_parse as $property ) { 1927 if ( ! empty( $pattern[ $property ] ) ) { 1928 $pattern[ $property ] = array_filter( wp_parse_list( (string) $pattern[ $property ] ) ); 1929 } else { 1930 unset( $pattern[ $property ] ); 1931 } 1932 } 1933 1934 // Parse properties of type int. 1935 $property = 'viewportWidth'; 1936 if ( ! empty( $pattern[ $property ] ) ) { 1937 $pattern[ $property ] = (int) $pattern[ $property ]; 1938 } else { 1939 unset( $pattern[ $property ] ); 1940 } 1941 1942 // Parse properties of type bool. 1943 $property = 'inserter'; 1944 if ( ! empty( $pattern[ $property ] ) ) { 1945 $pattern[ $property ] = in_array( 1946 strtolower( $pattern[ $property ] ), 1947 array( 'yes', 'true' ), 1948 true 1949 ); 1950 } else { 1951 unset( $pattern[ $property ] ); 1952 } 1953 1954 $key = str_replace( $dirpath, '', $file ); 1955 1956 $pattern_data[ $key ] = $pattern; 1957 } 1958 1959 if ( $can_use_cached ) { 1960 $this->set_pattern_cache( $pattern_data ); 1961 } 1962 1963 return $pattern_data; 1964 } 1965 1966 /** 1967 * Gets block pattern cache. 1968 * 1969 * @since 6.4.0 1970 * 1971 * @return array|false Returns an array of patterns if cache is found, otherwise false. 1972 */ 1973 private function get_pattern_cache() { 1974 if ( ! $this->exists() ) { 1975 return false; 1976 } 1977 $pattern_data = wp_cache_get( 'wp_theme_patterns_' . $this->stylesheet ); 1978 if ( is_array( $pattern_data ) && $pattern_data['version'] === $this->get( 'Version' ) ) { 1979 return $pattern_data['patterns']; 1980 } 1981 return false; 1982 } 1983 1984 /** 1985 * Sets block pattern cache. 1986 * 1987 * @since 6.4.0 1988 * 1989 * @param array $patterns Block patterns data to set in cache. 1990 */ 1991 private function set_pattern_cache( array $patterns ) { 1992 $pattern_data = array( 1993 'version' => $this->get( 'Version' ), 1994 'patterns' => $patterns, 1995 ); 1996 wp_cache_set( 'wp_theme_patterns_' . $this->stylesheet, $pattern_data ); 1997 } 1998 1999 /** 2000 * Clears block pattern cache. 2001 * 2002 * @since 6.4.0 2003 */ 2004 public function delete_pattern_cache() { 2005 wp_cache_delete( 'wp_theme_patterns_' . $this->stylesheet ); 2006 } 2007 2008 /** 1844 2009 * Enables a theme for all sites on the current network. 1845 2010 * -
trunk/tests/phpunit/tests/theme/wpGetGlobalStylesheet.php
r56042 r56978 27 27 28 28 public function tear_down() { 29 // Reset development mode after each test. 30 unset( $GLOBALS['_wp_tests_development_mode'] ); 31 29 32 // Reset the theme support. 30 33 if ( $this->remove_theme_support_at_teardown ) { -
trunk/tests/phpunit/tests/theme/wpThemeGetBlockPatterns.php
r56977 r56978 1 1 <?php 2 2 /** 3 * Tests for _wp_get_block_patterns.3 * Tests for WP_Theme::get_block_patterns. 4 4 * 5 5 * @package WordPress … … 8 8 * 9 9 * @group blocks 10 * @group themes 10 11 * 11 * @covers ::_wp_get_block_patterns12 * @covers WP_Theme::get_block_patterns 12 13 */ 13 class Tests_Blocks_WpGetBlockPatterns extends WP_UnitTestCase { 14 class Tests_Theme_WPThemeGetBlockPatterns extends WP_UnitTestCase { 15 16 public static function wpSetUpBeforeClass() { 17 // Ensure development mode is reset before running these tests. 18 unset( $GLOBALS['_wp_tests_development_mode'] ); 19 } 20 21 public static function wpTearDownAfterClass() { 22 // Ensure development mode is reset after running these tests. 23 unset( $GLOBALS['_wp_tests_development_mode'] ); 24 } 25 26 /** 27 * Test helper to access the private get_pattern_cache method of a theme. 28 * 29 * @param WP_Theme $wp_theme A WP_Theme object. 30 * @return array|false Returns an array of patterns if cache is found, otherwise false. 31 */ 32 private function get_pattern_cache( $wp_theme ) { 33 $reflection = new ReflectionMethod( $wp_theme, 'get_pattern_cache' ); 34 $reflection->setAccessible( true ); 35 36 $pattern_cache = $reflection->invoke( $wp_theme, 'get_pattern_cache' ); 37 $reflection->setAccessible( false ); 38 39 return $pattern_cache; 40 } 41 14 42 /** 15 43 * @ticket 59490 16 44 * 17 * @dataProvider data_ wp_get_block_patterns45 * @dataProvider data_get_block_patterns 18 46 * 19 * @param string $theme 20 * @param array $expected The expected pattern data.47 * @param string $theme_slug The theme's slug. 48 * @param array $expected The expected pattern data. 21 49 */ 22 public function test_should_return_block_patterns( $theme, $expected ) { 23 $patterns = _wp_get_block_patterns( wp_get_theme( $theme ) ); 50 public function test_should_return_block_patterns( $theme_slug, $expected ) { 51 $theme = wp_get_theme( $theme_slug ); 52 $patterns = $theme->get_block_patterns(); 24 53 $this->assertSameSets( $expected, $patterns ); 25 54 } … … 27 56 /** 28 57 * @ticket 59490 58 * 59 * @covers WP_Theme::delete_pattern_cache 29 60 */ 30 public function test_delete_ theme_cache() {61 public function test_delete_pattern_cache() { 31 62 $theme = wp_get_theme( 'block-theme-patterns' ); 32 _wp_get_block_patterns( $theme ); 63 64 $this->assertTrue( $theme->exists(), 'The test theme could not be found.' ); 65 66 $theme->get_block_patterns(); 67 33 68 $this->assertSameSets( 34 69 array( … … 40 75 ), 41 76 ), 42 $th eme->get_pattern_cache(),43 'The transient for block theme patterns should be set'77 $this->get_pattern_cache( $theme ), 78 'The cache for block theme patterns should match the expected.' 44 79 ); 45 80 $theme->delete_pattern_cache(); 46 81 $this->assertFalse( 47 $th eme->get_pattern_cache(),48 'The transient for block theme patterns should have been cleared'82 $this->get_pattern_cache( $theme ), 83 'The cache for block theme patterns should have been cleared.' 49 84 ); 50 85 } … … 53 88 * @ticket 59490 54 89 */ 55 public function test_should_clear_ transient_after_switching_theme() {90 public function test_should_clear_cache_after_switching_theme() { 56 91 switch_theme( 'block-theme' ); 57 92 $theme1 = wp_get_theme(); 58 _wp_get_block_patterns( $theme1 ); 93 94 $this->assertTrue( $theme1->exists(), 'The block-theme test theme could not be found.' ); 95 96 $theme1->get_block_patterns(); 59 97 $this->assertSameSets( 60 98 array(), 61 $th eme1->get_pattern_cache(),62 'The transient for block theme should be set'99 $this->get_pattern_cache( $theme1 ), 100 'The cache for block theme should be empty.' 63 101 ); 102 64 103 switch_theme( 'block-theme-patterns' ); 65 $this->assertFalse( $theme1->get_pattern_cache(), 'Transient should not be set for block theme after switch theme' ); 104 66 105 $theme2 = wp_get_theme(); 67 $this->assertFalse( $theme2->get_pattern_cache(), 'Transient should not be set for block theme patterns before being requested' ); 68 _wp_get_block_patterns( $theme2 ); 106 $this->assertTrue( $theme2->exists(), 'The block-theme-patterns test theme could not be found.' ); 107 108 $this->assertFalse( $this->get_pattern_cache( $theme1 ), 'Cache should not be set for block theme after switch theme.' ); 109 $this->assertFalse( $this->get_pattern_cache( $theme2 ), 'Cache should not be set for block theme patterns before being requested.' ); 110 111 $theme2->get_block_patterns( $theme2 ); 69 112 $this->assertSameSets( 70 113 array( … … 77 120 78 121 ), 79 $th eme2->get_pattern_cache(),80 'The transient for block theme patterns should be set'122 $this->get_pattern_cache( $theme2 ), 123 'The cache for block theme patterns should match the expected.' 81 124 ); 82 125 } … … 87 130 * @return array[] 88 131 */ 89 public function data_ wp_get_block_patterns() {132 public function data_get_block_patterns() { 90 133 return array( 91 134 array( … … 120 163 121 164 /** 122 * Tests that _wp_get_block_patterns() clears existing transientwhen in theme development mode.165 * Tests that WP_Theme::get_block_patterns() clears existing cache when in theme development mode. 123 166 * 124 167 * @ticket 59591 125 168 */ 126 public function test_should_clear_existing_ transient_when_in_development_mode() {169 public function test_should_clear_existing_cache_when_in_development_mode() { 127 170 $theme = wp_get_theme( 'block-theme-patterns' ); 128 171 172 $this->assertTrue( $theme->exists(), 'The test theme could not be found.' ); 173 129 174 // Calling the function should set the cache. 130 _wp_get_block_patterns( $theme);175 $theme->get_block_patterns(); 131 176 $this->assertSameSets( 132 177 array( … … 138 183 ), 139 184 ), 140 $th eme->get_pattern_cache(),141 'The transient for block theme patterns should be set'185 $this->get_pattern_cache( $theme ), 186 'The cache for block theme patterns should be set.' 142 187 ); 143 188 144 189 // Calling the function while in theme development mode should clear the cache. 145 190 $GLOBALS['_wp_tests_development_mode'] = 'theme'; 146 _wp_get_block_patterns( $theme );191 $theme->get_block_patterns( $theme ); 147 192 unset( $GLOBALS['_wp_tests_development_mode'] ); // Reset to not pollute other tests. 148 193 $this->assertFalse( 149 $th eme->get_pattern_cache(),150 'The transient for block theme patterns should have been cleared due to theme development mode'194 $this->get_pattern_cache( $theme ), 195 'The cache for block theme patterns should have been cleared due to theme development mode.' 151 196 ); 152 197 }
Note: See TracChangeset
for help on using the changeset viewer.