Completed
Push — master ( e4afe1...cae729 )
by Nazar
04:01
created

Permission::get_permission()   C

Complexity

Conditions 8
Paths 10

Size

Total Lines 24
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 8

Importance

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