Register   A
last analyzed

Complexity

Total Complexity 19

Size/Duplication

Total Lines 166
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 49
c 1
b 0
f 0
dl 0
loc 166
rs 10
wmc 19

10 Methods

Rating   Name   Duplication   Size   Complexity  
A removeRole() 0 13 4
A __construct() 0 9 1
A initializeRule() 0 9 1
A rules() 0 3 1
A removeAllRole() 0 5 1
A addRole() 0 13 2
A removeAllResource() 0 9 3
A setRule() 0 17 1
A isAllowed() 0 10 1
A removeResource() 0 11 4
1
<?php
2
3
namespace Tleckie\Acl\Acl;
4
5
use Tleckie\Acl\Operation\AddChain;
6
use Tleckie\Acl\Operation\OperationChainInterface;
7
use Tleckie\Acl\Operation\RemoveChain;
8
use Tleckie\Acl\Permissions\PermissionResolverInterface;
9
use Tleckie\Acl\Permissions\ResolverInterface;
10
use Tleckie\Acl\Resource\ResourceInterface;
11
use Tleckie\Acl\Role\RoleInterface;
12
use Tleckie\Acl\Role\RoleRecorderInterface;
13
14
/**
15
 * Class Register
16
 *
17
 * @package Tleckie\Acl\Acl
18
 * @author  Teodoro Leckie Westberg <[email protected]>
19
 */
20
class Register implements RegisterInterface
21
{
22
    /** @var array */
23
    private array $rules;
24
25
    /** @var RoleRecorderInterface */
26
    private RoleRecorderInterface $roleRecorder;
27
28
    /** @var OperationChainInterface */
29
    private OperationChainInterface $operations;
30
31
    /** @var PermissionResolverInterface */
32
    private PermissionResolverInterface $resolver;
33
34
    /**
35
     * Register constructor.
36
     *
37
     * @param RoleRecorderInterface $roleRecorder
38
     */
39
    public function __construct(RoleRecorderInterface $roleRecorder)
40
    {
41
        $this->roleRecorder = $roleRecorder;
42
43
        $this->operations = (new RemoveChain(new AddChain()));
44
45
        $this->resolver = new ResolverInterface();
46
47
        $this->rules = [];
48
    }
49
50
    /**
51
     * @inheritdoc
52
     */
53
    public function removeRole(RoleInterface|string $role): RegisterInterface
54
    {
55
        foreach ($this->rules['roles'] ?? [] as $roleName => $item) {
56
            foreach ($item['parents'] ?? [] as $parentName => $parent) {
57
                if ($parentName === (string)$role) {
58
                    unset($this->rules['roles'][$roleName]['parents'][$parentName]);
59
                }
60
            }
61
        }
62
63
        unset($this->rules['roles'][(string)$role]);
64
65
        return $this;
66
    }
67
68
    /**
69
     * @inheritdoc
70
     */
71
    public function removeResource(ResourceInterface|string $resource): RegisterInterface
72
    {
73
        foreach ($this->rules['roles'] ?? [] as $roleName => $item) {
74
            foreach ([(string)PermissionTypeEnum::DENY(), (string)PermissionTypeEnum::ALLOW()] as $type) {
75
                if (isset($this->rules['roles'][$roleName][$type][(string)$resource])) {
76
                    unset($this->rules['roles'][$roleName][$type][(string)$resource]);
77
                }
78
            }
79
        }
80
81
        return $this;
82
    }
83
84
    /**
85
     * @inheritdoc
86
     */
87
    public function addRole(
88
        RoleInterface|string $role,
89
        array $parents = []
90
    ): RegisterInterface {
91
        $role = $this->roleRecorder->getRole($role);
92
93
        $this->initializeRule('roles', $role);
94
95
        foreach ($parents as $parent) {
96
            $this->rules['roles'][(string)$role]['parents'][(string)$parent] = [];
97
        }
98
99
        return $this;
100
    }
101
102
    /**
103
     * @param string                          $type
104
     * @param RoleInterface|ResourceInterface $item
105
     * @return RegisterInterface
106
     */
107
    private function initializeRule(
108
        string $type,
109
        RoleInterface|ResourceInterface $item
110
    ): RegisterInterface {
111
        $this->rules[$type][(string)$item]['parents'] = [];
112
        $this->rules[$type][(string)$item][(string)PermissionTypeEnum::DENY()] = [];
113
        $this->rules[$type][(string)$item][(string)PermissionTypeEnum::ALLOW()] = [];
114
115
        return $this;
116
    }
117
118
    /**
119
     * @inheritdoc
120
     */
121
    public function removeAllRole(): RegisterInterface
122
    {
123
        $this->rules = [];
124
125
        return $this;
126
    }
127
128
    /**
129
     * @inheritdoc
130
     */
131
    public function removeAllResource(): RegisterInterface
132
    {
133
        foreach ($this->rules['roles'] as $roleName => &$item) {
134
            foreach ([(string)PermissionTypeEnum::DENY(), (string)PermissionTypeEnum::ALLOW()] as $type) {
135
                $item[$type] = [];
136
            }
137
        }
138
139
        return $this;
140
    }
141
142
    /**
143
     * @inheritdoc
144
     */
145
    public function rules(): array
146
    {
147
        return $this->rules;
148
    }
149
150
    /**
151
     * @inheritdoc
152
     */
153
    public function isAllowed(
154
        string $role,
155
        string $resource,
156
        string $privilege = null
157
    ): bool {
158
        return $this->resolver->isAllowed(
159
            $this->rules,
160
            $role,
161
            $resource,
162
            $privilege
163
        );
164
    }
165
166
    /**
167
     * @inheritdoc
168
     */
169
    public function setRule(
170
        OperationEnum $operation,
171
        PermissionTypeEnum $type,
172
        array $roles = [],
173
        array $resources = [],
174
        array $privileges = []
175
    ): RegisterInterface {
176
        $this->operations->handle(
177
            $operation,
178
            $type,
179
            $roles,
180
            $resources,
181
            $privileges,
182
            $this->rules
183
        );
184
185
        return $this;
186
    }
187
}
188