Completed
Push — master ( e1a535...c926f4 )
by Lars
02:38
created

Rule::getResourceAggregate()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

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