diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b7a6483..f54dc58 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,7 +7,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - php_version: [8.0, 8.1, 8.2] + php_version: [8.1, 8.2, 8.3] composer_flags: ['', '--prefer-lowest'] steps: diff --git a/composer.json b/composer.json index 3cd9a50..0cf2c1c 100644 --- a/composer.json +++ b/composer.json @@ -3,14 +3,14 @@ "description": "A powerful MVC framework for the modern WordPress developer. Write better, more expressive and easier to maintain code", "license": "MIT", "require": { - "php": ">=8.0", + "php": ">=8.1", "php-di/php-di": "^6.4.0", "rareloop/router": "^6.0.2", "psr/container": "^1.1.2", "psr/http-message": "^1.1", "psr/http-server-middleware": "^1.0.2", "blast/facades": "^1.0", - "timber/timber": "^1.24.0", + "timber/timber": "^2.3.0", "monolog/monolog": "^2.9.1", "http-interop/response-sender": "^1.0", "symfony/debug": "^4.4.44", @@ -50,4 +50,4 @@ "composer/installers": true } } -} +} \ No newline at end of file diff --git a/src/Post.php b/src/Post.php index 5a7257d..38f4258 100644 --- a/src/Post.php +++ b/src/Post.php @@ -8,7 +8,6 @@ use Timber\Post as TimberPost; use Timber\Timber; -#[\AllowDynamicProperties] class Post extends TimberPost { use Macroable { @@ -16,14 +15,14 @@ class Post extends TimberPost Macroable::__callStatic as __macroableCallStatic; } - public function __construct($id = false, $preventTimberInit = false) + public function __construct(mixed $wpPost = null, $preventTimberInit = false) { /** * There are occasions where we do not want the bootstrap the data. At the moment this is * designed to make Query Scopes possible */ if (!$preventTimberInit) { - parent::__construct($id); + parent::__construct($wpPost); } } @@ -102,9 +101,16 @@ public static function register() throw new PostTypeRegistrationException('Config not set'); } + add_filter('timber/post/classmap', [static::class, 'filterTimberPostClassMap']); + register_post_type($postType, $config); } + public static function filterTimberPostClassMap(array $classMap): array + { + return [...$classMap, static::getPostType() => static::class]; + } + /** * Get all posts of this type * diff --git a/src/Providers/TimberServiceProvider.php b/src/Providers/TimberServiceProvider.php index 29fd12c..837aa63 100644 --- a/src/Providers/TimberServiceProvider.php +++ b/src/Providers/TimberServiceProvider.php @@ -9,10 +9,7 @@ class TimberServiceProvider extends ServiceProvider { public function register() { - $timber = new Timber(); - - $this->app->bind('timber', $timber); - $this->app->bind(Timber::class, $timber); + Timber::init(); } public function boot(Config $config) diff --git a/src/QueryBuilder.php b/src/QueryBuilder.php index 0d5c6df..2bd82ee 100644 --- a/src/QueryBuilder.php +++ b/src/QueryBuilder.php @@ -159,16 +159,9 @@ public function whereMetaRelationshipIs(string $relation): QueryBuilderContract return $this; } - public function as($postClass): QueryBuilderContract - { - $this->postClass = $postClass; - - return $this; - } - public function get(): Collection { - $posts = Timber::get_posts($this->getParameters(), $this->postClass); + $posts = Timber::get_posts($this->getParameters()); if (!is_array($posts)) { $posts = []; diff --git a/src/ScopedQueryBuilder.php b/src/ScopedQueryBuilder.php index 100b69e..f6089c1 100644 --- a/src/ScopedQueryBuilder.php +++ b/src/ScopedQueryBuilder.php @@ -23,7 +23,6 @@ public function __construct($postClass) $this->queryBuilder = Helpers::app(QueryBuilderContract::class); $this->queryBuilder - ->as($postClass) ->wherePostType(call_user_func([$this->postClass, 'getPostType'])); } @@ -65,7 +64,7 @@ public function __call($name, $arguments) * @param string $name The method name * @return boolean */ - protected function hasQueryBuilderMethod(string $name) : bool + protected function hasQueryBuilderMethod(string $name): bool { if (method_exists($this->queryBuilder, $name)) { return true; @@ -82,9 +81,4 @@ public function wherePostType($postType) { throw new CannotRedeclarePostTypeOnQueryException; } - - public function as($postClass) - { - throw new CannotRedeclarePostClassOnQueryException; - } } diff --git a/tests/Unit/PostTest.php b/tests/Unit/PostTest.php index 2dbe99f..4aabdc7 100644 --- a/tests/Unit/PostTest.php +++ b/tests/Unit/PostTest.php @@ -8,6 +8,7 @@ use PHPUnit\Framework\TestCase; use Rareloop\Lumberjack\Post; use Rareloop\Lumberjack\Test\Unit\BrainMonkeyPHPUnitIntegration; +use Timber\Post as TimberPost; use Timber\Timber; /** @@ -28,6 +29,8 @@ public function register_function_calls_register_post_type_when_post_type_and_co ->with(RegisterablePostType::getPostType(), RegisterablePostType::getPrivateConfig()); RegisterablePostType::register(); + + $this->assertNotFalse(has_filter('timber/post/classmap', [RegisterablePostType::class, 'filterTimberPostClassMap'])); } /** @test */ @@ -45,6 +48,18 @@ public function register_function_throws_exception_if_config_is_not_provided() UnregisterablePostTypeWithoutConfig::register(); } + /** @test */ + public function can_filter_timber_post_classmaps() + { + $output = Post::filterTimberPostClassMap(['another' => TimberPost::class]); + + $this->assertEqualsCanonicalizing(['another' => TimberPost::class, 'post' => Post::class], $output); + + $output = RegisterablePostType::filterTimberPostClassMap($output); + + $this->assertEqualsCanonicalizing(['another' => TimberPost::class, 'post' => Post::class, 'registerable_post_type' => RegisterablePostType::class], $output); + } + /** * @test */ @@ -202,7 +217,7 @@ public function can_extend_post_behaviour_with_macros() return 'abc123'; }); - $post = new Post(false, true); + $post = new Post(null, true); $this->assertSame('abc123', $post->testFunctionAddedByMacro()); $this->assertSame('abc123', Post::testFunctionAddedByMacro()); @@ -213,12 +228,11 @@ public function can_extend_post_behaviour_with_macros() */ public function macros_set_correct_this_context_on_instances() { - Post::macro('testFunctionAddedByMacro', function () { - return $this->dummyData(); + PostWithPrivateData::macro('testFunctionAddedByMacro', function () { + return $this->dummyData; }); - $post = new Post(false, true); - $post->dummyData = 'abc123'; + $post = new PostWithPrivateData(null, true); $this->assertSame('abc123', $post->testFunctionAddedByMacro()); } @@ -230,7 +244,7 @@ public function can_extend_post_behaviour_with_mixin() { Post::mixin(new PostMixin); - $post = new Post(false, true); + $post = new Post(null, true); $this->assertSame('abc123', $post->testFunctionAddedByMixin()); } @@ -246,6 +260,11 @@ function testFunctionAddedByMixin() } } +class PostWithPrivateData extends Post +{ + private string $dummyData = 'abc123'; +} + class RegisterablePostType extends Post { public static function getPostType(): string diff --git a/tests/Unit/Providers/TimberServiceProviderTest.php b/tests/Unit/Providers/TimberServiceProviderTest.php index 960576a..734470d 100644 --- a/tests/Unit/Providers/TimberServiceProviderTest.php +++ b/tests/Unit/Providers/TimberServiceProviderTest.php @@ -2,18 +2,25 @@ namespace Rareloop\Lumberjack\Test\Providers; +use Mockery; use Brain\Monkey; +use Timber\Timber; use Brain\Monkey\Functions; use PHPUnit\Framework\TestCase; +use Rareloop\Lumberjack\Config; use Rareloop\Lumberjack\Application; +use Rareloop\Lumberjack\Http\Lumberjack; use Rareloop\Lumberjack\Bootstrappers\BootProviders; use Rareloop\Lumberjack\Bootstrappers\RegisterProviders; -use Rareloop\Lumberjack\Config; -use Rareloop\Lumberjack\Http\Lumberjack; use Rareloop\Lumberjack\Providers\TimberServiceProvider; use Rareloop\Lumberjack\Test\Unit\BrainMonkeyPHPUnitIntegration; -use Timber\Timber; +/** + * @runTestsInSeparateProcesses + * @preserveGlobalState disabled + * The above is required as we're using alias mocks which persist between tests + * https://laracasts.com/discuss/channels/testing/mocking-a-class-persists-over-tests/replies/103075 + */ class TimberServiceProviderTest extends TestCase { use BrainMonkeyPHPUnitIntegration; @@ -23,20 +30,20 @@ public function timber_plugin_is_initialiased() { Functions\expect('is_admin')->once()->andReturn(false); - $app = new Application(__DIR__.'/../'); + $timber = Mockery::mock('alias:' . Timber::class); + $timber->shouldReceive('init')->once(); + + $app = new Application(__DIR__ . '/../'); $lumberjack = new Lumberjack($app); $app->register(new TimberServiceProvider($app)); $lumberjack->bootstrap(); - - $this->assertTrue($app->has('timber')); - $this->assertSame($app->get('timber'), $app->get(Timber::class)); } /** @test */ public function dirname_variable_is_set_from_config() { - $app = new Application(__DIR__.'/../'); + $app = new Application(__DIR__ . '/../'); $config = new Config; $config->set('timber.paths', [ @@ -55,11 +62,10 @@ public function dirname_variable_is_set_from_config() $app->register(new TimberServiceProvider($app)); - $this->assertTrue($app->has('timber')); $this->assertSame([ 'path/one', 'path/two', 'path/three', - ], $app->get('timber')::$dirname); + ], Timber::$dirname); } } diff --git a/tests/Unit/QueryBuilderTest.php b/tests/Unit/QueryBuilderTest.php index 75d3ce5..7645e56 100644 --- a/tests/Unit/QueryBuilderTest.php +++ b/tests/Unit/QueryBuilderTest.php @@ -334,7 +334,6 @@ public function get_retrieves_list_of_posts() 'post_status' => 'publish', 'offset' => 10, ]), - Post::class, ]) ->once() ->andReturn($posts); @@ -361,7 +360,6 @@ public function get_retrieves_empty_collection_when_timber_returns_false() 'post_status' => 'publish', 'offset' => 10, ]), - Post::class, ]) ->once() ->andReturn(false); @@ -388,7 +386,6 @@ public function get_retrieves_empty_collection_when_timber_returns_null() 'post_status' => 'publish', 'offset' => 10, ]), - Post::class, ]) ->once() ->andReturn(null); @@ -400,29 +397,6 @@ public function get_retrieves_empty_collection_when_timber_returns_null() $this->assertSame(0, $returnedPosts->count()); } - /** - * @test - * @runInSeparateProcess - * @preserveGlobalState disabled - */ - public function can_specify_the_class_type_to_return() - { - $timber = Mockery::mock('alias:' . Timber::class); - $timber - ->shouldReceive('get_posts') - ->withArgs([ - Mockery::subset([ - 'post_status' => 'publish', - 'offset' => 10, - ]), - PostWithCustomPostType::class, - ]) - ->once(); - - $builder = new QueryBuilder(); - $builder->whereStatus('publish')->offset(10)->as(PostWithCustomPostType::class)->get(); - } - /** * @test * @runInSeparateProcess diff --git a/tests/Unit/ScopedQueryBuilderTest.php b/tests/Unit/ScopedQueryBuilderTest.php index 655231f..33ad032 100644 --- a/tests/Unit/ScopedQueryBuilderTest.php +++ b/tests/Unit/ScopedQueryBuilderTest.php @@ -48,21 +48,12 @@ public function cannot_overwrite_post_type() $builder->wherePostType('test_post_type'); } - /** @test */ - public function cannot_overwrite_post_class() - { - $this->expectException(\Rareloop\Lumberjack\Exceptions\CannotRedeclarePostClassOnQueryException::class); - - $builder = new ScopedQueryBuilder(PostWithQueryScope::class); - $builder->as(Post::class); - } - /** * @test * @runInSeparateProcess * @preserveGlobalState disabled */ - public function get_retrieves_list_of_posts_of_correct_type() + public function get_retrieves_list_of_posts() { $posts = [new PostWithQueryScope(1, true), new PostWithQueryScope(2, true)]; @@ -73,7 +64,6 @@ public function get_retrieves_list_of_posts_of_correct_type() 'post_status' => 'publish', 'offset' => 10, ]), - PostWithQueryScope::class, ])->once()->andReturn($posts); $builder = new ScopedQueryBuilder(PostWithQueryScope::class);