Completed
Push — master ( 6bfb13...0fc592 )
by Lars
02:22
created

Rule   B

Complexity

Total Complexity 43

Size/Duplication

Total Lines 341
Duplicated Lines 0 %

Coupling/Cohesion

Components 4
Dependencies 3

Test Coverage

Coverage 99.09%

Importance

Changes 22
Bugs 2 Features 10
Metric Value
wmc 43
c 22
b 2
f 10
lcom 4
cbo 3
dl 0
loc 341
ccs 109
cts 110
cp 0.9909
rs 8.3157

22 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A resetAggregate() 0 14 3
A getResourceAggregate() 0 4 1
A setResourceAggregate() 0 4 1
A getRoleAggregate() 0 4 1
A setRoleAggregate() 0 4 1
A getId() 0 4 1
A setId() 0 8 2
B getAction() 0 24 5
A setAction() 0 4 1
D isAllowed() 0 37 9
A isRuleMatched() 0 4 1
A getName() 0 4 1
A setName() 0 4 1
A getRole() 0 4 1
A setRole() 0 4 1
A getResource() 0 4 1
A setResource() 0 4 1
B match() 0 20 7
A getPriority() 0 4 1
A setPriority() 0 4 1
A generateId() 0 6 1

How to fix   Complexity   

Complex Class

Complex classes like Rule often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Rule, and based on these observations, apply Extract Interface, too.

1
<?php
2
namespace SimpleAcl;
3
4
use RecursiveIteratorIterator;
5
use SimpleAcl\Resource;
6
use SimpleAcl\Resource\ResourceAggregateInterface;
7
use SimpleAcl\Role;
8
use SimpleAcl\Role\RoleAggregateInterface;
9
10
/**
11
 * Used to connects Role and Resources together.
12
 *
13
 * @package SimpleAcl
14
 */
15
class Rule
16
{
17
  /**
18
   * Holds rule id.
19
   *
20
   * @var mixed
21
   */
22
  public $id;
23
24
  /**
25
   * Rule priority affect the order the rule is applied.
26
   *
27
   * @var int
28
   */
29
  protected $priority = 0;
30
31
  /**
32
   * Hold name of rule.
33
   *
34
   * @var string
35
   */
36
  protected $name;
37
38
  /**
39
   * Action used when determining is rule allow access to its Resource and Role.
40
   *
41
   * @var mixed
42
   */
43
  protected $action = false;
44
45
  /**
46
   * @var Role
47
   */
48
  protected $role;
49
50
  /**
51
   * @var Resource
52
   */
53
  protected $resource;
54
55
  /**
56
   * @var RoleAggregateInterface
57
   */
58
  protected $roleAggregate;
59
60
  /**
61
   * @var ResourceAggregateInterface
62
   */
63
  protected $resourceAggregate;
64
65
  /**
66
   * Create Rule with given name.
67
   *
68
   * @param $name
69
   */
70 49
  public function __construct($name)
71
  {
72 49
    $this->setId();
73 49
    $this->setName($name);
74 49
  }
75
76
  /**
77
   * Set aggregate objects.
78
   *
79
   * @param $roleAggregate
80
   * @param $resourceAggregate
81
   */
82 26
  public function resetAggregate($roleAggregate, $resourceAggregate)
83
  {
84 26
    if ($roleAggregate instanceof RoleAggregateInterface) {
85 4
      $this->setRoleAggregate($roleAggregate);
86 4
    } else {
87 23
      $this->roleAggregate = null;
88
    }
89
90 26
    if ($resourceAggregate instanceof ResourceAggregateInterface) {
91 3
      $this->setResourceAggregate($resourceAggregate);
92 3
    } else {
93 24
      $this->resourceAggregate = null;
94
    }
95 26
  }
96
97
  /**
98
   * @return ResourceAggregateInterface
99
   */
100 2
  public function getResourceAggregate()
101
  {
102 2
    return $this->resourceAggregate;
103
  }
104
105
  /**
106
   * @param ResourceAggregateInterface $resourceAggregate
107
   */
108 4
  public function setResourceAggregate(ResourceAggregateInterface $resourceAggregate)
109
  {
110 4
    $this->resourceAggregate = $resourceAggregate;
111 4
  }
112
113
  /**
114
   * @return RoleAggregateInterface
115
   */
116 2
  public function getRoleAggregate()
117
  {
118 2
    return $this->roleAggregate;
119
  }
120
121
  /**
122
   * @param RoleAggregateInterface $roleAggregate
123
   */
124 5
  public function setRoleAggregate(RoleAggregateInterface $roleAggregate)
125
  {
126 5
    $this->roleAggregate = $roleAggregate;
127 5
  }
128
129
  /**
130
   * @return mixed
131
   */
132 4
  public function getId()
133
  {
134 4
    return $this->id;
135
  }
136
137
  /**
138
   * @param mixed $id
139
   */
140 49
  public function setId($id = null)
141
  {
142 49
    if (null === $id) {
143 49
      $id = $this->generateId();
144 49
    }
145
146 49
    $this->id = $id;
147 49
  }
148
149
  /**
150
   * @param RuleResult|null $ruleResult
151
   *
152
   * @return bool|null
153
   */
154 32
  public function getAction(RuleResult $ruleResult = null)
155
  {
156 32
    $actionResult = $this->action;
157
158
    if (
159 32
        !is_callable($actionResult)
160 32
        ||
161 4
        null === $ruleResult
162 32
    ) {
163 29
      if (null !== $actionResult) {
164 29
        return (bool)$actionResult;
165
      } else {
166 3
        return null;
167
      }
168
    }
169
170 4
    $actionResult = call_user_func($this->action, $ruleResult);
171
172 4
    if (null !== $actionResult) {
173 4
      return (bool)$actionResult;
174
    } else {
175
      return null;
176
    }
177
  }
178
179
  /**
180
   * @param mixed $action
181
   */
182 40
  public function setAction($action)
183
  {
184 40
    $this->action = $action;
185 40
  }
186
187
  /**
188
   * Check owing Role & Resource and match its with $roleName & $resourceName;
189
   * if match was found depending on action allow or deny access to $resourceName for $roleName.
190
   *
191
   * @param        $needRuleName
192
   * @param string $needRoleName
193
   * @param string $needResourceName
194
   *
195
   * @return RuleResult|null null is returned if there is no matched Role & Resource in this rule.
196
   *                         RuleResult otherwise.
197
   */
198 27
  public function isAllowed($needRuleName, $needRoleName, $needResourceName)
199
  {
200 27
    if ($this->isRuleMatched($needRuleName)) {
201
202 27
      if (null !== $this->role) {
203 27
        $roles = iterator_to_array($this->role);
204 27
      } else {
205 5
        $roles = array(null);
206
      }
207
208 27
      if (null !== $this->resource) {
209 27
        $resources = iterator_to_array($this->getResource());
210 27
      } else {
211 5
        $resources = array(null);
212
      }
213
214 27
      $rolesDepth = 0;
215 27
      $resourceDepth = 0;
216
      
217 27
      foreach ($roles as $role) {
218 27
        $roleDepth = $role ? $rolesDepth++ : 0;
219
220 27
        foreach ($resources as $resource) {
221 27
          $resourceDepth = $resource ? $resourceDepth++ : 0;
222
223 27
          $depth = $roleDepth + $resourceDepth;
224 27
          $result = $this->match($role, $resource, $needRoleName, $needResourceName, -$depth);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $result is correct as $this->match($role, $res...dResourceName, -$depth) (which targets SimpleAcl\Rule::match()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
225
226 27
          if ($result) {
227 26
            return $result;
228
          }
229 18
        }
230 18
      }
231 18
    }
232
233 18
    return null;
234
  }
235
236
  /**
237
   * Check if rule can be used.
238
   *
239
   * @param $neeRuleName
240
   *
241
   * @return bool
242
   */
243 25
  protected function isRuleMatched($neeRuleName)
244
  {
245 25
    return $this->getName() === $neeRuleName;
246
  }
247
248
  /**
249
   * @return string
250
   */
251 29
  public function getName()
252
  {
253 29
    return $this->name;
254
  }
255
256
  /**
257
   * @param string $name
258
   */
259 49
  public function setName($name)
260
  {
261 49
    $this->name = $name;
262 49
  }
263
264
  /**
265
   * @return Role
266
   */
267 7
  public function getRole()
268
  {
269 7
    return $this->role;
270
  }
271
272
  /**
273
   * @param Role|null $role
274
   */
275 37
  public function setRole(Role $role = null)
276
  {
277 37
    $this->role = $role;
278 37
  }
279
280
  /**
281
   * @return \SimpleAcl\Resource
282
   */
283 30
  public function getResource()
284
  {
285 30
    return $this->resource;
286
  }
287
288
  /**
289
   * @param \SimpleAcl\Resource $resource
290
   */
291 37
  public function setResource(\SimpleAcl\Resource $resource = null)
292
  {
293 37
    $this->resource = $resource;
294 37
  }
295
296
  /**
297
   * Check if $role and $resource match to need role and resource.
298
   *
299
   * @param Role|null                $role
300
   * @param \SimpleAcl\Resource $resource
301
   * @param string                   $needRoleName
302
   * @param string                   $needResourceName
303
   * @param                          $priority
304
   *
305
   * @return RuleResult|null
306
   */
307 26
  protected function match(Role $role = null, \SimpleAcl\Resource $resource = null, $needRoleName, $needResourceName, $priority)
308
  {
309
    if (
310
        (
311 26
            null === $role
312 26
            ||
313 26
            ($role && $role->getName() === $needRoleName)
314 26
        )
315 26
        &&
316
        (
317 26
            null === $resource
318 26
            ||
319 26
            ($resource && $resource->getName() === $needResourceName)
320 26
        )
321 26
    ) {
322 25
      return new RuleResult($this, $priority, $needRoleName, $needResourceName);
323
    }
324
325 17
    return null;
326
  }
327
328
  /**
329
   * @return int
330
   */
331 28
  public function getPriority()
332
  {
333 28
    return $this->priority;
334
  }
335
336
  /**
337
   * @param int $priority
338
   */
339 1
  public function setPriority($priority)
340
  {
341 1
    $this->priority = $priority;
342 1
  }
343
344
  /**
345
   * Creates an id for rule.
346
   *
347
   * @return string
348
   */
349 49
  protected function generateId()
350
  {
351 49
    static $idCountRuleSimpleAcl = 1;
352
353 49
    return $idCountRuleSimpleAcl++;
354
  }
355
}
356