Completed
Push — master ( bae43a...71580e )
by Lars
02:55
created

Rule::isRuleMatched()   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 5
Bugs 1 Features 2
Metric Value
c 5
b 1
f 2
dl 0
loc 4
ccs 2
cts 2
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
      foreach ($roles as $role) {
236
237
        if (
238 25
            null === $role
239 25
            ||
240 25
            ($role && $role->name === $needRoleName)
241 25
        ) {
242 25
          $roleNameMatched = true;
243 25
        } else {
244 14
          $roleNameMatched = false;
245
        }
246
247 25
        foreach ($resources as $resource) {
248
249
          if (
250 25
              null === $resource
251 25
              ||
252 25
              ($resource && $resource->name === $needResourceName)
253 25
          ) {
254 25
            $resourceNameMatched = true;
255 25
          } else {
256 14
            $resourceNameMatched = false;
257
          }
258
259
          // Check if $role and $resource match to need role and resource.
260 25
          $ruleResult = null;
261
          if (
262
              $roleNameMatched === true
263 25
              &&
264
              $resourceNameMatched === true
265 25
          ) {
266 24
            $ruleResult = new RuleResult($this, $needRoleName, $needResourceName);
267 24
          }
268
269 25
          if ($ruleResult) {
270 24
            return $ruleResult;
271
          }
272 17
        }
273 17
      }
274 17
    }
275
276 17
    return null;
277
  }
278
279
  /**
280
   * Check if rule can be used.
281
   *
282
   * @param $needRuleName
283
   *
284
   * @return bool
285
   */
286 1
  protected function isRuleMatched($needRuleName)
287
  {
288 1
    return $this->name === $needRuleName;
289
  }
290
291
  /**
292
   * @return string
293
   */
294 28
  public function getName()
295
  {
296 28
    return $this->name;
297
  }
298
299
  /**
300
   * @param string $name
301
   */
302 47
  public function setName($name)
303
  {
304 47
    $this->name = $name;
305 47
  }
306
307
  /**
308
   * @return Role
309
   */
310 22
  public function getRole()
311
  {
312 22
    return $this->role;
313
  }
314
315
  /**
316
   * @param Role|null $role
317
   */
318 35
  public function setRole(Role $role = null)
319
  {
320 35
    $this->role = $role;
321 35
  }
322
323
  /**
324
   * @return \SimpleAcl\Resource
325
   */
326 22
  public function getResource()
327
  {
328 22
    return $this->resource;
329
  }
330
331
  /**
332
   * @param \SimpleAcl\Resource $resource
333
   */
334 35
  public function setResource(\SimpleAcl\Resource $resource = null)
335
  {
336 35
    $this->resource = $resource;
337 35
  }
338
339
  /**
340
   * Creates an id for rule.
341
   *
342
   * @return string
343
   */
344 47
  protected function generateId()
345
  {
346 47
    static $idCountRuleSimpleAcl = 1;
347
348 47
    return $idCountRuleSimpleAcl++;
349
  }
350
}
351