Passed
Push — master ( ee5e76...ea6ba5 )
by Morris
22:29 queued 12:17
created

Group::hideFromCollaboration()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 4
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 1
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * @copyright Copyright (c) 2016, ownCloud, Inc.
4
 *
5
 * @author Arthur Schiwon <[email protected]>
6
 * @author Bart Visscher <[email protected]>
7
 * @author Lukas Reschke <[email protected]>
8
 * @author Morris Jobke <[email protected]>
9
 * @author Robin Appelman <[email protected]>
10
 * @author Robin McCorkell <[email protected]>
11
 * @author Roeland Jago Douma <[email protected]>
12
 * @author Vincent Petry <[email protected]>
13
 * @author John Molakvoæ <[email protected]>
14
 *
15
 * @license AGPL-3.0
16
 *
17
 * This code is free software: you can redistribute it and/or modify
18
 * it under the terms of the GNU Affero General Public License, version 3,
19
 * as published by the Free Software Foundation.
20
 *
21
 * This program is distributed in the hope that it will be useful,
22
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24
 * GNU Affero General Public License for more details.
25
 *
26
 * You should have received a copy of the GNU Affero General Public License, version 3,
27
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
28
 *
29
 */
30
31
namespace OC\Group;
32
33
use OCP\Group\Backend\IHideFromCollaborationBackend;
34
use OCP\GroupInterface;
35
use OCP\IGroup;
36
use OCP\IUser;
37
use OCP\Group\Backend\ICountDisabledInGroup;
38
39
class Group implements IGroup {
40
	/** @var null|string  */
41
	protected $displayName;
42
43
	/**
44
	 * @var string $id
45
	 */
46
	private $gid;
47
48
	/**
49
	 * @var \OC\User\User[] $users
50
	 */
51
	private $users = array();
52
53
	/**
54
	 * @var bool $usersLoaded
55
	 */
56
	private $usersLoaded;
57
58
	/**
59
	 * @var \OC\Group\Backend[]|\OC\Group\Database[] $backend
60
	 */
61
	private $backends;
62
63
	/**
64
	 * @var \OC\Hooks\PublicEmitter $emitter
65
	 */
66
	private $emitter;
67
68
	/**
69
	 * @var \OC\User\Manager $userManager
70
	 */
71
	private $userManager;
72
73
	/**
74
	 * @param string $gid
75
	 * @param \OC\Group\Backend[] $backends
76
	 * @param \OC\User\Manager $userManager
77
	 * @param \OC\Hooks\PublicEmitter $emitter
78
	 * @param string $displayName
79
	 */
80
	public function __construct($gid, $backends, $userManager, $emitter = null, $displayName = null) {
81
		$this->gid = $gid;
82
		$this->backends = $backends;
83
		$this->userManager = $userManager;
84
		$this->emitter = $emitter;
85
		$this->displayName = $displayName;
86
	}
87
88
	public function getGID() {
89
		return $this->gid;
90
	}
91
92
	public function getDisplayName() {
93
		if (is_null($this->displayName)) {
94
			return $this->gid;
95
		}
96
		return $this->displayName;
97
	}
98
99
	/**
100
	 * get all users in the group
101
	 *
102
	 * @return \OC\User\User[]
103
	 */
104
	public function getUsers() {
105
		if ($this->usersLoaded) {
106
			return $this->users;
107
		}
108
109
		$userIds = array();
110
		foreach ($this->backends as $backend) {
111
			$diff = array_diff(
112
				$backend->usersInGroup($this->gid),
113
				$userIds
114
			);
115
			if ($diff) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $diff of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
116
				$userIds = array_merge($userIds, $diff);
117
			}
118
		}
119
120
		$this->users = $this->getVerifiedUsers($userIds);
121
		$this->usersLoaded = true;
122
		return $this->users;
123
	}
124
125
	/**
126
	 * check if a user is in the group
127
	 *
128
	 * @param IUser $user
129
	 * @return bool
130
	 */
131
	public function inGroup(IUser $user) {
132
		if (isset($this->users[$user->getUID()])) {
133
			return true;
134
		}
135
		foreach ($this->backends as $backend) {
136
			if ($backend->inGroup($user->getUID(), $this->gid)) {
137
				$this->users[$user->getUID()] = $user;
138
				return true;
139
			}
140
		}
141
		return false;
142
	}
143
144
	/**
145
	 * add a user to the group
146
	 *
147
	 * @param IUser $user
148
	 */
149
	public function addUser(IUser $user) {
150
		if ($this->inGroup($user)) {
151
			return;
152
		}
153
154
		if ($this->emitter) {
155
			$this->emitter->emit('\OC\Group', 'preAddUser', array($this, $user));
156
		}
157
		foreach ($this->backends as $backend) {
158
			if ($backend->implementsActions(\OC\Group\Backend::ADD_TO_GROUP)) {
159
				$backend->addToGroup($user->getUID(), $this->gid);
160
				if ($this->users) {
161
					$this->users[$user->getUID()] = $user;
162
				}
163
				if ($this->emitter) {
164
					$this->emitter->emit('\OC\Group', 'postAddUser', array($this, $user));
165
				}
166
				return;
167
			}
168
		}
169
	}
170
171
	/**
172
	 * remove a user from the group
173
	 *
174
	 * @param \OC\User\User $user
175
	 */
176
	public function removeUser($user) {
177
		$result = false;
178
		if ($this->emitter) {
179
			$this->emitter->emit('\OC\Group', 'preRemoveUser', array($this, $user));
180
		}
181
		foreach ($this->backends as $backend) {
182
			if ($backend->implementsActions(\OC\Group\Backend::REMOVE_FROM_GOUP) and $backend->inGroup($user->getUID(), $this->gid)) {
183
				$backend->removeFromGroup($user->getUID(), $this->gid);
184
				$result = true;
185
			}
186
		}
187
		if ($result) {
188
			if ($this->emitter) {
189
				$this->emitter->emit('\OC\Group', 'postRemoveUser', array($this, $user));
190
			}
191
			if ($this->users) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->users of type OC\User\User[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
192
				foreach ($this->users as $index => $groupUser) {
193
					if ($groupUser->getUID() === $user->getUID()) {
194
						unset($this->users[$index]);
195
						return;
196
					}
197
				}
198
			}
199
		}
200
	}
201
202
	/**
203
	 * search for users in the group by userid
204
	 *
205
	 * @param string $search
206
	 * @param int $limit
207
	 * @param int $offset
208
	 * @return \OC\User\User[]
209
	 */
210
	public function searchUsers($search, $limit = null, $offset = null) {
211
		$users = array();
212
		foreach ($this->backends as $backend) {
213
			$userIds = $backend->usersInGroup($this->gid, $search, $limit, $offset);
214
			$users += $this->getVerifiedUsers($userIds);
215
			if (!is_null($limit) and $limit <= 0) {
216
				return $users;
217
			}
218
		}
219
		return $users;
220
	}
221
222
	/**
223
	 * returns the number of users matching the search string
224
	 *
225
	 * @param string $search
226
	 * @return int|bool
227
	 */
228
	public function count($search = '') {
229
		$users = false;
230
		foreach ($this->backends as $backend) {
231
			if($backend->implementsActions(\OC\Group\Backend::COUNT_USERS)) {
232
				if($users === false) {
233
					//we could directly add to a bool variable, but this would
234
					//be ugly
235
					$users = 0;
236
				}
237
				$users += $backend->countUsersInGroup($this->gid, $search);
238
			}
239
		}
240
		return $users;
241
	}
242
243
	/**
244
	 * returns the number of disabled users
245
	 *
246
	 * @return int|bool
247
	 */
248
	public function countDisabled() {
249
		$users = false;
250
		foreach ($this->backends as $backend) {
251
			if($backend instanceOf ICountDisabledInGroup) {
252
				if($users === false) {
253
					//we could directly add to a bool variable, but this would
254
					//be ugly
255
					$users = 0;
256
				}
257
				$users += $backend->countDisabledInGroup($this->gid);
258
			}
259
		}
260
		return $users;
261
	}
262
263
	/**
264
	 * search for users in the group by displayname
265
	 *
266
	 * @param string $search
267
	 * @param int $limit
268
	 * @param int $offset
269
	 * @return \OC\User\User[]
270
	 */
271
	public function searchDisplayName($search, $limit = null, $offset = null) {
272
		$users = array();
273
		foreach ($this->backends as $backend) {
274
			$userIds = $backend->usersInGroup($this->gid, $search, $limit, $offset);
275
			$users = $this->getVerifiedUsers($userIds);
276
			if (!is_null($limit) and $limit <= 0) {
277
				return array_values($users);
278
			}
279
		}
280
		return array_values($users);
281
	}
282
283
	/**
284
	 * delete the group
285
	 *
286
	 * @return bool
287
	 */
288
	public function delete() {
289
		// Prevent users from deleting group admin
290
		if ($this->getGID() === 'admin') {
291
			return false;
292
		}
293
294
		$result = false;
295
		if ($this->emitter) {
296
			$this->emitter->emit('\OC\Group', 'preDelete', array($this));
297
		}
298
		foreach ($this->backends as $backend) {
299
			if ($backend->implementsActions(\OC\Group\Backend::DELETE_GROUP)) {
300
				$result = true;
301
				$backend->deleteGroup($this->gid);
302
			}
303
		}
304
		if ($result and $this->emitter) {
305
			$this->emitter->emit('\OC\Group', 'postDelete', array($this));
306
		}
307
		return $result;
308
	}
309
310
	/**
311
	 * returns all the Users from an array that really exists
312
	 * @param string[] $userIds an array containing user IDs
313
	 * @return \OC\User\User[] an Array with the userId as Key and \OC\User\User as value
314
	 */
315
	private function getVerifiedUsers($userIds) {
316
		if (!is_array($userIds)) {
0 ignored issues
show
introduced by
The condition is_array($userIds) is always true.
Loading history...
317
			return array();
318
		}
319
		$users = array();
320
		foreach ($userIds as $userId) {
321
			$user = $this->userManager->get($userId);
322
			if (!is_null($user)) {
323
				$users[$userId] = $user;
324
			}
325
		}
326
		return $users;
327
	}
328
329
	/**
330
	 * @return bool
331
	 * @since 14.0.0
332
	 */
333
	public function canRemoveUser() {
334
		foreach ($this->backends as $backend) {
335
			if ($backend->implementsActions(GroupInterface::REMOVE_FROM_GOUP)) {
336
				return true;
337
			}
338
		}
339
		return false;
340
	}
341
342
	/**
343
	 * @return bool
344
	 * @since 14.0.0
345
	 */
346
	public function canAddUser() {
347
		foreach ($this->backends as $backend) {
348
			if ($backend->implementsActions(GroupInterface::ADD_TO_GROUP)) {
349
				return true;
350
			}
351
		}
352
		return false;
353
	}
354
355
	/**
356
	 * @return bool
357
	 * @since 16.0.0
358
	 */
359
	public function hideFromCollaboration(): bool {
360
		return array_reduce($this->backends, function(bool $hide, GroupInterface $backend) {
361
			return $hide | ($backend instanceof IHideFromCollaborationBackend && $backend->hideGroup($this->gid));
0 ignored issues
show
Bug introduced by
Are you sure you want to use the bitwise | or did you mean ||?
Loading history...
362
		}, false);
363
	}
364
}
365