Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Font Library support for S3, CDNs, immutable file systems, atomic deployments, etc #1

Merged
merged 10 commits into from
Mar 3, 2024
1 change: 1 addition & 0 deletions .github/workflows/phpunit.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ jobs:
run:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
php-versions: ['7.4', '8.0', '8.1', '8.2', '8.3']
wp-versions: [ 'trunk' ]
Expand Down
56 changes: 56 additions & 0 deletions inc/namespace.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,61 @@
* Bootstrap the plugin.
*/
function bootstrap() {
add_filter( 'font_dir', __NAMESPACE__ . '\\filter_default_font_directory' );

/*
* Prime the uploads directory cache.
*
* This runs late on the `init` hook to allow time for plugins to register
* custom upload directory file handlers.
*/
add_action( 'init', __NAMESPACE__ . '\\cached_wp_get_upload_dir', 20 );
}

/**
* Store the uploads directory in a static variable.
*
* This is the prevent the potential for infinite loops in the event
* an extender includes `add_filter( 'upload_dir', 'wp_get_font_dir' );`
* in their code base.
*
* Without a primed cache, `wp_get_upload_dir()` would trigger the a call
* to `wp_get_font_dir()` which would trigger a call to `wp_get_upload_dir()`.
*
* @see https://github.com/pantheon-systems/pantheon-mu-plugin/blob/main/inc/fonts.php for inspiration.
*
* @return array Result of wp_get_upload_dir().
*/
function cached_wp_get_upload_dir() {
static $cached = null;

if ( null === $cached ) {
$cached = wp_get_upload_dir();
}

return $cached;
}

/**
* Filter the WordPress default font directory to use the uploads folder.
*
* Relocated files uploaded by the Font Library from `wp-content/fonts/` to a
* sub-directory of the uploads folder.
*
* @param array $font_directory The default in which to store fonts.
* @return array The modified fonts directory.
*/
function filter_default_font_directory( $font_directory ) {
$upload_dir = cached_wp_get_upload_dir();

$font_directory = array(
'path' => untrailingslashit( $upload_dir['basedir'] ) . '/wp-fonts',
'url' => untrailingslashit( $upload_dir['baseurl'] ) . '/wp-fonts',
'subdir' => '',
'basedir' => untrailingslashit( $upload_dir['basedir'] ) . '/wp-fonts',
'baseurl' => untrailingslashit( $upload_dir['baseurl'] ) . '/wp-fonts',
'error' => false,
);

return $font_directory;
}
52 changes: 49 additions & 3 deletions tests/class-test-fonts-to-uploads.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,57 @@
* Test the rewrite rules.
*/
class Test_Fonts_To_Uploads extends WP_UnitTestCase {

/**
* Ensure tests are running.
* Ensure `add_filter( 'upload_dir', 'wp_get_font_dir' );` does not trigger an infinite loop.
*/
public function test_sample() {
public function test_filter_does_not_cause_infinite_loop() {
add_filter( 'upload_dir', 'wp_get_font_dir' );

add_filter(
'upload_dir',
function( $upload_dir ) {
static $count = 0;
++$count;
$this->assertSame( 1, $count, 'Filtering uploads directory should not trigger infinite loop.' );
return $upload_dir;
},
5
);

$uploads = wp_get_upload_dir();

// This will never be hit if an infinite loop is triggered.
$this->assertTrue( true );
}

/**
* Ensure font directory begins with uploads base path.
*
* @dataProvider data_font_directory_begins_with_upload_base_path
*
* @param string $key The key to compare.
* @param string|false $uploads_key The uploads key to check against.
*/
public function test_font_directory_begins_with_upload_base_path( $key, $uploads_key ) {
$uploads = wp_get_upload_dir();
$fonts = wp_get_font_dir();

$this->assertArrayHasKey( $key, $uploads, "Uploads[{$uploads_key}] is not set." );
$this->assertArrayHasKey( $key, $fonts, "Fonts[{$key}] is not set." );
$this->assertStringStartsWith( $uploads[ $uploads_key ], $fonts[ $key ], "Fonts[{$key}] does not begin with uploads[{$uploads_key}]." );
}

/**
* Data provider for test_font_directory_begins_with_upload_base_path
*
* @return array[] Data Provider
*/
public function data_font_directory_begins_with_upload_base_path() {
return array(
array( 'path', 'basedir' ),
array( 'url', 'baseurl' ),
array( 'basedir', 'basedir' ),
array( 'baseurl', 'baseurl' ),
);
}
}
Loading