Completed
Push — master ( a8898a...5c0dbc )
by Nazar
04:15
created

Permission::set_permission()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
eloc 7
c 0
b 0
f 0
nc 2
nop 4
dl 0
loc 12
ccs 0
cts 12
cp 0
crap 6
rs 9.4285
1
<?php
2
/**
3
 * @package   CleverStyle Framework
4
 * @author    Nazar Mokrynskyi <[email protected]>
5
 * @copyright Copyright (c) 2011-2016, Nazar Mokrynskyi
6
 * @license   MIT License, see license.txt
7
 */
8
namespace cs\User;
9
use
10
	cs\Group as System_Group,
11
	cs\Permission as System_Permission,
12
	cs\Permission\Any,
13
	cs\User;
14
15
/**
16
 * Trait that contains all methods from <i>>cs\User</i> for working with user permissions
17
 *
18
 * @property int              $id
19
 * @property \cs\Cache\Prefix $cache
20
 *
21
 * @method false|int[]        get_groups(false|int $user)
22
 * @method bool               admin()
23
 */
24
trait Permission {
25
	use
26
		Any;
27
	/**
28
	 * Permissions cache for users
29
	 * @var array
30
	 */
31
	protected $permissions = [];
32
	/**
33
	 * Get permission state for specified user
34
	 *
35
	 * Rule: if not denied - allowed (users), if not allowed - denied (admins)
36
	 *
37
	 * @param string    $group Permission group
38
	 * @param string    $label Permission label
39
	 * @param false|int $user  If not specified - current user assumed
40
	 *
41
	 * @return bool If permission exists - returns its state for specified user, otherwise for admin permissions returns <b>false</b> and for others <b>true</b>
42
	 */
43
	function get_permission ($group, $label, $user = false) {
44
		$user = (int)$user ?: $this->id;
45
		if ($user == User::ROOT_ID) {
46
			return true;
47
		}
48
		$group_label_exploded = explode('/', "$group/$label");
49
		/**
50
		 * Default permissions values:
51
		 *
52
		 * - only administrators have access to `admin/*` URLs by default
53
		 * - only administrators have access to `api/{module}/admin/*` URLs by default
54
		 * - all other URLs are available to everyone by default
55
		 */
56
		$admin_section = $group_label_exploded[0] === 'admin' || ($group_label_exploded[0] === 'api' && @$group_label_exploded[2] === 'admin');
57
		if (!$user || ($admin_section && !$this->admin())) {
58
			return false;
59
		}
60
		$all_permissions = System_Permission::instance()->get_all();
61
		if (isset($all_permissions[$group][$label])) {
62
			$user_permissions = $this->get_permission_internal($user);
63
			$permission_id    = $all_permissions[$group][$label];
64
			return isset($user_permissions[$permission_id]) ? (bool)$user_permissions[$permission_id] : !$admin_section;
65
		}
66
		return true;
67
	}
68
	/**
69
	 * @param int $user
70
	 *
71
	 * @return array
72
	 */
73
	protected function get_permission_internal ($user) {
74
		if (isset($this->permissions[$user])) {
75
			return $this->permissions[$user];
76
		}
77
		$permissions = $this->cache->get(
78
			"permissions/computed/$user",
79
			function () use ($user) {
80
				$permissions = [];
81
				if ($user != User::GUEST_ID) {
82
					$Group = System_Group::instance();
83
					foreach ($this->get_groups($user) ?: [] as $group_id) {
84
						$permissions = ($Group->get_permissions($group_id) ?: []) + $permissions;
85
					}
86
				}
87
				$permissions = ($this->get_permissions($user) ?: []) + $permissions;
88
				return $permissions;
89
			}
90
		);
91
		if ($this->memory_cache || $user == User::GUEST_ID) {
92
			$this->permissions[$user] = $permissions;
93
		}
94
		return $permissions;
95
	}
96
	/**
97
	 * Set permission state for specified user
98
	 *
99
	 * @param string    $group Permission group
100
	 * @param string    $label Permission label
101
	 * @param int       $value 1 - allow, 0 - deny, -1 - undefined (remove permission, and use default value)
102
	 * @param false|int $user  If not specified - current user assumed
103
	 *
104
	 * @return bool
105
	 */
106
	function set_permission ($group, $label, $value, $user = false) {
107
		$permission = System_Permission::instance()->get(null, $group, $label);
108
		if ($permission) {
109
			return $this->set_permissions(
110
				[
111
					$permission[0]['id'] => $value
112
				],
113
				$user
114
			);
115
		}
116
		return false;
117
	}
118
	/**
119
	 * Delete permission state for specified user
120
	 *
121
	 * @param string    $group Permission group
122
	 * @param string    $label Permission label
123
	 * @param false|int $user  If not specified - current user assumed
124
	 *
125
	 * @return bool
126
	 */
127
	function del_permission ($group, $label, $user = false) {
128
		return $this->set_permission($group, $label, -1, $user);
129
	}
130
	/**
131
	 * Get array of all permissions states for specified user
132
	 *
133
	 * @param false|int $user If not specified - current user assumed
134
	 *
135
	 * @return int[]|false
136
	 */
137
	function get_permissions ($user = false) {
138
		$user = (int)$user ?: $this->id;
139
		if ($user == User::ROOT_ID || !$user) {
140
			return false;
141
		}
142
		return $this->get_any_permissions($user, 'user');
143
	}
144
	/**
145
	 * Set user's permissions according to the given array
146
	 *
147
	 * @param array     $data
148
	 * @param false|int $user If not specified - current user assumed
149
	 *
150
	 * @return bool
151
	 */
152
	function set_permissions ($data, $user = false) {
153
		$user = (int)$user ?: $this->id;
154
		if ($user == User::ROOT_ID || !$user) {
155
			return false;
156
		}
157
		$result = $this->set_any_permissions($data, $user, 'user');
158
		$this->cache->del("permissions/computed/$user");
159
		unset($this->permissions[$user]);
160
		return $result;
161
	}
162
	/**
163
	 * Delete all user's permissions
164
	 *
165
	 * @param false|int $user If not specified - current user assumed
166
	 *
167
	 * @return bool
168
	 */
169
	function del_permissions_all ($user = false) {
170
		$user = (int)$user ?: $this->id;
171
		if ($user == User::ROOT_ID || !$user) {
172
			return false;
173
		}
174
		$result = $this->del_any_permissions_all($user, 'user');
175
		$this->cache->del("permissions/computed/$user");
176
		unset($this->permissions[$user]);
177
		return $result;
178
	}
179
}
180