RoleCollection::areSuperiorThan()   B
last analyzed

Complexity

Conditions 5
Paths 3

Size

Total Lines 17
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 8
nc 3
nop 2
dl 0
loc 17
rs 8.8571
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * @file RoleCollection.php
5
 * @brief This file contains the RoleCollection class.
6
 * @details
7
 * @author Filippo F. Fadda
8
 */
9
10
11
namespace Daikengo\Collection;
12
13
14
use Meta\MetaCollection;
15
16
use Daikengo\User\IUser;
17
use Daikengo\Role\IRole;
18
19
20
/**
21
 * @brief This class is used to represent a collection of roles.
22
 * @nosubgrouping
23
 */
24
final class RoleCollection extends MetaCollection {
25
26
  /**
27
   * @var IUser $user
28
   */
29
  protected $user;
30
31
32
  /**
33
   * @brief Creates a new collection of roles.
34
   * @param string $name Collection's name.
35
   * @param array $meta Array of metadata.
36
   */
37
  public function __construct($name, array &$meta) {
38
    parent::__construct($name, $meta);
39
  }
40
41
42
  /**
43
   * @brief Grants the specified role to the current member.
44
   * @details The algorithm discards any role when a more important one has been granted to the member. That means you
45
   * can't add the Moderator role to an Admin, etc. You can also grant multiple roles to a member, to assign special
46
   * permissions.
47
   * @param IRole $role A role object.
48
   */
49
  public function grant(IRole $role) {
50
    // Checks if the same role has been already assigned to the member.
51
    if ($this->exists($role))
52
      return;
53
54
    $roles = $this->meta[$this->name];
55
56
    foreach ($roles as $name => $class) {
57
58
      if (is_subclass_of($class, get_class($role))) {
59
        // If a subclass of `$role` exists for the current collection then the function returns, because a more
60
        // important role has been already assigned to the member.
61
        return;
62
      }
63
      elseif (is_subclass_of($role, $class, FALSE)) {
64
        // If `$role` is an instance of a subclass of any role previously assigned to the member that means the new role
65
        // is more important and the one already assigned must be removed.
66
        unset($this->meta[$this->name][$name]);
67
      }
68
69
    }
70
71
    // Uses as key the role's name and as value its class.
72
    $this->meta[$this->name][$role->getName()] = get_class($role);
73
  }
74
75
76
  /**
77
   * @brief Revokes the specified role for the current member.
78
   * @param IRole $role A role object.
79
   */
80
  public function revoke(IRole $role) {
81
    if ($this->exists($role))
82
      unset($this->meta[$this->name][$role->getName()]);
83
  }
84
85
86
  /**
87
   * @brief Returns `true` if the role is already present, `false` otherwise.
88
   * @param IRole $role A role object.
89
   * @return bool
90
   */
91
  public function exists(IRole $role) {
92
    return isset($this->meta[$this->name][$role->getName()]);
93
  }
94
95
96
  /**
97
   * @brief Returns `true` if at least one of the role associated to the current user is an instance of subclass (or an
98
   * instance of the same class) of the specified role object, `false` otherwise.
99
   * @param IRole $role A role object.
100
   * @param bool $orEqual (optional) When `false` doesn't check if the role is an instance of the same class.
101
   * @return bool
102
   */
103
  public function areSuperiorThan(IRole $role, $orEqual = TRUE) {
104
    $result = FALSE;
105
106
    $roles = $this->meta[$this->name];
107
108
    $roleClass = get_class($role);
109
110
    foreach ($roles as $name => $class) {
111
112
      if (is_subclass_of($class, $roleClass) or ($orEqual && ($class === $roleClass))) {
113
        $result = TRUE;
114
        break;
115
      }
116
117
    }
118
119
    return $result;
120
  }
121
122
}