diff --git a/lib/experimental/fonts/font-library/font-library.php b/lib/experimental/fonts/font-library/font-library.php index 3f41c13a00514..eb76cbab19128 100644 --- a/lib/experimental/fonts/font-library/font-library.php +++ b/lib/experimental/fonts/font-library/font-library.php @@ -187,3 +187,60 @@ function wp_get_font_dir( $defaults = array() ) { return apply_filters( 'font_dir', $defaults ); } } + +// @core-merge: Filters should go in `src/wp-includes/default-filters.php`, +// functions in a general file for font library. +if ( ! function_exists( '_wp_delete_font_family' ) ) { + /** + * Deletes child font faces when a font family is deleted. + * + * @access private + * @since 6.5.0 + * + * @param int $post_id Post ID. + * @param WP_Post $post Post object. + * @return void + */ + function _wp_delete_font_family( $post_id, $post ) { + if ( 'wp_font_family' !== $post->post_type ) { + return; + } + + $font_faces = get_children( + array( + 'post_parent' => $post_id, + 'post_type' => 'wp_font_face', + ) + ); + + foreach ( $font_faces as $font_face ) { + wp_delete_post( $font_face->ID, true ); + } + } + add_action( 'deleted_post', '_wp_delete_font_family', 10, 2 ); +} + +if ( ! function_exists( '_wp_delete_font_face' ) ) { + /** + * Deletes associated font files when a font face is deleted. + * + * @access private + * @since 6.5.0 + * + * @param int $post_id Post ID. + * @param WP_Post $post Post object. + * @return void + */ + function _wp_delete_font_face( $post_id, $post ) { + if ( 'wp_font_face' !== $post->post_type ) { + return; + } + + $font_files = get_post_meta( $post_id, '_wp_font_face_files', false ); + + foreach ( $font_files as $font_file ) { + wp_delete_file( wp_get_font_dir()['path'] . '/' . $font_file ); + } + } + add_action( 'before_delete_post', '_wp_delete_font_face', 10, 2 ); +} diff --git a/phpunit/tests/fonts/font-library/fontLibraryHooks.php b/phpunit/tests/fonts/font-library/fontLibraryHooks.php new file mode 100644 index 0000000000000..546b08b24ae25 --- /dev/null +++ b/phpunit/tests/fonts/font-library/fontLibraryHooks.php @@ -0,0 +1,85 @@ +post->create( + array( + 'post_type' => 'wp_font_family', + ) + ); + $font_face_id = self::factory()->post->create( + array( + 'post_type' => 'wp_font_face', + 'post_parent' => $font_family_id, + ) + ); + $other_font_family_id = self::factory()->post->create( + array( + 'post_type' => 'wp_font_family', + ) + ); + $other_font_face_id = self::factory()->post->create( + array( + 'post_type' => 'wp_font_face', + 'post_parent' => $other_font_family_id, + ) + ); + + wp_delete_post( $font_family_id, true ); + + $this->assertNull( get_post( $font_face_id ) ); + $this->assertNotNull( get_post( $other_font_face_id ) ); + } + + public function test_deleting_font_faces_deletes_associated_font_files() { + list( $font_face_id, $font_path ) = $this->create_font_face_with_file( 'OpenSans-Regular.woff2' ); + list( , $other_font_path ) = $this->create_font_face_with_file( 'OpenSans-Regular.ttf' ); + + wp_delete_post( $font_face_id, true ); + + $this->assertFalse( file_exists( $font_path ) ); + $this->assertTrue( file_exists( $other_font_path ) ); + } + + protected function create_font_face_with_file( $filename ) { + $font_face_id = self::factory()->post->create( + array( + 'post_type' => 'wp_font_face', + ) + ); + + $font_file = $this->upload_font_file( $filename ); + + // Make sure the font file uploaded successfully. + $this->assertFalse( $font_file['error'] ); + + $font_path = $font_file['file']; + $font_filename = basename( $font_path ); + add_post_meta( $font_face_id, '_wp_font_face_files', $font_filename ); + + return array( $font_face_id, $font_path ); + } + + protected function upload_font_file( $font_filename ) { + // @core-merge Use `DIR_TESTDATA` instead of `GUTENBERG_DIR_TESTDATA`. + $font_file_path = GUTENBERG_DIR_TESTDATA . 'fonts/' . $font_filename; + + add_filter( 'upload_mimes', array( 'WP_Font_Library', 'set_allowed_mime_types' ) ); + add_filter( 'upload_dir', 'wp_get_font_dir' ); + $font_file = wp_upload_bits( + $font_filename, + null, + file_get_contents( $font_file_path ) + ); + remove_filter( 'upload_dir', 'wp_get_font_dir' ); + remove_filter( 'upload_mimes', array( 'WP_Font_Library', 'set_allowed_mime_types' ) ); + + return $font_file; + } +} diff --git a/phpunit/tests/fonts/font-library/wpRestFontFamiliesController.php b/phpunit/tests/fonts/font-library/wpRestFontFamiliesController.php index 1f7e86ab92fe5..b11e0de3d2cc2 100644 --- a/phpunit/tests/fonts/font-library/wpRestFontFamiliesController.php +++ b/phpunit/tests/fonts/font-library/wpRestFontFamiliesController.php @@ -762,12 +762,11 @@ protected function check_font_family_data( $data, $post_id, $links ) { $this->assertArrayHasKey( 'theme_json_version', $data ); $this->assertSame( WP_Theme_JSON::LATEST_SCHEMA, $data['theme_json_version'] ); - $font_face_ids = get_posts( + $font_face_ids = get_children( array( - 'fields' => 'ids', - 'post_parent' => $post_id, - 'post_type' => 'wp_font_face', - 'posts_per_page' => 999, + 'fields' => 'ids', + 'post_parent' => $post_id, + 'post_type' => 'wp_font_face', ) ); $this->assertArrayHasKey( 'font_faces', $data );