diff --git a/includes/class-create-block-theme-api.php b/includes/class-create-block-theme-api.php index a620fbb0..f7ff32fc 100644 --- a/includes/class-create-block-theme-api.php +++ b/includes/class-create-block-theme-api.php @@ -13,6 +13,7 @@ require_once __DIR__ . '/create-theme/theme-readme.php'; require_once __DIR__ . '/create-theme/theme-fonts.php'; require_once __DIR__ . '/create-theme/theme-create.php'; +require_once __DIR__ . '/create-theme/theme-fluid-typography.php'; /** * The api functionality of the plugin leveraged by the site editor UI. diff --git a/includes/create-theme/theme-fluid-typography.php b/includes/create-theme/theme-fluid-typography.php new file mode 100644 index 00000000..65fbe197 --- /dev/null +++ b/includes/create-theme/theme-fluid-typography.php @@ -0,0 +1,68 @@ + $font_size ) { + // Check if this font size has fluid settings + if ( isset( $font_size['fluid'] ) && is_array( $font_size['fluid'] ) ) { + // If fluid.max is set, sync it with size + if ( isset( $font_size['fluid']['max'] ) ) { + $font_sizes[ $key ]['size'] = $font_size['fluid']['max']; + } + } + } + + $data['settings']['typography']['fontSizes'] = $font_sizes; + + return $data; + } + + /** + * Hook into the global styles REST API to sync fluid typography sizes. + */ + public static function init() { + add_filter( 'rest_pre_insert_wp_global_styles', array( __CLASS__, 'sync_global_styles_fluid_typography' ), 10, 2 ); + } + + /** + * Sync fluid typography in global styles before saving. + * + * @param stdClass $prepared_post The prepared post object. + * @return stdClass The modified prepared post object. + */ + public static function sync_global_styles_fluid_typography( $prepared_post ) { + if ( ! isset( $prepared_post->post_content ) ) { + return $prepared_post; + } + + $data = json_decode( $prepared_post->post_content, true ); + + if ( ! is_array( $data ) ) { + return $prepared_post; + } + + $data = self::sync_fluid_typography_sizes( $data ); + + $prepared_post->post_content = wp_json_encode( $data ); + + return $prepared_post; + } +} + +// Initialize the fluid typography sync on plugins_loaded +add_action( 'plugins_loaded', array( 'CBT_Theme_Fluid_Typography', 'init' ) ); diff --git a/tests/test-fluid-typography.php b/tests/test-fluid-typography.php new file mode 100644 index 00000000..b8ebb0ce --- /dev/null +++ b/tests/test-fluid-typography.php @@ -0,0 +1,129 @@ + array( + 'typography' => array( + 'fontSizes' => array( + array( + 'slug' => 'custom-fluid', + 'name' => 'Custom Fluid', + 'fluid' => array( + 'min' => '1.5rem', + 'max' => '5.63rem', + ), + 'size' => '3rem', // Old value, should be updated + ), + array( + 'slug' => 'normal', + 'name' => 'Normal', + 'size' => '1rem', // No fluid, should remain unchanged + ), + ), + ), + ), + ); + + $result = CBT_Theme_Fluid_Typography::sync_fluid_typography_sizes( $data ); + + // Verify the fluid size was synced + $this->assertEquals( + '5.63rem', + $result['settings']['typography']['fontSizes'][0]['size'], + 'Fluid typography size should be synced with fluid.max' + ); + + // Verify the non-fluid size remained unchanged + $this->assertEquals( + '1rem', + $result['settings']['typography']['fontSizes'][1]['size'], + 'Non-fluid typography size should remain unchanged' + ); + } + + /** + * Test that global styles filter works correctly + */ + public function test_sync_global_styles_fluid_typography() { + $prepared_post = new stdClass(); + $prepared_post->post_content = wp_json_encode( + array( + 'settings' => array( + 'typography' => array( + 'fontSizes' => array( + array( + 'slug' => 'custom-fluid', + 'name' => 'Custom Fluid', + 'fluid' => array( + 'min' => '1.5rem', + 'max' => '5.63rem', + ), + 'size' => '3rem', + ), + ), + ), + ), + ) + ); + + $result = CBT_Theme_Fluid_Typography::sync_global_styles_fluid_typography( $prepared_post ); + + $data = json_decode( $result->post_content, true ); + + $this->assertEquals( + '5.63rem', + $data['settings']['typography']['fontSizes'][0]['size'], + 'Global styles should have synced fluid typography sizes' + ); + } + + /** + * Test that missing typography doesn't cause errors + */ + public function test_sync_with_no_typography() { + $data = array( + 'settings' => array(), + ); + + $result = CBT_Theme_Fluid_Typography::sync_fluid_typography_sizes( $data ); + + $this->assertArrayNotHasKey( 'typography', $result['settings'] ); + $this->assertEqualsCanonicalizing( array(), $result['settings'] ); + } + + /** + * Test that missing fontSizes doesn't cause errors + */ + public function test_sync_with_no_font_sizes() { + $data = array( + 'settings' => array( + 'typography' => array(), + ), + ); + + $result = CBT_Theme_Fluid_Typography::sync_fluid_typography_sizes( $data ); + + $this->assertArrayNotHasKey( 'fontSizes', $result['settings']['typography'] ); + } + + /** + * Test that invalid JSON in global styles filter is handled gracefully + */ + public function test_sync_global_styles_with_invalid_json() { + $prepared_post = new stdClass(); + $prepared_post->post_content = 'invalid json'; + + $result = CBT_Theme_Fluid_Typography::sync_global_styles_fluid_typography( $prepared_post ); + + // Should return the prepared post unchanged + $this->assertEquals( 'invalid json', $result->post_content ); + } +}