Completed
Push — master ( e4829c...bae43a )
by Lars
03:15
created

Rule::setAction()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

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