diff --git a/src/Illuminate/Container/Attributes/Auth.php b/src/Illuminate/Container/Attributes/Auth.php new file mode 100644 index 000000000000..4cf0c1a4cc68 --- /dev/null +++ b/src/Illuminate/Container/Attributes/Auth.php @@ -0,0 +1,30 @@ +make('auth')->guard($attribute->guard); + } +} diff --git a/src/Illuminate/Container/Attributes/Authenticated.php b/src/Illuminate/Container/Attributes/Authenticated.php new file mode 100644 index 000000000000..67cdd53cc3cf --- /dev/null +++ b/src/Illuminate/Container/Attributes/Authenticated.php @@ -0,0 +1,30 @@ +make('auth')->guard($attribute->guard)->user(); + } +} diff --git a/src/Illuminate/Container/Attributes/Cache.php b/src/Illuminate/Container/Attributes/Cache.php new file mode 100644 index 000000000000..2b7b1f78e038 --- /dev/null +++ b/src/Illuminate/Container/Attributes/Cache.php @@ -0,0 +1,30 @@ +make('cache')->store($attribute->store); + } +} diff --git a/src/Illuminate/Container/Attributes/CurrentUser.php b/src/Illuminate/Container/Attributes/CurrentUser.php new file mode 100644 index 000000000000..7c13b4efee58 --- /dev/null +++ b/src/Illuminate/Container/Attributes/CurrentUser.php @@ -0,0 +1,11 @@ +make('db')->connection($attribute->connection); + } +} diff --git a/src/Illuminate/Container/Attributes/Log.php b/src/Illuminate/Container/Attributes/Log.php new file mode 100644 index 000000000000..07673e703704 --- /dev/null +++ b/src/Illuminate/Container/Attributes/Log.php @@ -0,0 +1,30 @@ +make('log')->channel($attribute->channel); + } +} diff --git a/src/Illuminate/Container/Attributes/Storage.php b/src/Illuminate/Container/Attributes/Storage.php new file mode 100644 index 000000000000..b9a16d19817a --- /dev/null +++ b/src/Illuminate/Container/Attributes/Storage.php @@ -0,0 +1,30 @@ +make('filesystem')->disk($attribute->disk); + } +} diff --git a/tests/Container/ContextualAttributeBindingTest.php b/tests/Container/ContextualAttributeBindingTest.php index a474cbbba531..b7360da204aa 100644 --- a/tests/Container/ContextualAttributeBindingTest.php +++ b/tests/Container/ContextualAttributeBindingTest.php @@ -3,13 +3,38 @@ namespace Illuminate\Tests\Container; use Attribute; +use Illuminate\Auth\AuthManager; +use Illuminate\Cache\CacheManager; +use Illuminate\Cache\Repository as CacheRepository; use Illuminate\Config\Repository; +use Illuminate\Container\Attributes\Auth; +use Illuminate\Container\Attributes\Authenticated; +use Illuminate\Container\Attributes\Cache; +use Illuminate\Container\Attributes\Config; +use Illuminate\Container\Attributes\CurrentUser; +use Illuminate\Container\Attributes\Database; +use Illuminate\Container\Attributes\Log; +use Illuminate\Container\Attributes\Storage; use Illuminate\Container\Container; +use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract; +use Illuminate\Contracts\Auth\Guard as GuardContract; use Illuminate\Contracts\Container\ContextualAttribute; +use Illuminate\Contracts\Filesystem\Filesystem; +use Illuminate\Database\Connection; +use Illuminate\Database\DatabaseManager; +use Illuminate\Filesystem\FilesystemManager; +use Illuminate\Log\LogManager; +use Mockery as m; use PHPUnit\Framework\TestCase; +use Psr\Log\LoggerInterface; class ContextualAttributeBindingTest extends TestCase { + protected function tearDown(): void + { + m::close(); + } + public function testDependencyCanBeResolvedFromAttributeBinding() { $container = new Container; @@ -75,6 +100,114 @@ public function testDependencyWithAfterCallbackAttributeCanBeResolved() $this->assertEquals('Developer', $class->person->role); } + + public function testAuthedAttribute() + { + $container = new Container; + $container->singleton('auth', function () { + $manager = m::mock(AuthManager::class); + $manager->shouldReceive('guard')->with('foo')->andReturnUsing(function () { + $guard = m::mock(GuardContract::class); + $guard->shouldReceive('user')->andReturn(m:mock(AuthenticatableContract::class)); + + return $guard; + }); + $manager->shouldReceive('guard')->with('bar')->andReturnUsing(function () { + $guard = m::mock(GuardContract::class); + $guard->shouldReceive('user')->andReturn(m:mock(AuthenticatableContract::class)); + + return $guard; + }); + + return $manager; + }); + + $container->make(AuthedTest::class); + } + + public function testCacheAttribute() + { + $container = new Container; + $container->singleton('cache', function () { + $manager = m::mock(CacheManager::class); + $manager->shouldReceive('store')->with('foo')->andReturn(m::mock(CacheRepository::class)); + $manager->shouldReceive('store')->with('bar')->andReturn(m::mock(CacheRepository::class)); + + return $manager; + }); + + $container->make(CacheTest::class); + } + + public function testConfigAttribute() + { + $container = new Container; + $container->singleton('config', function () { + $repository = m::mock(Repository::class); + $repository->shouldReceive('get')->with('foo', null)->andReturn('foo'); + $repository->shouldReceive('get')->with('bar', null)->andReturn('bar'); + + return $repository; + }); + + $container->make(ConfigTest::class); + } + + public function testDatabaseAttribute() + { + $container = new Container; + $container->singleton('db', function () { + $manager = m::mock(DatabaseManager::class); + $manager->shouldReceive('connection')->with('foo')->andReturn(m::mock(Connection::class)); + $manager->shouldReceive('connection')->with('bar')->andReturn(m::mock(Connection::class)); + + return $manager; + }); + + $container->make(DatabaseTest::class); + } + + public function testAuthAttribute() + { + $container = new Container;# + $container->singleton('auth', function () { + $manager = m::mock(AuthManager::class); + $manager->shouldReceive('guard')->with('foo')->andReturn(m::mock(GuardContract::class)); + $manager->shouldReceive('guard')->with('bar')->andReturn(m::mock(GuardContract::class)); + + return $manager; + }); + + $container->make(GuardTest::class); + } + + public function testLogAttribute() + { + $container = new Container; + $container->singleton('log', function () { + $manager = m::mock(LogManager::class); + $manager->shouldReceive('channel')->with('foo')->andReturn(m::mock(LoggerInterface::class)); + $manager->shouldReceive('channel')->with('bar')->andReturn(m::mock(LoggerInterface::class)); + + return $manager; + }); + + $container->make(LogTest::class); + } + + public function testStorageAttribute() + { + $container = new Container; + $container->singleton('filesystem', function () { + $manager = m::mock(FilesystemManager::class); + $manager->shouldReceive('disk')->with('foo')->andReturn(m::mock(Filesystem::class)); + $manager->shouldReceive('disk')->with('bar')->andReturn(m::mock(Filesystem::class)); + + return $manager; + }); + + $container->make(StorageTest::class); + } } #[Attribute(Attribute::TARGET_PARAMETER)] @@ -179,3 +312,52 @@ public function __construct( ) { } } + +final class AuthedTest +{ + public function __construct(#[Authenticated('foo')] AuthenticatableContract $foo, #[CurrentUser('bar')] AuthenticatableContract $bar) + { + } +} + +final class CacheTest +{ + public function __construct(#[Cache('foo')] CacheRepository $foo, #[Cache('bar')] CacheRepository $bar) + { + } +} + +final class ConfigTest +{ + public function __construct(#[Config('foo')] string $foo, #[Config('bar')] string $bar) + { + } +} + +final class DatabaseTest +{ + public function __construct(#[Database('foo')] Connection $foo, #[Database('bar')] Connection $bar) + { + } +} + +final class GuardTest +{ + public function __construct(#[Auth('foo')] GuardContract $foo, #[Auth('bar')] GuardContract $bar) + { + } +} + +final class LogTest +{ + public function __construct(#[Log('foo')] LoggerInterface $foo, #[Log('bar')] LoggerInterface $bar) + { + } +} + +final class StorageTest +{ + public function __construct(#[Storage('foo')] Filesystem $foo, #[Storage('bar')] Filesystem $bar) + { + } +}