Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
96.30% covered (success)
96.30%
26 / 27
66.67% covered (warning)
66.67%
2 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
AccessControlListGenerator
96.30% covered (success)
96.30%
26 / 27
66.67% covered (warning)
66.67%
2 / 3
7
0.00% covered (danger)
0.00%
0 / 1
 boot
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
1
 postRun
100.00% covered (success)
100.00%
17 / 17
100.00% covered (success)
100.00%
1 / 1
4
 hasPermissionRequirement
80.00% covered (warning)
80.00%
4 / 5
0.00% covered (danger)
0.00%
0 / 1
2.03
1<?php
2namespace Apie\StorageMetadataBuilder\CodeGenerators;
3
4use Apie\Core\Permissions\RequiresPermissionsInterface;
5use Apie\StorageMetadata\Attributes\AclLinkAttribute;
6use Apie\StorageMetadata\Attributes\ManyToOneAttribute;
7use Apie\StorageMetadataBuilder\Interfaces\BootGeneratedCodeInterface;
8use Apie\StorageMetadataBuilder\Interfaces\PostRunGeneratedCodeContextInterface;
9use Apie\StorageMetadataBuilder\Interfaces\RootObjectInterface;
10use Apie\StorageMetadataBuilder\Mediators\GeneratedCode;
11use Apie\StorageMetadataBuilder\Mediators\GeneratedCodeContext;
12use Nette\PhpGenerator\ClassType;
13use ReflectionClass;
14
15final class AccessControlListGenerator implements BootGeneratedCodeInterface, PostRunGeneratedCodeContextInterface
16{
17    public function boot(GeneratedCode $generatedCode): void
18    {
19        $class = new ClassType('apie_access_control_list');
20        $constructor = $class->addMethod('__construct');
21        $constructor->addPromotedParameter('permission')
22            ->setType('string');
23        $generatedCode->generatedCodeHashmap['apie_access_control_list'] = $class;
24    }
25
26    public function postRun(GeneratedCodeContext $generatedCodeContext): void
27    {
28        $accessControlTable = $generatedCodeContext->generatedCode->generatedCodeHashmap['apie_access_control_list'] ?? null;
29        assert($accessControlTable instanceof ClassType);
30        $added = false;
31        foreach ($generatedCodeContext->generatedCode->generatedCodeHashmap->getObjectsWithInterface(RootObjectInterface::class) as $code) {
32            if ($this->hasPermissionRequirement($code)) {
33                $added = true;
34                $code->addMethod('getAccessControlTable')
35                    ->setReturnType('ReflectionClass')
36                    ->setBody('return new \\ReflectionClass(' . $accessControlTable->getName() . '::class);');
37                $code->addProperty('_acl')
38                    ->setType('array')
39                    ->addAttribute(AclLinkAttribute::class, [$accessControlTable->getName()]);
40                $accessControlTable->addProperty('ref_' . $code->getName(), null)
41                    ->setType('?' . $code->getName())
42                    ->addAttribute(ManyToOneAttribute::class, ['_acl']);
43            }
44        }
45        if (!$added) {
46            unset($generatedCodeContext->generatedCode->generatedCodeHashmap['apie_access_control_list']);
47        }
48    }
49
50    private function hasPermissionRequirement(ClassType $code): bool
51    {
52        // comment is original php class
53        $doc = $code->getComment();
54        if (!class_exists($doc)) {
55            return false;
56        }
57        $refl = new ReflectionClass($doc);
58        return in_array(RequiresPermissionsInterface::class, $refl->getInterfaceNames());
59    }
60}