diff --git a/src/View/PermissionAclDelegatorFactory.php b/src/View/PermissionAclDelegatorFactory.php new file mode 100644 index 00000000..ace67bca --- /dev/null +++ b/src/View/PermissionAclDelegatorFactory.php @@ -0,0 +1,57 @@ +aclName = $aclName; + } + + public static function __set_state(array $state): self + { + return new self($state['aclName'] ?? AclInterface::class); + } + + public function __invoke( + ContainerInterface $container, + string $name, + callable $callback, + array $options = null + ) { + /** @var AbstractHelper|mixed $instance */ + $helper = $callback(); + + if (! $helper instanceof AbstractHelper) { + return $helper; + } + if (! $container->has($this->aclName)) { + return $helper; + } + + $acl = $container->get($this->aclName); + if (! $acl instanceof AclInterface) { + return $helper; + } + + $helper->setAcl($acl); + + return $helper; + } +} diff --git a/test/View/PermissionAclDelegatorFactoryTest.php b/test/View/PermissionAclDelegatorFactoryTest.php new file mode 100644 index 00000000..011f2b97 --- /dev/null +++ b/test/View/PermissionAclDelegatorFactoryTest.php @@ -0,0 +1,165 @@ +createMock(ContainerInterface::class); + $container->expects($this->once()) + ->method('has') + ->with(AclInterface::class) + ->willReturn(true); + $container->expects($this->once()) + ->method('get') + ->with(AclInterface::class) + ->willReturn($this->createMock(AclInterface::class)); + + $callback = static function () { + return new Navigation(); + }; + + /** @var Navigation $result */ + $result = (new PermissionAclDelegatorFactory())( + $container, + 'name', + $callback + ); + + $this->assertInstanceOf( + AclInterface::class, + $result->getAcl() + ); + } + + public function testAclWithCustomNameShouldBeSetForHelper(): void + { + $customName = 'alternate-acl'; + + $container = $this->createMock(ContainerInterface::class); + $container->expects($this->once()) + ->method('has') + ->with($customName) + ->willReturn(true); + $container->expects($this->once()) + ->method('get') + ->with($customName) + ->willReturn($this->createMock(AclInterface::class)); + + $callback = static function () { + return new Navigation(); + }; + + /** @var Navigation $result */ + $result = (new PermissionAclDelegatorFactory($customName))( + $container, + 'name', + $callback + ); + + $this->assertInstanceOf( + AclInterface::class, + $result->getAcl() + ); + } + + public function testNoneNavigationHelperPassedAsGiven(): void + { + $class = new stdClass(); + + $callback = static function () use ($class) { + return $class; + }; + + /** @var Navigation $result */ + $result = (new PermissionAclDelegatorFactory())( + $this->createMock(ContainerInterface::class), + 'name', + $callback + ); + + $this->assertSame($class, $result); + } + + public function testNoneExistingAclWillHelperPassedAsGiven(): void + { + $container = $this->createMock(ContainerInterface::class); + $container->expects($this->once()) + ->method('has') + ->with(AclInterface::class) + ->willReturn(false); + + $callback = static function () { + return new Navigation(); + }; + + /** @var Navigation $result */ + $result = (new PermissionAclDelegatorFactory())( + $container, + 'name', + $callback + ); + + $this->assertNull($result->getAcl()); + } + + public function testWrongAclWillHelperPassedAsGiven(): void + { + $container = $this->createMock(ContainerInterface::class); + $container->expects($this->once()) + ->method('has') + ->with(AclInterface::class) + ->willReturn(true); + $container->expects($this->once()) + ->method('get') + ->with(AclInterface::class) + ->willReturn(null); + + $callback = static function () { + return new Navigation(); + }; + + /** @var Navigation $result */ + $result = (new PermissionAclDelegatorFactory())( + $container, + 'name', + $callback + ); + + $this->assertNull($result->getAcl()); + } + + public function testMagicMethodSetStateShouldContainAclClassName(): void + { + $this->assertStringContainsString( + 'Laminas\\\Permissions\\\Acl\\\AclInterface', + var_export(new PermissionAclDelegatorFactory(), true) + ); + } + + public function testMagicMethodSetStateShouldContainCustomNameIfSet(): void + { + $customName = 'alternate-name'; + + $this->assertStringContainsString( + $customName, + var_export(new PermissionAclDelegatorFactory($customName), true) + ); + } +}