Passed
Push — master ( 13f577...04b25a )
by Filippo
03:34
created

TMember::issetRoles()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * @file TMember.php
5
 * @brief This file contains the TMember trait.
6
 * @details
7
 * @author Filippo F. Fadda
8
 */
9
10
11
namespace Daikengo\User;
12
13
14
use Daikengo\User\IUser;
15
use Daikengo\Permission\IPermission;
16
use Daikengo\Collection\RoleCollection;
17
18
use Meta\Extension;
19
20
21
/**
22
 * @brief This trait implements the `IUser` interface for the `Member` class.
23
 * @details Use this trait when you can't extend the `Member` class since you already have a class for it in your
24
 * project.
25
 *
26
 * @cond HIDDEN_SYMBOLS
27
 *
28
 * @property RoleCollection $roles
29
 *
30
 * @endcond
31
 */
32
trait TMember {
33
  use Extension\TProperty;
34
35
  private $roles; // Associative array [roleName => roleClass].
36
37
38
  /**
39
   * @copydoc IUser::has()
40
   */
41
  public function has(IPermission $permission) {
42
    $result = FALSE;
43
44
    $permissionReflection = new \ReflectionObject($permission);
45
46
    foreach ($this->roles as $roleName => $roleClass) {
47
48
      do {
49
        $role = new $roleClass;
50
51
        // Sets the execution role for the current user.
52
        $permission->setRole($role);
53
54
        // Creates a reflection class for the roleName.
55
        $roleReflection = new \ReflectionObject($role);
56
57
        // Determines the method's name related to the roleName.
58
        $methodName = 'checkFor' . $roleReflection->getShortName();
59
60
        if ($permissionReflection->hasMethod($methodName)) { // If a method exists for the roleName...
61
          // Gets the method.
62
          $method = $permissionReflection->getMethod($methodName);
63
64
          // Invokes the method.
65
          $result = $method->invoke($permission);
66
67
          // Exits from the do while and foreach as well.
68
          break 2;
69
        }
70
        else {
71
          // Go back to the previous role class in the hierarchy. For example, from AdminRole to ModeratorRole.
72
          $parentRoleReflection = $roleReflection->getParentClass();
73
74
          // Proceed only if the parent role is not an abstract class.
75
          if (is_object($parentRoleReflection) && !$parentRoleReflection->isAbstract())
76
            $roleClass = $parentRoleReflection->name;
77
          else
78
            break; // No more roles in the hierarchy.
79
        }
80
      } while (TRUE);
81
82
    }
83
84
    return $result;
85
  }
86
87
88
  /**
89
   * @brief This implementation returns always `false`.
90
   * @retval bool
91
   */
92
  public function isGuest() {
93
    return FALSE;
94
  }
95
96
97
  /**
98
   * @brief This implementation returns always `true`.
99
   * @retval bool
100
   */
101
  public function isMember() {
102
    return TRUE;
103
  }
104
105
106
  /**
107
   * @copydoc IUser::getRoles()
108
   */
109
  public function getRoles() {
110
    return $this->roles;
111
  }
112
113
}