Completed
Pull Request — development (#3050)
by John
23:37
created

Permissions   A

Complexity

Total Complexity 28

Size/Duplication

Total Lines 275
Duplicated Lines 3.64 %

Coupling/Cohesion

Components 2
Dependencies 1

Test Coverage

Coverage 55.28%

Importance

Changes 0
Metric Value
dl 10
loc 275
ccs 47
cts 85
cp 0.5528
rs 10
c 0
b 0
f 0
wmc 28
lcom 2
cbo 1

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
A getIllegalPermissions() 0 4 1
A getIllegalGuestPermissions() 0 4 1
A loadIllegalGuest() 0 9 1
A loadIllegal() 0 17 3
A deletePermissions() 0 16 2
D updateChild() 10 125 19

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

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 2.0 dev
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 context.
69
	 *
70
	 * Calls hook: integrate_load_illegal_permissions
71
	 */
72 4
	public function __construct()
73
	{
74 4
		$this->db = database();
75 4
		$this->loadIllegal();
76 4
		$this->loadIllegalGuest();
77 4
	}
78
79
	/**
80
	 * @return string[]
81
	 */
82 4
	public function getIllegalPermissions()
83
	{
84 4
		return $this->illegal_permissions;
85
	}
86
87
	/**
88
	 * @return array
89
	 */
90 4
	public function getIllegalGuestPermissions()
91
	{
92 4
		return $this->illegal_guest_permissions;
93
	}
94
95
	/**
96
	 * @return array
97
	 */
98 4
	public function loadIllegal()
99
	{
100 4
		global $context;
101
102 4
		$illegal_permissions = array();
103 4
		foreach ($this->reserved_permissions as $illegal_permission)
104
		{
105 4
			if (!allowedTo($illegal_permission))
106
			{
107 4
				$illegal_permissions[] = $illegal_permission;
108
			}
109
		}
110 4
		$context['illegal_permissions'] = $illegal_permissions;
111 4
		call_integration_hook('integrate_load_illegal_permissions');
112
113 4
		$this->illegal_permissions = $illegal_permissions;
114 4
	}
115
116
	/**
117
	 * Loads those permissions guests cannot have, into context.
118
	 *
119
	 * @return array
120
	 */
121 4
	public function loadIllegalGuest()
122
	{
123 4
		global $context;
124
125 4
		$context['non_guest_permissions'] = $this->illegal_guest_permissions;
126 4
		call_integration_hook('integrate_load_illegal_guest_permissions');
127
128 4
		return $this->illegal_guest_permissions;
129
	}
130
131
	/**
132
	 * Deletes permissions.
133
	 *
134
	 * @param string[] $permissions
135
	 * @param string[] $where
136
	 * @param mixed[]  $where_parameters = array() or values used in the where statement
137
	 */
138 2
	public function deletePermissions($permissions, $where = array(), $where_parameters = array())
139
	{
140 2
		if (count($this->illegal_permissions) > 0)
141
		{
142 2
			$where[] = 'permission NOT IN ({array_string:illegal_permissions})';
143 2
			$where_parameters['illegal_permissions'] = $this->illegal_permissions;
144
		}
145 2
		$where[] = 'permission IN ({array_string:permissions})';
146 2
		$where_parameters['permissions'] = $permissions;
147
148 2
		$this->db->query('', '
149
			DELETE FROM {db_prefix}permissions
150 2
			WHERE ' . implode(' AND ', $where),
151 2
			$where_parameters
152
		);
153 2
	}
154
155
	/**
156
	 * This function updates the permissions of any groups based on the given groups.
157
	 *
158
	 * @param mixed[]|int $parents (array or int) group or groups whose children are to be updated
159
	 * @param int|null    $profile = null an int or null for the customized profile, if any
160
	 */
161 2
	public function updateChild($parents, $profile = null)
162
	{
163
		// All the parent groups to sort out.
164 2
		if (!is_array($parents))
165
		{
166
			$parents = array($parents);
167
		}
168
169
		// Find all the children of this group.
170 2
		$request = $this->db->query('', '
171
			SELECT id_parent, id_group
172
			FROM {db_prefix}membergroups
173
			WHERE id_parent != {int:not_inherited}
174 2
				' . (empty($parents) ? '' : 'AND id_parent IN ({array_int:parent_list})'),
175
			array(
176 2
				'parent_list' => $parents,
177
				'not_inherited' => -2,
178
			)
179
		);
180 2
		$children = array();
181 2
		$parents = array();
182 2
		$child_groups = array();
183 2
		while ($row = $this->db->fetch_assoc($request))
184
		{
185
			$children[$row['id_parent']][] = $row['id_group'];
186
			$child_groups[] = $row['id_group'];
187
			$parents[] = $row['id_parent'];
188
		}
189 2
		$this->db->free_result($request);
190
191 2
		$parents = array_unique($parents);
192
193
		// Not a sausage, or a child?
194 2
		if (empty($children))
195
		{
196 2
			return false;
197
		}
198
199
		// Need functions that modify permissions...
200
		require_once(SUBSDIR . '/ManagePermissions.subs.php');
201
202
		// First off, are we doing general permissions?
203
		if ($profile < 1 || $profile === null)
204
		{
205
			// Fetch all the parent permissions.
206
			$request = $this->db->query('', '
207
				SELECT id_group, permission, add_deny
208
				FROM {db_prefix}permissions
209
				WHERE id_group IN ({array_int:parent_list})',
210
				array(
211
					'parent_list' => $parents,
212
				)
213
			);
214
			$permissions = array();
215 View Code Duplication
			while ($row = $this->db->fetch_assoc($request))
216
			{
217
				foreach ($children[$row['id_group']] as $child)
218
				{
219
					$permissions[] = array(
220
						'id_group' => (int) $child,
221
						'permission' => $row['permission'],
222
						'add_deny' => $row['add_deny'],
223
					);
224
				}
225
			}
226
			$this->db->free_result($request);
227
228
			$this->db->query('', '
229
				DELETE FROM {db_prefix}permissions
230
				WHERE id_group IN ({array_int:child_groups})',
231
				array(
232
					'child_groups' => $child_groups,
233
				)
234
			);
235
236
			// Finally insert.
237
			if (!empty($permissions))
238
			{
239
				replacePermission($permissions);
240
			}
241
		}
242
243
		// Then, what about board profiles?
244
		if ($profile != -1)
245
		{
246
			$profileQuery = $profile === null ? '' : ' AND id_profile = {int:current_profile}';
247
248
			// Again, get all the parent permissions.
249
			$request = $this->db->query('', '
250
				SELECT id_profile, id_group, permission, add_deny
251
				FROM {db_prefix}board_permissions
252
				WHERE id_group IN ({array_int:parent_groups})
253
					' . $profileQuery,
254
				array(
255
					'parent_groups' => $parents,
256
					'current_profile' => $profile !== null && $profile ? $profile : 1,
257
				)
258
			);
259
			$permissions = array();
260 View Code Duplication
			while ($row = $this->db->fetch_assoc($request))
261
			{
262
				foreach ($children[$row['id_group']] as $child)
263
				{
264
					$permissions[] = array($row['permission'], $child, $row['add_deny'], $row['id_profile']);
265
				}
266
			}
267
			$this->db->free_result($request);
268
269
			$this->db->query('', '
270
				DELETE FROM {db_prefix}board_permissions
271
				WHERE id_group IN ({array_int:child_groups})
272
					' . $profileQuery,
273
				array(
274
					'child_groups' => $child_groups,
275
					'current_profile' => $profile !== null && $profile ? $profile : 1,
276
				)
277
			);
278
279
			// Do the insert.
280
			if (!empty($permissions))
281
			{
282
				replaceBoardPermission($permissions);
283
			}
284
		}
285
	}
286
}
287