Passed
Pull Request — patch_1-1-7 (#3404)
by
unknown
15:47
created

Permissions   A

Complexity

Total Complexity 28

Size/Duplication

Total Lines 270
Duplicated Lines 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
eloc 116
dl 0
loc 270
rs 10
c 1
b 1
f 0
wmc 28

7 Methods

Rating   Name   Duplication   Size   Complexity  
A deletePermissions() 0 14 2
D updateChild() 0 122 19
A loadIllegal() 0 14 3
A loadIllegalGuest() 0 6 1
A getIllegalPermissions() 0 3 1
A getIllegalGuestPermissions() 0 3 1
A __construct() 0 5 1
1
<?php
2
3
/**
4
 * Functions to support the permissions controller
5
 *
6
 * @name      ElkArte Forum
7
 * @copyright ElkArte Forum contributors
8
 * @license   BSD http://opensource.org/licenses/BSD-3-Clause
9
 *
10
 * @version 1.1.6
11
 */
12
class Permissions
13
{
14
	private $db;
15
16
	/**
17
	 * @var array
18
	 */
19
	protected $reserved_permissions = array(
20
		'admin_forum',
21
		'manage_membergroups',
22
		'manage_permissions',
23
	);
24
25
	/**
26
	 * @var string[]
27
	 */
28
	private $illegal_permissions = array();
29
30
	/**
31
	 * @var array
32
	 */
33
	protected $illegal_guest_permissions = array(
34
		'delete_replies',
35
		'karma_edit',
36
		'poll_add_own',
37
		'pm_read',
38
		'pm_send',
39
		'profile_identity',
40
		'profile_extra',
41
		'profile_title',
42
		'profile_remove',
43
		'profile_set_avatar',
44
		'profile_view_own',
45
		'mark_any_notify',
46
		'mark_notify',
47
		'admin_forum',
48
		'manage_boards',
49
		'manage_attachments',
50
		'manage_smileys',
51
		'edit_news',
52
		'access_mod_center',
53
		'moderate_forum',
54
		'issue_warning',
55
		'manage_membergroups',
56
		'manage_permissions',
57
		'manage_bans',
58
		'move_own',
59
		'modify_replies',
60
		'send_mail',
61
		'approve_posts',
62
		'postby_email',
63
		'approve_emails',
64
		'like_posts',
65
	);
66
67
	/**
68
	 * Load a few illegal permissions into the class and context.
69
	 *
70
	 * - Calls hook: integrate_load_illegal_permissions
71
	 * - Calls hook: integrate_load_illegal_guest_permissions
72
	 */
73
	public function __construct()
74
	{
75
		$this->db = database();
76
		$this->loadIllegal();
77
		$this->loadIllegalGuest();
78
	}
79
80
	/**
81
	 * Return the list of illegal permissions
82
	 *
83
	 * @return string[]
84
	 */
85
	public function getIllegalPermissions()
86
	{
87
		return $this->illegal_permissions;
88
	}
89
90
	/**
91
	 * Return the list of illegal guest permissions
92
	 *
93
	 * @return string[]
94
	 */
95
	public function getIllegalGuestPermissions()
96
	{
97
		return $this->illegal_guest_permissions;
98
	}
99
100
	/**
101
	 * Loads those reserved permissions into context.
102
	 */
103
	public function loadIllegal()
104
	{
105
		global $context;
106
107
		foreach ($this->reserved_permissions as $illegal_permission)
108
		{
109
			if (!allowedTo($illegal_permission))
110
			{
111
				$this->illegal_permissions[] = $illegal_permission;
112
			}
113
		}
114
115
		$context['illegal_permissions'] = &$this->illegal_permissions;
116
		call_integration_hook('integrate_load_illegal_permissions', array(&$this->illegal_permissions));
117
	}
118
119
	/**
120
	 * Loads those permissions guests cannot have, into context.
121
	 */
122
	public function loadIllegalGuest()
123
	{
124
		global $context;
125
126
		$context['non_guest_permissions'] = &$this->illegal_guest_permissions;
127
		call_integration_hook('integrate_load_illegal_guest_permissions', array(&$this->illegal_guest_permissions));
128
	}
129
130
	/**
131
	 * Deletes permissions.
132
	 *
133
	 * @param string[] $permissions
134
	 * @param string[] $where
135
	 * @param mixed[]  $where_parameters = array() or values used in the where statement
136
	 */
137
	public function deletePermissions($permissions, $where = array(), $where_parameters = array())
138
	{
139
		if (count($this->illegal_permissions) > 0)
140
		{
141
			$where[] = 'permission NOT IN ({array_string:illegal_permissions})';
142
			$where_parameters['illegal_permissions'] = $this->illegal_permissions;
143
		}
144
		$where[] = 'permission IN ({array_string:permissions})';
145
		$where_parameters['permissions'] = $permissions;
146
147
		$this->db->query('', '
148
			DELETE FROM {db_prefix}permissions
149
			WHERE ' . implode(' AND ', $where),
150
			$where_parameters
151
		);
152
	}
153
154
	/**
155
	 * This function updates the permissions of any groups based on the given groups.
156
	 *
157
	 * @param mixed[]|int $parents (array or int) group or groups whose children are to be updated
158
	 * @param int|null    $profile = null an int or null for the customized profile, if any
159
	 */
160
	public function updateChild($parents, $profile = null)
161
	{
162
		// All the parent groups to sort out.
163
		if (!is_array($parents))
164
		{
165
			$parents = array($parents);
166
		}
167
168
		// Find all the children of this group.
169
		$request = $this->db->query('', '
170
			SELECT id_parent, id_group
171
			FROM {db_prefix}membergroups
172
			WHERE id_parent != {int:not_inherited}
173
				' . (empty($parents) ? '' : 'AND id_parent IN ({array_int:parent_list})'),
174
			array(
175
				'parent_list' => $parents,
176
				'not_inherited' => -2,
177
			)
178
		);
179
		$children = array();
180
		$parents = array();
181
		$child_groups = array();
182
		while ($row = $this->db->fetch_assoc($request))
183
		{
184
			$children[$row['id_parent']][] = $row['id_group'];
185
			$child_groups[] = $row['id_group'];
186
			$parents[] = $row['id_parent'];
187
		}
188
		$this->db->free_result($request);
189
190
		$parents = array_unique($parents);
191
192
		// Not a sausage, or a child?
193
		if (empty($children))
194
		{
195
			return false;
196
		}
197
198
		// Need functions that modify permissions...
199
		require_once(SUBSDIR . '/ManagePermissions.subs.php');
200
201
		// First off, are we doing general permissions?
202
		if ($profile < 1 || $profile === null)
203
		{
204
			// Fetch all the parent permissions.
205
			$request = $this->db->query('', '
206
				SELECT id_group, permission, add_deny
207
				FROM {db_prefix}permissions
208
				WHERE id_group IN ({array_int:parent_list})',
209
				array(
210
					'parent_list' => $parents,
211
				)
212
			);
213
			$permissions = array();
214
			while ($row = $this->db->fetch_assoc($request))
215
			{
216
				foreach ($children[$row['id_group']] as $child)
217
				{
218
					$permissions[] = array(
219
						'id_group' => (int) $child,
220
						'permission' => $row['permission'],
221
						'add_deny' => $row['add_deny'],
222
					);
223
				}
224
			}
225
			$this->db->free_result($request);
226
227
			$this->db->query('', '
228
				DELETE FROM {db_prefix}permissions
229
				WHERE id_group IN ({array_int:child_groups})',
230
				array(
231
					'child_groups' => $child_groups,
232
				)
233
			);
234
235
			// Finally insert.
236
			if (!empty($permissions))
237
			{
238
				replacePermission($permissions);
239
			}
240
		}
241
242
		// Then, what about board profiles?
243
		if ($profile != -1)
244
		{
245
			$profileQuery = $profile === null ? '' : ' AND id_profile = {int:current_profile}';
246
247
			// Again, get all the parent permissions.
248
			$request = $this->db->query('', '
249
				SELECT id_profile, id_group, permission, add_deny
250
				FROM {db_prefix}board_permissions
251
				WHERE id_group IN ({array_int:parent_groups})
252
					' . $profileQuery,
253
				array(
254
					'parent_groups' => $parents,
255
					'current_profile' => $profile !== null && $profile ? $profile : 1,
256
				)
257
			);
258
			$permissions = array();
259
			while ($row = $this->db->fetch_assoc($request))
260
			{
261
				foreach ($children[$row['id_group']] as $child)
262
				{
263
					$permissions[] = array($row['permission'], $child, $row['add_deny'], $row['id_profile']);
264
				}
265
			}
266
			$this->db->free_result($request);
267
268
			$this->db->query('', '
269
				DELETE FROM {db_prefix}board_permissions
270
				WHERE id_group IN ({array_int:child_groups})
271
					' . $profileQuery,
272
				array(
273
					'child_groups' => $child_groups,
274
					'current_profile' => $profile !== null && $profile ? $profile : 1,
275
				)
276
			);
277
278
			// Do the insert.
279
			if (!empty($permissions))
280
			{
281
				replaceBoardPermission($permissions);
282
			}
283
		}
284
	}
285
}
286