Rule::setResource()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 1
1
<?php
2
3
namespace SimpleAcl;
4
5
use SimpleAcl\Resource\ResourceAggregateInterface;
6
use SimpleAcl\Role\RoleAggregateInterface;
7
8
/**
9
 * Used to connects Role and Resources together.
10
 *
11
 * @package SimpleAcl
12
 */
13
class Rule
14
{
15
  /**
16
   * Holds rule id.
17
   *
18
   * @var null|int
19
   */
20
  public $id;
21
22
  /**
23
   * Hold name of rule.
24
   *
25
   * @var string
26
   */
27
  public $name;
28
29
  /**
30
   * Action used when determining is rule allow access to its Resource and Role.
31
   *
32
   * @var mixed
33
   */
34
  protected $action = false;
35
36
  /**
37
   * @var Role
38
   */
39
  protected $role;
40
41
  /**
42
   * @var \SimpleAcl\Resource
43
   */
44
  protected $resource;
45
46
  /**
47
   * @var RoleAggregateInterface
48
   */
49
  protected $roleAggregate;
50
51
  /**
52
   * @var ResourceAggregateInterface
53
   */
54
  protected $resourceAggregate;
55
56
  /**
57
   * Create Rule with given name.
58
   *
59
   * @param string $name
60 47
   */
61
  public function __construct($name)
62 47
  {
63 47
    $this->setId();
64 47
    $this->setName($name);
65
  }
66
67
  /**
68
   * Set aggregate objects.
69
   *
70
   * @param RoleAggregateInterface|mixed     $roleAggregate
71
   * @param ResourceAggregateInterface|mixed $resourceAggregate
72 17
   */
73
  public function resetAggregate($roleAggregate, $resourceAggregate)
74 17
  {
75 4
    if ($roleAggregate instanceof RoleAggregateInterface) {
76 4
      $this->setRoleAggregate($roleAggregate);
77 13
    } else {
78
      $this->roleAggregate = null;
79
    }
80 17
81 3
    if ($resourceAggregate instanceof ResourceAggregateInterface) {
82 3
      $this->setResourceAggregate($resourceAggregate);
83 14
    } else {
84
      $this->resourceAggregate = null;
85 17
    }
86
  }
87
88
  /**
89
   * @return ResourceAggregateInterface
90 2
   */
91
  public function getResourceAggregate(): ResourceAggregateInterface
92 2
  {
93
    return $this->resourceAggregate;
94
  }
95
96
  /**
97
   * @param ResourceAggregateInterface $resourceAggregate
98 4
   */
99
  public function setResourceAggregate(ResourceAggregateInterface $resourceAggregate)
100 4
  {
101 4
    $this->resourceAggregate = $resourceAggregate;
102
  }
103
104
  /**
105
   * @return RoleAggregateInterface
106 2
   */
107
  public function getRoleAggregate(): RoleAggregateInterface
108 2
  {
109
    return $this->roleAggregate;
110
  }
111
112
  /**
113
   * @param RoleAggregateInterface $roleAggregate
114 5
   */
115
  public function setRoleAggregate(RoleAggregateInterface $roleAggregate)
116 5
  {
117 5
    $this->roleAggregate = $roleAggregate;
118
  }
119
120
  /**
121
   * @return null|int
122 4
   */
123
  public function getId()
124 4
  {
125
    return $this->id;
126
  }
127
128
  /**
129
   * @param int|null $id
130 47
   */
131
  public function setId(int $id = null)
132 47
  {
133 47
    if (null === $id) {
134 47
      $id = $this->generateId();
135
    }
136 47
137 47
    $this->id = $id;
138
  }
139
140
  /**
141
   * @param RuleResult|null $ruleResult
142
   *
143
   * @return bool|null
144 30
   */
145
  public function getAction(RuleResult $ruleResult = null)
146 30
  {
147
    $actionResult = $this->action;
148
149 30
    if (
150 30
        null === $ruleResult
151 30
        ||
152 30
        !\is_callable($actionResult)
153 27
    ) {
154 27
      if (null !== $actionResult) {
155
        return (bool)$actionResult;
156 2
      }
157
158
      return null;
159
    }
160 4
161
    $actionResult = \call_user_func($this->action, $ruleResult);
162 4
163 4
    if (null !== $actionResult) {
164
      return (bool)$actionResult;
165
    }
166
167
    return null;
168
  }
169
170
  /**
171
   * @param mixed $action
172 38
   */
173
  public function setAction($action)
174 38
  {
175 38
    $this->action = $action;
176
  }
177
178
  /**
179
   * Check owing Role & Resource and match its with $roleName & $resourceName;
180
   * if match was found depending on action allow or deny access to $resourceName for $roleName.
181
   *
182
   * @param string|null $needRuleName
183
   * @param string|null $needRoleName
184
   * @param string|null $needResourceName
185
   *
186
   * @return RuleResult|null null is returned if there is no matched Role & Resource in this rule.
187
   *                         RuleResult otherwise.
188 25
   */
189
  public function isAllowed($needRuleName, $needRoleName, $needResourceName)
190 25
  {
191 25
    static $roleCache = [];
192
    static $resourceCache = [];
193
194
    if (
195
        (
196 25
            $needRuleName != 'RuleWide'
197 25
            &&
198 25
            $this->name === $needRuleName
199
        )
200 2
        ||
201 25
        $this->isRuleMatched($needRuleName)
202
    ) {
203 25
204
      if (null !== $this->role) {
205 25
206
        $roleNameTmp = $this->role->getName();
207 25
208 6
        if (!isset($roleCache[$roleNameTmp])) {
209
          $roles = iterator_to_array($this->role);
210 6
211 6
          $roleCache[$roleNameTmp] = $roles;
212 25
        } else {
213
          $roles = $roleCache[$roleNameTmp];
214
        }
215 25
216 5
      } else {
217
        $roles = [null];
218
      }
219 25
220
      if (null !== $this->resource) {
221 25
222
        $resourceNameTmp = $this->resource->getName();
223 25
224 7
        if (!isset($resourceCache[$resourceNameTmp])) {
225
          $resources = iterator_to_array($this->resource);
226 7
227 7
          $resourceCache[$resourceNameTmp] = $resources;
228 24
        } else {
229
          $resources = $resourceCache[$resourceNameTmp];
230
        }
231 25
232 5
      } else {
233
        $resources = [null];
234
      }
235 25
236
      foreach ($roles as $role) {
237
238 25
        if (
239 25
            null === $role
240 25
            ||
241 25
            ($role && $role->name === $needRoleName)
242 25
        ) {
243 25
          $roleNameMatched = true;
244 14
        } else {
245
          $roleNameMatched = false;
246
        }
247 25
248
        foreach ($resources as $resource) {
249
250 25
          if (
251 25
              null === $resource
252 25
              ||
253 25
              ($resource && $resource->name === $needResourceName)
254 25
          ) {
255 25
            $resourceNameMatched = true;
256 14
          } else {
257
            $resourceNameMatched = false;
258
          }
259
260 25
          // Check if $role and $resource match to need role and resource.
261
          $ruleResult = null;
262
          if (
263 25
              $roleNameMatched === true
264
              &&
265 25
              $resourceNameMatched === true
266 24
          ) {
267 24
            $ruleResult = new RuleResult($this, $needRoleName, $needResourceName);
268
          }
269 25
270 24
          if ($ruleResult) {
271
            return $ruleResult;
272 17
          }
273 17
        }
274 17
      }
275
    }
276 17
277
    return null;
278
  }
279
280
  /**
281
   * Check if rule can be used.
282
   *
283
   * @param string|null $needRuleName
284
   *
285
   * @return bool
286 1
   */
287
  protected function isRuleMatched($needRuleName): bool
288 1
  {
289
    return $this->name === $needRuleName;
290
  }
291
292
  /**
293
   * @return string
294 20
   */
295
  public function getName(): string
296 20
  {
297
    return $this->name;
298
  }
299
300
  /**
301
   * @param string $name
302 47
   */
303
  public function setName(string $name)
304 47
  {
305 47
    $this->name = $name;
306
  }
307
308
  /**
309
   * @return Role|null
310 22
   */
311
  public function getRole()
312 22
  {
313
    return $this->role;
314
  }
315
316
  /**
317
   * @param Role|null $role
318 35
   */
319
  public function setRole(Role $role = null)
320 35
  {
321 35
    $this->role = $role;
322
  }
323
324
  /**
325
   * @return \SimpleAcl\Resource|null
326 22
   */
327
  public function getResource()
328 22
  {
329
    return $this->resource;
330
  }
331
332
  /**
333
   * @param \SimpleAcl\Resource $resource
334 35
   */
335
  public function setResource(\SimpleAcl\Resource $resource = null)
336 35
  {
337 35
    $this->resource = $resource;
338
  }
339
340
  /**
341
   * Creates an id for rule.
342
   *
343
   * @return int
344 47
   */
345
  protected function generateId(): int
346 47
  {
347
    static $idCountRuleSimpleAcl = 1;
348 47
349
    return $idCountRuleSimpleAcl++;
350
  }
351
}
352