1: <?php
2:
3: namespace Charcoal\User\Acl;
4:
5: // Dependency from 'charcoal-core'
6: use Charcoal\Model\AbstractModel;
7:
8: /**
9: * ACL Roles define hierarchical allowed and denied permissions.
10: *
11: * They can be attached to user accounts for fine-grained permission control.
12: */
13: class Role extends AbstractModel
14: {
15: const SEPARATOR = ',';
16:
17: /**
18: * @var string $ident
19: */
20: public $ident;
21:
22: /**
23: * The parent ACL role.
24: *
25: * This role will inherit all of its parent's permissions.
26: *
27: * @var string $parent
28: */
29: public $parent;
30:
31: /**
32: * List of explicitely allowed permissions.
33: *
34: * @var string[]|null $allowed
35: */
36: public $allowed;
37:
38: /**
39: * List of explicitely denied permissions.
40: *
41: * @var string[]|null $denied
42: */
43: public $denied;
44:
45: /**
46: * @var boolean
47: */
48: private $superuser = false;
49:
50: /**
51: * @var integer
52: */
53: private $position;
54:
55: /**
56: * ACL Role can be used as a string (ident).
57: *
58: * @return string
59: */
60: public function __toString()
61: {
62: return (string)$this->ident;
63: }
64:
65: /**
66: * @param string $parent Role's parent.
67: * @return AclRole Chainable
68: */
69: public function setParent($parent)
70: {
71: $this->parent = (string)$parent;
72: return $this;
73: }
74:
75: /**
76: * @return string
77: */
78: public function parent()
79: {
80: return $this->parent;
81: }
82:
83: /**
84: * @param string[]|string|null $allowed The allowed permissions for this role.
85: * @throws InvalidArgumentException If the passed arguments is not an array, null, or a comma-separated string.
86: * @return AclRole Chainable
87: */
88: public function setAllowed($allowed)
89: {
90: if ($allowed === null) {
91: $this->allowed = null;
92: return $this;
93: }
94:
95: if (is_string($allowed)) {
96: $allowed = explode(self::SEPARATOR, $allowed);
97: $allowed = array_map('trim', $allowed);
98: }
99: if (!is_array($allowed)) {
100: throw new InvalidArgumentException(
101: 'Invalid allowed value. Must be an array, null, or a comma-separated string.'
102: );
103: }
104: $this->allowed = $allowed;
105: return $this;
106: }
107:
108: /**
109: * @return string[]|null
110: */
111: public function allowed()
112: {
113: return $this->allowed;
114: }
115:
116: /**
117: * @param string[]|string|null $denied The denied permissions for this role.
118: * @throws InvalidArgumentException If the passed arguments is not an array, null, or a comma-separated string.
119: * @return AclRole Chainable
120: */
121: public function setDenied($denied)
122: {
123: if ($denied === null) {
124: $this->denied = null;
125: return $this;
126: }
127:
128: if (is_string($denied)) {
129: $denied = explode(self::SEPARATOR, $denied);
130: $denied = array_walk('trim', $denied);
131: }
132: if (!is_array($denied)) {
133: throw new InvalidArgumentException(
134: 'Invalid denied value. Must be an array, null, or a comma-separated string.'
135: );
136: }
137: $this->denied = $denied;
138: return $this;
139: }
140:
141: /**
142: * @return string[]|null
143: */
144: public function denied()
145: {
146: return $this->denied();
147: }
148:
149: /**
150: * @param boolean $isSuper The superuser flag.
151: * @return AclRole Chainable
152: */
153: public function setSuperuser($isSuper)
154: {
155: $this->superuser = !!$isSuper;
156: return $this;
157: }
158:
159: /**
160: * @return boolean
161: */
162: public function superuser()
163: {
164: return $this->superuser;
165: }
166:
167: /**
168: * @param integer $position The role's ordering position.
169: * @return AclRole Chainable
170: */
171: public function setPosition($position)
172: {
173: $this->position = (int)$position;
174: return $this;
175: }
176:
177: /**
178: * @return integer
179: */
180: public function position()
181: {
182: return $this->position;
183: }
184: }
185: