Completed
Push — master ( c6794e...0594fd )
by Nazar
03:59
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 6
CRAP Score 2

Importance

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