From 2dfd2dac862e9626055db1400612731ced018bb8 Mon Sep 17 00:00:00 2001 From: Luca Tumedei Date: Wed, 1 May 2024 17:11:25 +0200 Subject: [PATCH] feat(Asset) support callable dependencies --- README.md | 12 +++++++ src/Assets/Asset.php | 20 +++++------ src/Assets/Assets.php | 4 +-- tests/wpunit/AssetsTest.php | 66 +++++++++++++++++++++++++++++++++++++ 4 files changed, 90 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 0303b37..ee2d22a 100644 --- a/README.md +++ b/README.md @@ -150,6 +150,18 @@ Asset::add( 'script-with-dependencies', 'js/something.js' ) ->register(); ``` +You can also specify dependencies as a callable that returns an array of dependencies, like so: + +```php +Asset::add( 'script-with-dependencies', 'js/something.js' ) + ->set_dependencies( function() { + return [ 'jquery', 'jquery-ui', 'some-other-thing' ]; + } ) + ->register(); +``` + +Note that the callable will be called when the asset is enqueued, not later, when the asset is printed. + #### Auto-enqueuing on an action To specify when to enqueue the asset, you can indicate it like so: diff --git a/src/Assets/Asset.php b/src/Assets/Asset.php index 2797f81..3b06837 100644 --- a/src/Assets/Asset.php +++ b/src/Assets/Asset.php @@ -36,9 +36,9 @@ class Asset { /** * The asset dependencies. * - * @var array + * @var array|callable */ - protected array $dependencies = []; + protected $dependencies = []; /** * The asset file path. @@ -492,9 +492,9 @@ public function get_condition() { /** * Get the asset dependencies. * - * @return array + * @return array|callable */ - public function get_dependencies(): array { + public function get_dependencies() { return $this->dependencies; } @@ -1215,15 +1215,15 @@ public function set_condition( $condition ) { /** * @since 1.0.0 * - * @param string ...$dependencies + * @param string|callable ...$dependencies * * @return static */ - public function set_dependencies( string ...$dependencies ) { - $this->dependencies = []; - - foreach ( $dependencies as $dependency ) { - $this->add_dependency( $dependency ); + public function set_dependencies( ...$dependencies ) { + if ( $dependencies[0] && is_callable( $dependencies[0] ) ) { + $this->dependencies = $dependencies[0]; + } else { + $this->dependencies = $dependencies; } return $this; diff --git a/src/Assets/Assets.php b/src/Assets/Assets.php index 6fddbcf..8cf02c1 100755 --- a/src/Assets/Assets.php +++ b/src/Assets/Assets.php @@ -705,8 +705,8 @@ public function register_in_wp( $assets = null ) { // If the asset is a callable, we call the function, // passing it the asset and expecting back an array of dependencies. - if ( is_callable( $asset->get_dependencies() ) ) { - $dependencies = call_user_func( $asset->get_dependencies(), [ $asset ] ); + if ( is_callable( $dependencies ) ) { + $dependencies = $dependencies( $asset ); } wp_register_script( $asset->get_slug(), $asset->get_url(), $dependencies, $asset->get_version(), $asset->is_in_footer() ); diff --git a/tests/wpunit/AssetsTest.php b/tests/wpunit/AssetsTest.php index b94c677..3f92974 100644 --- a/tests/wpunit/AssetsTest.php +++ b/tests/wpunit/AssetsTest.php @@ -266,4 +266,70 @@ public function should_allow_localizing_data_using_a_closure(): void { $this->assertTrue( $resolved_one ); $this->assertTrue( $resolved_two ); } + + /** + * It should allow setting dependencies with an array + * + * @test + */ + public function should_allow_setting_dependencies_with_an_array(): void { + Asset::add( 'my-deps-base-script', 'base-script.js' ) + ->register(); + Asset::add( 'my-deps-vendor-script', 'vendor-script.js' ) + ->register(); + Asset::add( 'my-deps-dependent-script', 'dependent-script.js' ) + ->set_dependencies( 'my-deps-base-script', 'my-deps-vendor-script' ) + ->enqueue_on( 'test_action' ) + ->print() + ->register(); + + ob_start(); + do_action( 'test_action' ); + $this->assertEquals( <<< SCRIPT + + + + +SCRIPT, + ob_get_clean() + ); + } + + /** + * It should allow setting dependencies with a callable + * + * @test + */ + public function should_allow_setting_dependencies_with_a_callable(): void { + Asset::add( 'my-base-script-2', 'base-script-2.js' ) + ->register(); + Asset::add( 'my-vendor-script-2', 'vendor-script-2.js' ) + ->register(); + $resolved = false; + $asset = Asset::add( 'my-dependent-script-2', 'dependent-script-2.js' ) + ->set_dependencies( function () use ( &$resolved ) { + $resolved = true; + + return [ 'my-base-script-2', 'my-vendor-script-2' ]; + } ) + ->enqueue_on( 'test_action_2' ) + ->print(); + + $this->assertFalse( $resolved, 'The dependencies should not have been resolved yet.' ); + + $asset->register(); + + $this->assertTrue( $resolved ); + + ob_start(); + do_action( 'test_action_2' ); + $this->assertEquals( <<< SCRIPT + + + + +SCRIPT, + ob_get_clean() + ); + } }