PrivilegeUtil::getQueryToUsersByGroup()   A
last analyzed

Complexity

Conditions 4
Paths 3

Size

Total Lines 27
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 4

Importance

Changes 0
Metric Value
eloc 20
c 0
b 0
f 0
dl 0
loc 27
rs 9.6
ccs 6
cts 6
cp 1
cc 4
nc 3
nop 3
crap 4
1
<?php
2
/**
3
 * Privilege Util basic class.
4
 *
5
 * @package App
6
 *
7
 * @copyright YetiForce S.A.
8
 * @license   YetiForce Public License 6.5 (licenses/LicenseEN.txt or yetiforce.com)
9
 * @author    Mariusz Krzaczkowski <[email protected]>
10
 * @author    Radosław Skrzypczak <[email protected]>
11
 */
12
13
namespace App;
14
15
class PrivilegeUtil
16
{
17
	/** @var int Allowed group nests */
18
	public const GROUP_LOOP_LIMIT = 5;
19
20
	/** Function to get parent record owner.
21
	 * @param $tabid    -- tabid :: Type integer
0 ignored issues
show
Documentation Bug introduced by
The doc comment -- at position 0 could not be parsed: Unknown type name '--' at position 0 in --.
Loading history...
22
	 * @param $parModId -- parent module id :: Type integer
23
	 * @param $recordId -- record id :: Type integer
24
	 * @returns $parentRecOwner -- parentRecOwner:: Type integer
25
	 */
26
	public static function getParentRecordOwner($tabid, $parModId, $recordId)
27
	{
28
		Log::trace("Entering getParentRecordOwner($tabid,$parModId,$recordId) method ...");
29
		$parentRecOwner = [];
30
		$parentTabName = Module::getModuleName($parModId);
31
		$relTabName = Module::getModuleName($tabid);
32
		$fnName = 'get' . $relTabName . 'Related' . $parentTabName;
33
		$entId = static::$fnName($recordId);
34
		if ('' !== $entId) {
35
			$recordMetaData = \vtlib\Functions::getCRMRecordMetadata($entId);
36
			if ($recordMetaData) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $recordMetaData 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...
37
				$ownerId = $recordMetaData['smownerid'];
38
				$type = \App\Fields\Owner::getType($ownerId);
39
				$parentRecOwner[$type] = $ownerId;
40
			}
41
		}
42
		Log::trace('Exiting getParentRecordOwner method ...');
43
		return $parentRecOwner;
44
	}
45
46
	/**
47 1
	 * Function return related account with ticket.
48
	 *
49 1
	 * @param int $recordId
50 1
	 *
51 1
	 * @return int
52
	 */
53
	private static function getHelpDeskRelatedAccounts($recordId)
54
	{
55
		return (new Db\Query())->select(['parent_id'])->from('vtiger_troubletickets')
0 ignored issues
show
Bug Best Practice introduced by
The expression return new App\Db\Query(... 'Accounts'))->scalar() also could return the type false|string which is incompatible with the documented return type integer.
Loading history...
56
			->innerJoin('vtiger_crmentity', 'vtiger_troubletickets.parent_id = vtiger_crmentity.crmid')
57
			->where(['ticketid' => $recordId, 'vtiger_crmentity.setype' => 'Accounts'])->scalar();
58
	}
59
60
	protected static $datashareRelatedCache = false;
61 2
62
	/**
63 2
	 * Function to get data share related modules.
64 1
	 *
65 1
	 * @return array
66 1
	 */
67 1
	public static function getDatashareRelatedModules()
68 1
	{
69
		if (false === static::$datashareRelatedCache) {
70
			$relModSharArr = [];
71
			$dataReader = (new \App\Db\Query())->from('vtiger_datashare_relatedmodules')->createCommand()->query();
72 1
			while ($row = $dataReader->read()) {
73 1
				$relTabId = $row['relatedto_tabid'];
74
				if (isset($relModSharArr[$relTabId]) && \is_array($relModSharArr[$relTabId])) {
75 1
					$temArr = $relModSharArr[$relTabId];
76
					$temArr[] = $row['tabid'];
77 1
				} else {
78
					$temArr = [];
79 2
					$temArr[] = $row['tabid'];
80
				}
81
				$relModSharArr[$relTabId] = $temArr;
82
			}
83
			static::$datashareRelatedCache = $relModSharArr;
84
		}
85
		return static::$datashareRelatedCache;
0 ignored issues
show
Bug Best Practice introduced by
The expression return static::datashareRelatedCache also could return the type true which is incompatible with the documented return type array.
Loading history...
86
	}
87
88
	protected static $defaultSharingActionCache = false;
89 2
90
	/**
91 2
	 * This Function returns the Default Organisation Sharing Action Array for all modules.
92 1
	 *
93 1
	 * @return array
94
	 */
95 2
	public static function getAllDefaultSharingAction()
96
	{
97
		if (false === static::$defaultSharingActionCache) {
98
			Log::trace('getAllDefaultSharingAction');
99
			static::$defaultSharingActionCache = array_map('intval', (new \App\Db\Query())->select(['tabid', 'permission'])->from('vtiger_def_org_share')->createCommand()->queryAllByGroup(0));
100
		}
101
		return static::$defaultSharingActionCache;
0 ignored issues
show
Bug Best Practice introduced by
The expression return static::defaultSharingActionCache also could return the type true which is incompatible with the documented return type array.
Loading history...
102
	}
103
104
	/**
105 3
	 * Function to get the vtiger_role related user ids.
106
	 *
107 3
	 * @param string $roleId Role ID
108
	 *
109
	 * @return array $users Role related user array
110 3
	 */
111 3
	public static function getUsersByRole($roleId): array
112 3
	{
113 3
		if (Cache::has('getUsersByRole', $roleId)) {
114
			return Cache::get('getUsersByRole', $roleId);
115
		}
116
		$users = static::getQueryToUsersByRole($roleId)->column();
117
		$users = array_map('intval', $users);
118
		Cache::save('getUsersByRole', $roleId, $users);
119
		return $users;
120
	}
121
122
	/**
123 2
	 * Function to get the users names by role.
124
	 *
125 2
	 * @param int $roleId
126
	 *
127
	 * @return array $users
128 2
	 */
129 2
	public static function getUsersNameByRole($roleId)
130 2
	{
131 1
		if (Cache::has('getUsersNameByRole', $roleId)) {
132 1
			return Cache::get('getUsersNameByRole', $roleId);
133
		}
134
		$users = static::getUsersByRole($roleId);
135 2
		$roleRelatedUsers = [];
136 2
		if ($users) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $users 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...
137
			foreach ($users as $userId) {
138
				$roleRelatedUsers[$userId] = Fields\Owner::getUserLabel($userId);
139
			}
140
		}
141
		Cache::save('getUsersNameByRole', $roleId, $roleRelatedUsers);
142
		return $roleRelatedUsers;
143
	}
144 14
145
	/**
146 14
	 * Function to get the role related user ids.
147 2
	 *
148
	 * @param int $userId RoleId :: Type varchar
149 14
	 */
150 14
	public static function getRoleByUsers($userId)
151 14
	{
152 14
		if (Cache::has('getRoleByUsers', $userId)) {
153 14
			return Cache::get('getRoleByUsers', $userId);
154
		}
155
		$roleId = (new \App\Db\Query())->select(['roleid'])
156
			->from('vtiger_user2role')->where(['userid' => $userId])
157
			->scalar();
158
		Cache::save('getRoleByUsers', $userId, $roleId);
159
		return $roleId;
160
	}
161
162
	/**
163 14
	 * Function to get user groups.
164
	 *
165 14
	 * @param int $userId
166
	 *
167
	 * @return array - groupId's
168 14
	 */
169 14
	public static function getUserGroups($userId)
170 14
	{
171 14
		if (Cache::has('UserGroups', $userId)) {
172
			return Cache::get('UserGroups', $userId);
173
		}
174
		$groupIds = (new \App\Db\Query())->select(['groupid'])->from('vtiger_users2group')->where(['userid' => $userId])->column();
175
		$groupIds = array_map('intval', $groupIds);
176
		Cache::save('UserGroups', $userId, $groupIds);
177
		return $groupIds;
178
	}
179
180
	/**
181 5778
	 * This function is to retreive the vtiger_profiles associated with the  the specified role.
182
	 *
183 5778
	 * @param string $roleId
184 5778
	 *
185 5771
	 * @return array
186
	 */
187 14
	public static function getProfilesByRole($roleId)
188 14
	{
189 14
		$profiles = Cache::staticGet('getProfilesByRole', $roleId);
190 14
		if ($profiles) {
191 14
			return $profiles;
192 14
		}
193 14
		$profiles = (new \App\Db\Query())
194 14
			->select(['profileid'])
195
			->from('vtiger_role2profile')
196
			->where(['roleid' => $roleId])
197
			->column();
198
		$profiles = array_map('intval', $profiles);
199
		Cache::staticSave('getProfilesByRole', $roleId, $profiles);
200
		return $profiles;
201
	}
202
203
	/**
204 2
	 *  This function is to retreive the vtiger_profiles associated with the  the specified user.
205
	 *
206 2
	 * @param int $userId
207
	 *
208 2
	 * @return array
209
	 */
210
	public static function getProfilesByUser($userId)
211
	{
212
		$roleId = static::getRoleByUsers($userId);
213
214
		return static::getProfilesByRole($roleId);
215
	}
216
217
	const MEMBER_TYPE_USERS = 'Users';
218
	const MEMBER_TYPE_GROUPS = 'Groups';
219
	const MEMBER_TYPE_ROLES = 'Roles';
220
	const MEMBER_TYPE_ROLE_AND_SUBORDINATES = 'RoleAndSubordinates';
221
222
	protected static $membersCache = false;
223
224
	/**
225
	 * Function to get all members.
226
	 *
227
	 * @return array
228
	 */
229
	public static function getMembers()
230
	{
231
		if (false === static::$membersCache) {
232
			$members = [];
233
			$owner = new \App\Fields\Owner();
234
			foreach ($owner->initUsers() as $id => $user) {
235
				$members[static::MEMBER_TYPE_USERS][static::MEMBER_TYPE_USERS . ':' . $id] = ['name' => $user['fullName'], 'id' => $id, 'type' => static::MEMBER_TYPE_USERS];
236
			}
237
			foreach ($owner->getGroups(false) as $id => $groupName) {
238
				$members[static::MEMBER_TYPE_GROUPS][static::MEMBER_TYPE_GROUPS . ':' . $id] = ['name' => $groupName, 'id' => $id, 'type' => static::MEMBER_TYPE_GROUPS];
239
			}
240
			foreach (\Settings_Roles_Record_Model::getAll() as $id => $roleModel) {
241
				$members[static::MEMBER_TYPE_ROLES][static::MEMBER_TYPE_ROLES . ':' . $id] = ['name' => $roleModel->getName(), 'id' => $id, 'type' => static::MEMBER_TYPE_ROLES];
242
				$members[static::MEMBER_TYPE_ROLE_AND_SUBORDINATES][static::MEMBER_TYPE_ROLE_AND_SUBORDINATES . ':' . $id] = ['name' => $roleModel->getName(), 'id' => $id, 'type' => static::MEMBER_TYPE_ROLE_AND_SUBORDINATES];
243
			}
244
			static::$membersCache = $members;
245
		}
246
		return static::$membersCache;
0 ignored issues
show
Bug Best Practice introduced by
The expression return static::membersCache also could return the type true which is incompatible with the documented return type array.
Loading history...
247
	}
248
249
	/**
250 1
	 * Get list of users based on members, eg. Users:2, Roles:H2.
251
	 *
252 1
	 * @param string $member
253
	 *
254
	 * @return array
255 1
	 */
256 1
	public static function getUserByMember($member)
257 1
	{
258 1
		if (Cache::has('getUserByMember', $member)) {
259 1
			return Cache::get('getUserByMember', $member);
260 1
		}
261 1
		[$type, $id] = explode(':', $member);
262 1
		$users = [];
263 1
		switch ($type) {
264 1
			case 'Users':
265 1
				$users[] = (int) $id;
266 1
				break;
267 1
			case 'Groups':
268 1
				$users = array_merge($users, static::getUsersByGroup($id));
0 ignored issues
show
Bug introduced by
$id of type string is incompatible with the type integer expected by parameter $groupId of App\PrivilegeUtil::getUsersByGroup(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

268
				$users = array_merge($users, static::getUsersByGroup(/** @scrutinizer ignore-type */ $id));
Loading history...
269 1
				break;
270
			case 'Roles':
271
				$users = array_merge($users, static::getUsersByRole($id));
272
				break;
273 1
			case 'RoleAndSubordinates':
274 1
				$users = array_merge($users, static::getUsersByRoleAndSubordinate($id));
275 1
				break;
276
			default:
277
				break;
278
		}
279
		$users = array_unique($users);
280
		Cache::save('getUserByMember', $member, $users, Cache::LONG);
281
		return $users;
282
	}
283
284
	/**
285
	 * Get list of users based on group id.
286
	 *
287 1
	 * @param int        $groupId
288
	 * @param array|bool $subGroups
289 1
	 * @param int        $i
290 1
	 *
291
	 * @return array
292
	 */
293
	public static function getUsersByGroup($groupId, $subGroups = false, $i = 0)
294 1
	{
295
		$cacheKey = $groupId . (false === $subGroups ? '' : '#');
296 1
		if (Cache::has('getUsersByGroup', $cacheKey)) {
297 1
			return Cache::get('getUsersByGroup', $cacheKey);
298 1
		}
299 1
		if (false === $subGroups) {
300
			$users = static::getQueryToUsersByGroup($groupId)->column();
301
		} else {
302 1
			$users = static::getQueryToUsersByGroup($groupId, false)->column();
303 1
			if ($i < self::GROUP_LOOP_LIMIT) {
304 1
				++$i;
305 1
				if (true === $subGroups) {
306
					$subGroups = [];
307 1
				}
308 1
				$dataReader = (new \App\Db\Query())->select(['containsgroupid'])->from('vtiger_group2grouprel')->where(['groupid' => $groupId])->createCommand()->query();
309
				$containsGroups = [];
310
				while ($containsGroupId = $dataReader->readColumn(0)) {
311
					$roleUsers = static::getUsersByGroup($containsGroupId, $subGroups, $i);
312 1
					$containsGroups = array_merge($containsGroups, $roleUsers['users']);
313 1
					if (!isset($subGroups[$containsGroupId])) {
314 1
						$subGroups[$containsGroupId] = $containsGroups;
315
					}
316
					foreach ($roleUsers['subGroups'] as $key => $value) {
317
						if (!isset($subGroups[$key])) {
318
							$subGroups[$key] = $containsGroups;
319
						}
320
					}
321
				}
322
				if ($containsGroups) {
323
					$users = array_merge($users, $containsGroups);
324
				}
325
			} else {
326
				Log::error('Exceeded the recursive limit, a loop might have been created. Group ID:' . $groupId);
327
			}
328
		}
329
		$users = array_unique($users);
330 1
		$return = (false === $subGroups ? $users : ['users' => $users, 'subGroups' => $subGroups]);
331
		Cache::save('getUsersByGroup', $cacheKey, $return, Cache::LONG);
332
		return $return;
333
	}
334
335
	/**
336 1
	 * Gets query to users by members.
337 1
	 *
338 1
	 * @param array $members
339 1
	 *
340
	 * @return Db\Query
341
	 */
342
	public static function getQueryToUsersByMembers(array $members): Db\Query
343
	{
344
		$queryGenerator = (new \App\QueryGenerator('Users'))->setFields(['id']);
345
		$columName = $queryGenerator->getColumnName('id');
346
		$conditions = ['or'];
347
		foreach ($members as $member) {
348
			[$type, $id] = explode(':', $member);
349 1
			switch ($type) {
350
					case self::MEMBER_TYPE_USERS:
351 1
						if (!isset($conditions[$type])) {
352
							$conditions[$type][$columName] = [(int) $id];
353
						} else {
354 1
							$conditions[$type][$columName][] = (int) $id;
355 1
						}
356 1
						break;
357 1
					case self::MEMBER_TYPE_GROUPS:
358 1
						$conditions[] = [$columName => (new \App\Db\Query())->select(['userid'])->from(["condition_{$type}_{$id}_" . \App\Layout::getUniqueId() => self::getQueryToUsersByGroup((int) $id)])];
359 1
						break;
360
					case self::MEMBER_TYPE_ROLES:
361 1
						$conditions[] = [$columName => self::getQueryToUsersByRole($id)];
362
						break;
363
					case self::MEMBER_TYPE_ROLE_AND_SUBORDINATES:
364
						$conditions[] = [$columName => self::getQueryToUsersByRoleAndSubordinate($id)];
365
						break;
366
					default:
367
						break;
368
				}
369
		}
370
		if (\count($conditions) <= 1) {
371 5788
			$conditions[] = [$columName => -1];
372
		}
373 5788
374 5782
		return $queryGenerator->setFields(['id'])->addNativeCondition(array_values($conditions))->createQuery();
375
	}
376 20
377 20
	/**
378 20
	 * Gets query to users by group.
379 20
	 *
380 20
	 * @param int  $groupId
381 20
	 * @param bool $recursive
382 20
	 * @param int  $depth
383
	 *
384 20
	 * @return Db\Query
385 20
	 */
386
	public static function getQueryToUsersByGroup(int $groupId, bool $recursive = true, int $depth = 0): Db\Query
387
	{
388
		++$depth;
389
		$query = (new \App\Db\Query())->select(['userid'])->from('vtiger_users2group')->where(['groupid' => $groupId])
390
			->union(
391
			(new \App\Db\Query())->select(['vtiger_user2role.userid'])
392
				->from('vtiger_group2role')
393
				->innerJoin('vtiger_user2role', 'vtiger_group2role.roleid=vtiger_user2role.roleid')->where(['groupid' => $groupId])
394
			)
395 4
			->union(
396
			(new \App\Db\Query())->select(['vtiger_user2role.userid'])->from('vtiger_group2rs')
397 4
				->innerJoin('vtiger_role', "vtiger_group2rs.roleandsubid=vtiger_role.roleid OR vtiger_role.parentrole like CONCAT('%', vtiger_group2rs.roleandsubid, '::%')")
398 4
				->innerJoin('vtiger_user2role', 'vtiger_role.roleid=vtiger_user2role.roleid')
399
				->where(['vtiger_group2rs.groupid' => $groupId])
400
			);
401
		if ($recursive) {
402
			if ($depth < self::GROUP_LOOP_LIMIT) {
403
				$dataReader = (new \App\Db\Query())->select(['containsgroupid'])->from('vtiger_group2grouprel')->where(['groupid' => $groupId])->createCommand()->query();
404
				while ($containsGroupId = $dataReader->readColumn(0)) {
405
					$query->union((new \App\Db\Query())->select(['userid'])->from(["query_{$groupId}_{$containsGroupId}_{$depth}" => static::getQueryToUsersByGroup($containsGroupId, $recursive, $depth)]));
406
				}
407
				$dataReader->close();
408
			} else {
409 14
				Log::error('Exceeded the recursive limit, a loop might have been created. Group ID:' . $groupId);
410
			}
411 14
		}
412 14
		return $query;
413
	}
414
415
	/**
416
	 * Gets query to users by role.
417
	 *
418
	 * @param string $roleId
419
	 *
420
	 * @return Db\Query
421
	 */
422 2
	public static function getQueryToUsersByRole(string $roleId): Db\Query
423
	{
424 2
		return (new \App\Db\Query())->select(['userid'])->from('vtiger_user2role')->where(['roleid' => $roleId]);
425
	}
426
427 2
	/**
428 2
	 * Gets query to users by role and subordinate.
429 2
	 *
430 2
	 * @param string $roleId
431 2
	 *
432 2
	 * @return Db\Query
433 2
	 */
434 2
	public static function getQueryToUsersByRoleAndSubordinate(string $roleId): Db\Query
435
	{
436
		$parentRole = static::getRoleDetail($roleId)['parentrole'] ?? '-';
437
		return (new \App\Db\Query())->select(['vtiger_user2role.userid'])->from('vtiger_user2role')
438
			->innerJoin('vtiger_role', 'vtiger_user2role.roleid = vtiger_role.roleid')
439
			->where(['or', ['vtiger_role.parentrole' => $parentRole], ['like', 'vtiger_role.parentrole', "{$parentRole}::%", false]]);
440
	}
441
442
	/**
443
	 * Function to get the roles and subordinate users.
444 1
	 *
445
	 * @param string $roleId
446 1
	 *
447 1
	 * @return array
448
	 */
449
	public static function getUsersByRoleAndSubordinate($roleId)
450 1
	{
451 1
		if (Cache::has('getUsersByRoleAndSubordinate', $roleId)) {
452 1
			return Cache::get('getUsersByRoleAndSubordinate', $roleId);
453 1
		}
454 1
		$users = static::getQueryToUsersByRoleAndSubordinate($roleId)->column();
455
		$users = array_map('intval', $users);
456
		Cache::save('getUsersByRoleAndSubordinate', $roleId, $users, Cache::LONG);
457
458
		return $users;
459
	}
460
461
	/**
462
	 * Function to get the vtiger_role information of the specified vtiger_role.
463
	 *
464 1
	 * @param $roleId
465
	 *
466 1
	 * @return array|bool|string
467
	 */
468
	public static function getRoleDetail($roleId)
469 1
	{
470 1
		if (Cache::has('RoleDetail', $roleId)) {
471 1
			return Cache::get('RoleDetail', $roleId);
472 1
		}
473 1
		$row = (new Db\Query())->from('vtiger_role')->where(['roleid' => $roleId])->one();
474
		if ($row) {
475
			$parentRoleArr = explode('::', $row['parentrole']);
476
			array_pop($parentRoleArr);
477
			$row['parentRoles'] = $parentRoleArr;
478
			$immediateParent = array_pop($parentRoleArr);
479
			$row['immediateParent'] = $immediateParent;
480
		}
481
		Cache::save('RoleDetail', $roleId, $row);
482
		return $row;
483 2
	}
484
485 2
	/**
486
	 * Function to get the role name.
487
	 *
488 2
	 * @param int $roleId
489 2
	 *
490 2
	 * @return string
491 2
	 */
492 1
	public static function getRoleName($roleId)
493 1
	{
494
		$roleInfo = static::getRoleDetail($roleId);
495
		return $roleInfo['rolename'];
496
	}
497
498
	/**
499
	 * To retreive the parent vtiger_role of the specified vtiger_role.
500
	 *
501
	 * @param $roleid -- The Role Id:: Type varchar
0 ignored issues
show
Documentation Bug introduced by
The doc comment -- at position 0 could not be parsed: Unknown type name '--' at position 0 in --.
Loading history...
502
	 * @param mixed $roleId
503
	 *
504
	 * @return parent vtiger_role array in the following format:
505 2
	 */
506 2
	public static function getParentRole($roleId)
507
	{
508
		$roleInfo = static::getRoleDetail($roleId);
509
		return $roleInfo['parentRoles'];
510
	}
511
512
	/**
513
	 * To retreive the subordinate vtiger_roles of the specified parent vtiger_role.
514
	 *
515
	 * @param int $roleId
516 2
	 *
517
	 * @return array
518 2
	 */
519
	public static function getRoleSubordinates($roleId)
520
	{
521 2
		if (Cache::has('getRoleSubordinates', $roleId)) {
522 2
			return Cache::get('getRoleSubordinates', $roleId);
523 2
		}
524 1
		$roleDetails = static::getRoleDetail($roleId);
525 1
		$roleSubordinates = (new \App\Db\Query())
526
			->select(['roleid'])
527
			->from('vtiger_role')
528
			->where(['like', 'parentrole', $roleDetails['parentrole'] . '::%', false])
529
			->column();
530
		Cache::save('getRoleSubordinates', $roleId, $roleSubordinates, Cache::LONG);
531
		return $roleSubordinates;
532
	}
533
534
	/**
535
	 * Function to get the Profile Tab Permissions for the specified vtiger_profileid.
536
	 *
537 2
	 * @param int $profileid
538 2
	 *
539 2
	 * @return int[]
540
	 */
541 2
	public static function getProfileTabsPermission($profileid)
542 2
	{
543
		Log::trace('Entering getProfileTabsPermission(' . $profileid . ') method ...');
544
		if (Cache::has('getProfileTabsPermission', $profileid)) {
545
			return Cache::get('getProfileTabsPermission', $profileid);
546
		}
547
		$profileData = (new Db\Query())->select(['tabid', 'permissions'])->from('vtiger_profile2tab')->where(['profileid' => $profileid])->createCommand()->queryAllByGroup(0);
548
		$profileData = array_map('intval', $profileData);
549
		Cache::save('getProfileTabsPermission', $profileid, $profileData);
550
		Log::trace('Exiting getProfileTabsPermission method ...');
551
		return $profileData;
552 1
	}
553
554 1
	/**
555 1
	 * Function to get the Profile Global Information for the specified vtiger_profileid.
556 1
	 *
557 1
	 * @param int $profileid
558 1
	 *
559
	 * @return int[]
560 1
	 */
561
	public static function getProfileGlobalPermission($profileid)
562
	{
563
		if (Cache::has('getProfileGlobalPermission', $profileid)) {
564
			return Cache::get('getProfileGlobalPermission', $profileid);
565
		}
566
		$profileData = (new Db\Query())->select(['globalactionid', 'globalactionpermission'])->from('vtiger_profile2globalpermissions')
567
			->where(['profileid' => $profileid])->createCommand()->queryAllByGroup(0);
568
		$profileData = array_map('intval', $profileData);
569
		Cache::save('getProfileGlobalPermission', $profileid, $profileData);
570 1
		return $profileData;
571
	}
572 1
573 1
	/**
574 1
	 * To retreive the global permission of the specifed user from the various vtiger_profiles associated with the user.
575 1
	 *
576 1
	 * @param int $userId
577
	 *
578 1
	 * @return int[]
579
	 */
580
	public static function getCombinedUserGlobalPermissions($userId)
581
	{
582
		if (Cache::staticHas('getCombinedUserGlobalPermissions', $userId)) {
583
			return Cache::staticGet('getCombinedUserGlobalPermissions', $userId);
584
		}
585
		$userGlobalPerrArr = [];
586
		$profArr = static::getProfilesByUser($userId);
587
		$profileId = array_shift($profArr);
588 1
		if ($profileId) {
589
			$userGlobalPerrArr = static::getProfileGlobalPermission($profileId);
590 1
			foreach ($profArr as $profileId) {
591
				$tempUserGlobalPerrArr = static::getProfileGlobalPermission($profileId);
592
				foreach ($userGlobalPerrArr as $globalActionId => $globalActionPermission) {
593 1
					if (1 === $globalActionPermission) {
594 1
						$permission = $tempUserGlobalPerrArr[$globalActionId];
595 1
						if (0 === $permission) {
596 1
							$userGlobalPerrArr[$globalActionId] = $permission;
597 1
						}
598 1
					}
599
				}
600 1
			}
601
		}
602 1
		Cache::staticSave('getCombinedUserGlobalPermissions', $userId, $userGlobalPerrArr);
603 1
		return $userGlobalPerrArr;
604
	}
605
606
	/**
607
	 * To retreive the vtiger_tab permissions of the specifed user from the various vtiger_profiles associated with the user.
608
	 *
609
	 * @param int $userId
610
	 *
611
	 * @return array
612
	 */
613 2
	public static function getCombinedUserModulesPermissions($userId)
614
	{
615 2
		if (Cache::staticHas('getCombinedUserModulesPermissions', $userId)) {
616 2
			return Cache::staticGet('getCombinedUserModulesPermissions', $userId);
617 2
		}
618 1
		$profArr = static::getProfilesByUser($userId);
619 1
		$profileId = array_shift($profArr);
620
		if ($profileId) {
621 2
			$userTabPerrArr = static::getProfileTabsPermission($profileId);
622 2
			foreach ($profArr as $profileId) {
623
				$tempUserTabPerrArr = static::getProfileTabsPermission($profileId);
624
				foreach ($userTabPerrArr as $tabId => $tabPermission) {
625
					if (1 === $tabPermission) {
626
						$permission = $tempUserTabPerrArr[$tabId];
627
						if (0 === $permission) {
628
							$userTabPerrArr[$tabId] = $permission;
629
						}
630
					}
631
				}
632
			}
633
		}
634
		$homeId = Module::getModuleId('Home');
635
		if (!isset($userTabPerrArr[$homeId])) {
636 2
			$dashBoardId = Module::getModuleId('Dashboard');
637
			$userTabPerrArr[$homeId] = $userTabPerrArr[$dashBoardId] ?? 1;
638
		}
639
		Cache::staticSave('getCombinedUserModulesPermissions', $userId, $userTabPerrArr);
640
		return $userTabPerrArr;
641
	}
642
643
	/**
644
	 * Function to get all the vtiger_tab utility action permission for the specified vtiger_profile.
645
	 *
646
	 * @param int $profileid
647
	 *
648
	 * @return array
649
	 */
650
	public static function getUtilityPermissions($profileid)
651
	{
652
		$permissions = [];
653
		$dataReader = (new Db\Query())->from('vtiger_profile2utility')
654
			->where(['profileid' => $profileid])->createCommand()->query();
655
		while ($row = $dataReader->read()) {
656
			$permissions[$row['tabid']][$row['activityid']] = (int) $row['permission'];
657
		}
658
		return $permissions;
659
	}
660
661
	/**
662
	 * Function to get the Profile Action Permissions for the specified vtiger_profileid.
663
	 *
664
	 * @param int $profileid
665
	 *
666
	 * @return array
667
	 */
668 2
	public static function getStandardPermissions($profileid)
669
	{
670 2
		$permissions = [];
671 2
		$dataReader = (new Db\Query())->from('vtiger_profile2standardpermissions')
672
			->where(['profileid' => $profileid])->createCommand()->query();
673
		while ($row = $dataReader->read()) {
674 2
			$permissions[$row['tabid']][$row['operation']] = (int) $row['permissions'];
675 2
		}
676 2
		return $permissions;
677 2
	}
678 2
679 2
	/**
680
	 * Function to get the Standard and Utility Profile Action Permissions for the specified vtiger_profileid.
681 2
	 *
682 2
	 * @param int $profileid
683 2
	 *
684
	 * @return array
685
	 */
686
	public static function getAllProfilePermissions($profileid)
687
	{
688
		if (Cache::staticHas(__METHOD__, $profileid)) {
689
			return Cache::staticGet(__METHOD__, $profileid);
690
		}
691
		$allActions = static::getStandardPermissions($profileid);
692
		$utilityActions = static::getUtilityPermissions($profileid);
693
		foreach ($utilityActions as $tabid => $utilityAction) {
694
			$actionTabs = $allActions[$tabid] ?? [];
695
			foreach ($utilityAction as $utilityId => $utilityPermission) {
696
				$actionTabs[$utilityId] = (int) $utilityPermission;
697
			}
698 2
			$allActions[$tabid] = $actionTabs;
699
		}
700 2
		Cache::staticSave(__METHOD__, $profileid, $allActions);
701 2
		return $allActions;
702 2
	}
703 2
704 2
	/**
705
	 * To retreive the vtiger_tab acion permissions of the specifed user from the various vtiger_profiles associated with the user.
706 2
	 *
707
	 * @param int $userId
708 2
	 *
709 2
	 * @return array
710
	 */
711 2
	public static function getCombinedUserActionsPermissions($userId)
712
	{
713
		$profiles = static::getProfilesByUser($userId);
714
		$actionPermissions = [];
715
		if (isset($profiles[0])) {
716
			$actionPermissions = static::getAllProfilePermissions($profiles[0]);
717
			unset($profiles[0]);
718
		}
719
		if (\is_array($profiles)) {
0 ignored issues
show
introduced by
The condition is_array($profiles) is always true.
Loading history...
720
			foreach ($profiles as $profileId) {
721
				$tempActionPerrArr = static::getAllProfilePermissions($profileId);
722
				foreach ($actionPermissions as $tabId => $permissionsInModule) {
723
					foreach ($permissionsInModule as $actionId => $permission) {
724
						if (1 == $permission) {
725
							$nowPermission = $tempActionPerrArr[$tabId][$actionId];
726
							if (0 == $nowPermission && '' != $nowPermission) {
727
								$actionPermissions[$tabId][$actionId] = $nowPermission;
728
							}
729
						}
730 2
					}
731 2
				}
732 2
			}
733 1
		}
734
		return $actionPermissions;
735
	}
736 2
737 2
	protected static $dataShareStructure = [
738
		'role2role' => ['vtiger_datashare_role2role', 'to_roleid'],
739
		'role2rs' => ['vtiger_datashare_role2rs', 'to_roleandsubid'],
740
		'role2group' => ['vtiger_datashare_role2group', 'to_groupid'],
741
		'role2user' => ['vtiger_datashare_role2us', 'to_userid'],
742
		'rs2role' => ['vtiger_datashare_rs2role', 'to_roleid'],
743
		'rs2rs' => ['vtiger_datashare_rs2rs', 'to_roleandsubid'],
744
		'rs2group' => ['vtiger_datashare_rs2grp', 'to_groupid'],
745
		'rs2user' => ['vtiger_datashare_rs2us', 'to_userid'],
746
		'group2role' => ['vtiger_datashare_grp2role', 'to_roleid'],
747
		'group2rs' => ['vtiger_datashare_grp2rs', 'to_roleandsubid'],
748
		'group2user' => ['vtiger_datashare_grp2us', 'to_userid'],
749
		'group2group' => ['vtiger_datashare_grp2grp', 'to_groupid'],
750
		'user2user' => ['vtiger_datashare_us2us', 'to_userid'],
751
		'user2group' => ['vtiger_datashare_us2grp', 'to_groupid'],
752
		'user2role' => ['vtiger_datashare_us2role', 'to_roleid'],
753
		'user2rs' => ['vtiger_datashare_us2rs', 'to_roleandsubid'],
754
	];
755
756 2
	/**
757 2
	 * Get data share.
758 1
	 *
759
	 * @param int   $tabId
760 2
	 * @param int   $roleId
761 2
	 * @param mixed $type
762
	 * @param mixed $data
763
	 *
764
	 * @return array
765
	 */
766
	public static function getDatashare($type, $tabId, $data)
767
	{
768
		$cacheKey = "$type|$tabId|" . (\is_array($data) ? implode(',', $data) : $data);
769
		if (Cache::staticHas('getDatashare', $cacheKey)) {
770
			return Cache::staticGet('getDatashare', $cacheKey);
771
		}
772
		$structure = static::$dataShareStructure[$type];
773
		$query = (new \App\Db\Query())->select([$structure[0] . '.*'])->from($structure[0])
774
			->innerJoin('vtiger_datashare_module_rel', "$structure[0].shareid = vtiger_datashare_module_rel.shareid")
775
			->where(['vtiger_datashare_module_rel.tabid' => $tabId]);
776
		if ($data) {
777
			$query->andWhere([$structure[1] => $data]);
778
		}
779
		$rows = $query->all();
780
		Cache::staticSave('getDatashare', $cacheKey, $rows);
781 2
		return $rows;
782 2
	}
783
784
	/**
785
	 * Gives an array which contains the information for what all roles, groups and user data is to be shared with the spcified user for the specified module.
786
	 *
787
	 * @param string $module            module name
788
	 * @param int    $userid            user id
789
	 * @param array  $defOrgShare       default organization sharing permission array
790
	 * @param string $currentUserRoles  roleid
791
	 * @param string $parentRoles       parent roles
792
	 * @param int    $currentUserGroups user id
793
	 *
794
	 * @return array array which contains the id of roles,group and users data shared with specifed user for the specified module
795
	 */
796
	public static function getUserModuleSharingObjects($module, $userid, $defOrgShare, $currentUserRoles, $parentRoles, $currentUserGroups)
797
	{
798
		$modTabId = Module::getModuleId($module);
799
		$modShareWritePermission = $modShareReadPermission = ['ROLE' => [], 'GROUP' => []];
800 2
		$modDefOrgShare = null;
801
		if (isset($defOrgShare[$modTabId])) {
802
			$modDefOrgShare = $defOrgShare[$modTabId];
803
		}
804
		$shareIdMembers = [];
805
		//If Sharing of leads is Private
806
		if (3 === $modDefOrgShare || 0 === $modDefOrgShare) {
807
			$roleWritePer = $roleWritePer = $grpReadPer = $grpWritePer = $roleReadPer = [];
0 ignored issues
show
Unused Code introduced by
The assignment to $roleWritePer is dead and can be removed.
Loading history...
808
			//Retreiving from vtiger_role to vtiger_role
809
			foreach (static::getDatashare('role2role', $modTabId, $currentUserRoles) as $row) {
810
				$shareRoleId = $row['share_roleid'];
811
				$shareIdRoles = [];
812
				$shareIdRoles[] = $shareRoleId;
813
				$shareIdMembers[$row['shareid']] = ['ROLE' => $shareIdRoles];
814
				if (1 === (int) $row['permission']) {
815
					if (3 === $modDefOrgShare && !isset($roleReadPer[$shareRoleId])) {
816
						$roleReadPer[$shareRoleId] = static::getUsersByRole($shareRoleId);
817
					}
818
					if (!isset($roleWritePer[$shareRoleId])) {
819
						$roleWritePer[$shareRoleId] = static::getUsersByRole($shareRoleId);
820 2
					}
821
				} elseif (0 === (int) $row['permission'] && 3 === $modDefOrgShare) {
822
					if (!isset($roleReadPer[$shareRoleId])) {
823
						$roleReadPer[$shareRoleId] = static::getUsersByRole($shareRoleId);
824
					}
825
				}
826
			}
827
			//Retreiving from role to rs
828
			$parRoleList = [];
829
			if (\is_array($parentRoles)) {
0 ignored issues
show
introduced by
The condition is_array($parentRoles) is always false.
Loading history...
830
				foreach ($parentRoles as $par_role_id) {
831
					$parRoleList[] = $par_role_id;
832
				}
833
			}
834
			$parRoleList[] = $currentUserRoles;
835
			foreach (static::getDatashare('role2rs', $modTabId, $parRoleList) as $row) {
836
				$shareRoleId = $row['share_roleid'];
837
				$shareIdRoles = [];
838
				$shareIdRoles[] = $shareRoleId;
839
				$shareIdMembers[$row['shareid']] = ['ROLE' => $shareIdRoles];
840 2
				if (1 === (int) $row['permission']) {
841
					if (3 === $modDefOrgShare && !isset($roleReadPer[$shareRoleId])) {
842
						$roleReadPer[$shareRoleId] = static::getUsersByRole($shareRoleId);
843
					}
844
					if (!isset($roleWritePer[$shareRoleId])) {
845
						$roleWritePer[$shareRoleId] = static::getUsersByRole($shareRoleId);
846
					}
847
				} elseif (0 === (int) $row['permission'] && 3 === $modDefOrgShare) {
848
					if (!isset($roleReadPer[$shareRoleId])) {
849
						$roleReadPer[$shareRoleId] = static::getUsersByRole($shareRoleId);
850
					}
851
				}
852
			}
853
			//Get roles from Role2Grp
854
			$groupList = $currentUserGroups;
855
			if (empty($groupList)) {
856
				$groupList = [0];
857
			}
858
			if ($groupList) {
859
				foreach (static::getDatashare('role2group', $modTabId, $groupList) as $row) {
860 2
					$shareRoleId = $row['share_roleid'];
861
					$shareIdRoles = [];
862
					$shareIdRoles[] = $shareRoleId;
863
					$shareIdMembers[$row['shareid']] = ['ROLE' => $shareIdRoles];
864
					if (1 === (int) $row['permission']) {
865
						if (3 === $modDefOrgShare && !isset($roleReadPer[$shareRoleId])) {
866
							$roleReadPer[$shareRoleId] = static::getUsersByRole($shareRoleId);
867
						}
868
						if (!isset($roleWritePer[$shareRoleId])) {
869
							$roleWritePer[$shareRoleId] = static::getUsersByRole($shareRoleId);
870
						}
871
					} elseif (0 === (int) $row['permission'] && 3 === $modDefOrgShare) {
872
						if (!isset($roleReadPer[$shareRoleId])) {
873
							$roleReadPer[$shareRoleId] = static::getUsersByRole($shareRoleId);
874
						}
875
					}
876
				}
877
			}
878
			//Get roles from Role2Us
879 2
			if (!empty($userid)) {
880 2
				foreach (static::getDatashare('role2user', $modTabId, $userid) as $row) {
881
					$shareRoleId = $row['share_roleid'];
882
					$shareIdRoles = [];
883 2
					$shareIdRoles[] = $shareRoleId;
884
					$shareIdMembers[$row['shareid']] = ['ROLE' => $shareIdRoles];
885
					if (1 === (int) $row['permission']) {
886
						if (3 === $modDefOrgShare && !isset($roleReadPer[$shareRoleId])) {
887
							$roleReadPer[$shareRoleId] = static::getUsersByRole($shareRoleId);
888
						}
889
						if (!isset($roleWritePer[$shareRoleId])) {
890
							$roleWritePer[$shareRoleId] = static::getUsersByRole($shareRoleId);
891
						}
892
					} elseif (0 === (int) $row['permission'] && 3 === $modDefOrgShare && !isset($roleReadPer[$shareRoleId])) {
893
						$roleReadPer[$shareRoleId] = static::getUsersByRole($shareRoleId);
894
					}
895
				}
896
			}
897
			//Retreiving from rs to vtiger_role
898
			foreach (static::getDatashare('rs2role', $modTabId, $currentUserRoles) as $row) {
899
				$shareRoleIds = static::getRoleSubordinates($row['share_roleandsubid']);
900
				$shareRoleIds[] = $row['share_roleandsubid'];
901
				foreach ($shareRoleIds as $shareRoleId) {
902
					if (1 === (int) $row['permission']) {
903
						if (3 === $modDefOrgShare && !isset($roleReadPer[$shareRoleId])) {
904
							$roleReadPer[$shareRoleId] = static::getUsersByRole($shareRoleId);
905
						}
906
						if (!isset($roleWritePer[$shareRoleId])) {
907
							$roleWritePer[$shareRoleId] = static::getUsersByRole($shareRoleId);
908
						}
909
					} elseif (0 === (int) $row['permission'] && 3 === $modDefOrgShare) {
910
						if (!isset($roleReadPer[$shareRoleId])) {
911
							$roleReadPer[$shareRoleId] = static::getUsersByRole($shareRoleId);
912
						}
913
					}
914
				}
915
				$shareIdMembers[$row['shareid']] = ['ROLE' => $shareRoleIds];
916
			}
917
			//Retreiving from rs to rs
918
			foreach (static::getDatashare('rs2rs', $modTabId, $parRoleList) as $row) {
919
				$shareRoleIds = static::getRoleSubordinates($row['share_roleandsubid']);
920
				$shareRoleIds[] = $row['share_roleandsubid'];
921
				foreach ($shareRoleIds as $shareRoleId) {
922
					if (1 === (int) $row['permission']) {
923
						if (3 === $modDefOrgShare && !isset($roleReadPer[$shareRoleId])) {
924
							$roleReadPer[$shareRoleId] = static::getUsersByRole($shareRoleId);
925
						}
926
						if (!isset($roleWritePer[$shareRoleId])) {
927
							$roleWritePer[$shareRoleId] = static::getUsersByRole($shareRoleId);
928
						}
929 2
					} elseif (0 === (int) $row['permission'] && 3 === $modDefOrgShare) {
930
						if (!isset($roleReadPer[$shareRoleId])) {
931
							$roleReadPer[$shareRoleId] = static::getUsersByRole($shareRoleId);
932
						}
933
					}
934
				}
935
				$shareIdMembers[$row['shareid']] = ['ROLE' => $shareRoleIds];
936
			}
937
			//Get roles from Rs2Grp
938
			foreach (static::getDatashare('rs2group', $modTabId, $groupList) as $row) {
939
				$shareRoleIds = static::getRoleSubordinates($row['share_roleandsubid']);
940
				$shareRoleIds[] = $row['share_roleandsubid'];
941
				foreach ($shareRoleIds as $shareRoleId) {
942
					if (1 === (int) $row['permission']) {
943
						if (3 === $modDefOrgShare && !isset($roleReadPer[$shareRoleId])) {
944
							$roleReadPer[$shareRoleId] = static::getUsersByRole($shareRoleId);
945
						}
946
						if (!isset($roleWritePer[$shareRoleId])) {
947
							$roleWritePer[$shareRoleId] = static::getUsersByRole($shareRoleId);
948
						}
949
					} elseif (0 === (int) $row['permission'] && 3 === $modDefOrgShare) {
950
						if (!isset($roleReadPer[$shareRoleId])) {
951
							$roleReadPer[$shareRoleId] = static::getUsersByRole($shareRoleId);
952
						}
953
					}
954
				}
955
				$shareIdMembers[$row['shareid']] = ['ROLE' => $shareRoleIds];
956
			}
957
			//Get roles from Rs2Us
958
			foreach (static::getDatashare('rs2user', $modTabId, $userid) as $row) {
959
				$shareRoleIds = static::getRoleSubordinates($row['share_roleandsubid']);
960
				$shareRoleIds[] = $row['share_roleandsubid'];
961
				foreach ($shareRoleIds as $shareRoleId) {
962
					if (1 === (int) $row['permission']) {
963
						if (3 === $modDefOrgShare && !isset($roleReadPer[$shareRoleId])) {
964
							$roleReadPer[$shareRoleId] = static::getUsersByRole($shareRoleId);
965
						}
966
						if (!isset($roleWritePer[$shareRoleId])) {
967
							$roleWritePer[$shareRoleId] = static::getUsersByRole($shareRoleId);
968
						}
969
					} elseif (0 === (int) $row['permission'] && 3 === $modDefOrgShare) {
970
						if (!isset($roleReadPer[$shareRoleId])) {
971
							$roleReadPer[$shareRoleId] = static::getUsersByRole($shareRoleId);
972
						}
973
					}
974
				}
975 2
				$shareIdMembers[$row['shareid']] = ['ROLE' => $shareRoleIds];
976
			}
977
			$modShareReadPermission['ROLE'] = $roleReadPer;
978
			$modShareWritePermission['ROLE'] = $roleWritePer;
979
980
			//Retreiving from the grp2role sharing
981
			foreach (static::getDatashare('group2role', $modTabId, $currentUserRoles) as $row) {
982
				$shareGrpId = (int) $row['share_groupid'];
983
				$shareIdGrps = [];
984
				$shareIdGrps[] = $shareGrpId;
985
				if (1 === (int) $row['permission']) {
986
					if (3 === $modDefOrgShare && !isset($grpReadPer[$shareGrpId])) {
987
						$usersByGroup = static::getUsersByGroup($shareGrpId, true);
988
						$grpReadPer[$shareGrpId] = $usersByGroup['users'];
989
						foreach ($usersByGroup['subGroups'] as $subgrpid => $subgrpusers) {
990
							if (!isset($grpReadPer[$subgrpid])) {
991
								$grpReadPer[$subgrpid] = $subgrpusers;
992
							}
993
							if (!\in_array($subgrpid, $shareIdGrps)) {
994
								$shareIdGrps[] = $subgrpid;
995
							}
996
						}
997
					}
998
					if (!isset($grpWritePer[$shareGrpId])) {
999
						$usersByGroup = static::getUsersByGroup($shareGrpId, true);
1000
						$grpWritePer[$shareGrpId] = $usersByGroup['users'];
1001
						foreach ($usersByGroup['subGroups'] as $subgrpid => $subgrpusers) {
1002
							if (!isset($grpWritePer[$subgrpid])) {
1003
								$grpWritePer[$subgrpid] = $subgrpusers;
1004
							}
1005
							if (!\in_array($subgrpid, $shareIdGrps)) {
1006
								$shareIdGrps[] = $subgrpid;
1007
							}
1008
						}
1009
					}
1010
				} elseif (0 === (int) $row['permission'] && 3 === $modDefOrgShare) {
1011
					if (!isset($grpReadPer[$shareGrpId])) {
1012
						$usersByGroup = static::getUsersByGroup($shareGrpId, true);
1013
						$grpReadPer[$shareGrpId] = $usersByGroup['users'];
1014
						foreach ($usersByGroup['subGroups'] as $subgrpid => $subgrpusers) {
1015
							if (!isset($grpReadPer[$subgrpid])) {
1016
								$grpReadPer[$subgrpid] = $subgrpusers;
1017
							}
1018
							if (!\in_array($subgrpid, $shareIdGrps)) {
1019
								$shareIdGrps[] = $subgrpid;
1020
							}
1021 2
						}
1022
					}
1023
				}
1024
				$shareIdMembers[$row['shareid']] = ['GROUP' => $shareIdGrps];
1025
			}
1026
			//Retreiving from the grp2rs sharing
1027
			foreach (static::getDatashare('group2rs', $modTabId, $parRoleList) as $row) {
1028
				$shareGrpId = (int) $row['share_groupid'];
1029
				$shareIdGrps = [];
1030
				$shareIdGrps[] = $shareGrpId;
1031
				if (1 === (int) $row['permission']) {
1032
					if (3 === $modDefOrgShare && !isset($grpReadPer[$shareGrpId])) {
1033
						$usersByGroup = static::getUsersByGroup($shareGrpId, true);
1034
						$grpReadPer[$shareGrpId] = $usersByGroup['users'];
1035
						foreach ($usersByGroup['subGroups'] as $subgrpid => $subgrpusers) {
1036
							if (!isset($grpReadPer[$subgrpid])) {
1037
								$grpReadPer[$subgrpid] = $subgrpusers;
1038
							}
1039
							if (!\in_array($subgrpid, $shareIdGrps)) {
1040
								$shareIdGrps[] = $subgrpid;
1041
							}
1042
						}
1043
					}
1044
					if (!isset($grpWritePer[$shareGrpId])) {
1045
						$usersByGroup = static::getUsersByGroup($shareGrpId, true);
1046
						$grpWritePer[$shareGrpId] = $usersByGroup['users'];
1047
						foreach ($usersByGroup['subGroups'] as $subgrpid => $subgrpusers) {
1048
							if (!isset($grpWritePer[$subgrpid])) {
1049
								$grpWritePer[$subgrpid] = $subgrpusers;
1050
							}
1051
							if (!\in_array($subgrpid, $shareIdGrps)) {
1052
								$shareIdGrps[] = $subgrpid;
1053
							}
1054
						}
1055
					}
1056
				} elseif (0 === (int) $row['permission'] && 3 === $modDefOrgShare) {
1057
					if (!isset($grpReadPer[$shareGrpId])) {
1058
						$usersByGroup = static::getUsersByGroup($shareGrpId, true);
1059
						$grpReadPer[$shareGrpId] = $usersByGroup['users'];
1060
						foreach ($usersByGroup['subGroups'] as $subgrpid => $subgrpusers) {
1061
							if (!isset($grpReadPer[$subgrpid])) {
1062
								$grpReadPer[$subgrpid] = $subgrpusers;
1063
							}
1064
							if (!\in_array($subgrpid, $shareIdGrps)) {
1065
								$shareIdGrps[] = $subgrpid;
1066
							}
1067 2
						}
1068
					}
1069
				}
1070
				$shareIdMembers[$row['shareid']] = ['GROUP' => $shareIdGrps];
1071
			}
1072
			//Retreiving from the grp2us sharing
1073
			foreach (static::getDatashare('group2user', $modTabId, $userid) as $row) {
1074
				$shareGrpId = (int) $row['share_groupid'];
1075
				$shareIdGrps = [];
1076
				$shareIdGrps[] = $shareGrpId;
1077
				if (1 === (int) $row['permission']) {
1078
					if (3 === $modDefOrgShare && !isset($grpReadPer[$shareGrpId])) {
1079
						$usersByGroup = static::getUsersByGroup($shareGrpId, true);
1080
						$grpReadPer[$shareGrpId] = $usersByGroup['users'];
1081
						foreach ($usersByGroup['subGroups'] as $subgrpid => $subgrpusers) {
1082
							if (!isset($grpReadPer[$subgrpid])) {
1083
								$grpReadPer[$subgrpid] = $subgrpusers;
1084
							}
1085
							if (!\in_array($subgrpid, $shareIdGrps)) {
1086 2
								$shareIdGrps[] = $subgrpid;
1087
							}
1088
						}
1089
					}
1090
					if (!isset($grpWritePer[$shareGrpId])) {
1091
						$usersByGroup = static::getUsersByGroup($shareGrpId, true);
1092
						$grpWritePer[$shareGrpId] = $usersByGroup['users'];
1093
						foreach ($usersByGroup['subGroups'] as $subgrpid => $subgrpusers) {
1094
							if (!isset($grpWritePer[$subgrpid])) {
1095
								$grpWritePer[$subgrpid] = $subgrpusers;
1096
							}
1097
							if (!\in_array($subgrpid, $shareIdGrps)) {
1098
								$shareIdGrps[] = $subgrpid;
1099
							}
1100
						}
1101
					}
1102
				} elseif (0 === (int) $row['permission'] && 3 === $modDefOrgShare) {
1103
					if (!isset($grpReadPer[$shareGrpId])) {
1104
						$usersByGroup = static::getUsersByGroup($shareGrpId, true);
1105 2
						$grpReadPer[$shareGrpId] = $usersByGroup['users'];
1106
						foreach ($usersByGroup['subGroups'] as $subgrpid => $subgrpusers) {
1107
							if (!isset($grpReadPer[$subgrpid])) {
1108
								$grpReadPer[$subgrpid] = $subgrpusers;
1109
							}
1110
							if (!\in_array($subgrpid, $shareIdGrps)) {
1111
								$shareIdGrps[] = $subgrpid;
1112
							}
1113
						}
1114
					}
1115
				}
1116
				$shareIdMembers[$row['shareid']] = ['GROUP' => $shareIdGrps];
1117
			}
1118
			//Retreiving from the grp2grp sharing
1119
			foreach (static::getDatashare('group2group', $modTabId, $groupList) as $row) {
1120
				$shareGrpId = (int) $row['share_groupid'];
1121
				$shareIdGrps = [];
1122
				$shareIdGrps[] = $shareGrpId;
1123
				if (1 === (int) $row['permission']) {
1124
					if (3 === $modDefOrgShare && !isset($grpReadPer[$shareGrpId])) {
1125 2
						$usersByGroup = static::getUsersByGroup($shareGrpId, true);
1126
						$grpReadPer[$shareGrpId] = $usersByGroup['users'];
1127
						foreach ($usersByGroup['subGroups'] as $subgrpid => $subgrpusers) {
1128
							if (!isset($grpReadPer[$subgrpid])) {
1129
								$grpReadPer[$subgrpid] = $subgrpusers;
1130
							}
1131
							if (!\in_array($subgrpid, $shareIdGrps)) {
1132
								$shareIdGrps[] = $subgrpid;
1133
							}
1134
						}
1135
					}
1136
					if (!isset($grpWritePer[$shareGrpId])) {
1137
						$usersByGroup = static::getUsersByGroup($shareGrpId, true);
1138
						$grpWritePer[$shareGrpId] = $usersByGroup['users'];
1139
						foreach ($usersByGroup['subGroups'] as $subgrpid => $subgrpusers) {
1140
							if (!isset($grpWritePer[$subgrpid])) {
1141
								$grpWritePer[$subgrpid] = $subgrpusers;
1142
							}
1143 2
							if (!\in_array($subgrpid, $shareIdGrps)) {
1144 2
								$shareIdGrps[] = $subgrpid;
1145
							}
1146
						}
1147 2
					}
1148 2
				} elseif (0 === (int) $row['permission'] && 3 === $modDefOrgShare) {
1149 2
					if (!isset($grpReadPer[$shareGrpId])) {
1150
						$usersByGroup = static::getUsersByGroup($shareGrpId, true);
1151
						$grpReadPer[$shareGrpId] = $usersByGroup['users'];
1152
						foreach ($usersByGroup['subGroups'] as $subgrpid => $subgrpusers) {
1153
							if (!isset($grpReadPer[$subgrpid])) {
1154
								$grpReadPer[$subgrpid] = $subgrpusers;
1155
							}
1156
							if (!\in_array($subgrpid, $shareIdGrps)) {
1157
								$shareIdGrps[] = $subgrpid;
1158
							}
1159
						}
1160 5778
					}
1161
				}
1162 5778
				$shareIdMembers[$row['shareid']] = ['GROUP' => $shareIdGrps];
1163 5767
			}
1164
			//Get roles from Us2Us
1165 14
			foreach (static::getDatashare('user2user', $modTabId, $userid) as $row) {
1166 14
				$shareUserId = (int) $row['share_userid'];
1167 14
				$shareIdUsers = [];
1168 14
				$shareIdUsers[] = $shareUserId;
1169 14
				if (1 === (int) $row['permission']) {
1170 14
					if (3 === $modDefOrgShare && !isset($grpReadPer[$shareUserId])) {
1171 14
						$grpReadPer[$shareUserId] = [$shareUserId];
1172 14
					}
1173 14
					if (!isset($grpWritePer[$shareUserId])) {
1174 13
						$grpWritePer[$shareUserId] = [$shareUserId];
1175
					}
1176 14
				} elseif (0 === (int) $row['permission'] && 3 === $modDefOrgShare) {
1177
					if (!isset($grpReadPer[$shareUserId])) {
1178
						$grpReadPer[$shareUserId] = [$shareUserId];
1179 14
					}
1180
				}
1181 14
				$shareIdMembers[$row['shareid']] = ['GROUP' => $shareIdUsers];
1182
			}
1183
			//Get roles from Us2Grp
1184
			foreach (static::getDatashare('user2group', $modTabId, $groupList) as $row) {
1185
				$shareUserId = (int) $row['share_userid'];
1186
				$shareIdUsers = [];
1187
				$shareIdUsers[] = $shareUserId;
1188
				if (1 === (int) $row['permission']) {
1189
					if (3 === $modDefOrgShare && !isset($grpReadPer[$shareUserId])) {
1190
						$grpReadPer[$shareUserId] = [$shareUserId];
1191
					}
1192 13
					if (!isset($grpWritePer[$shareUserId])) {
1193
						$grpWritePer[$shareUserId] = [$shareUserId];
1194 13
					}
1195 13
				} elseif (0 === (int) $row['permission'] && 3 === $modDefOrgShare) {
1196 13
					if (!isset($grpReadPer[$shareUserId])) {
1197 13
						$grpReadPer[$shareUserId] = [$shareUserId];
1198
					}
1199
				}
1200
				$shareIdMembers[$row['shareid']] = ['GROUP' => $shareIdUsers];
1201
			}
1202
			//Get roles from Us2role
1203 13
			foreach (static::getDatashare('user2role', $modTabId, $currentUserRoles) as $row) {
1204
				$shareUserId = (int) $row['share_userid'];
1205
				$shareIdUsers = [];
1206
				$shareIdUsers[] = $shareUserId;
1207
				if (1 === (int) $row['permission']) {
1208
					if (3 === $modDefOrgShare && !isset($grpReadPer[$shareUserId])) {
1209
						$grpReadPer[$shareUserId] = [$shareUserId];
1210
					}
1211
					if (!isset($grpWritePer[$shareUserId])) {
1212
						$grpWritePer[$shareUserId] = [$shareUserId];
1213
					}
1214
				} elseif (0 === (int) $row['permission'] && 3 === $modDefOrgShare) {
1215
					if (!isset($grpReadPer[$shareUserId])) {
1216
						$grpReadPer[$shareUserId] = [$shareUserId];
1217
					}
1218
				}
1219
1220
				$shareIdMembers[$row['shareid']] = ['GROUP' => $shareIdUsers];
1221
			}
1222
			//Get roles from Us2rs
1223
			foreach (static::getDatashare('user2rs', $modTabId, $parRoleList) as $row) {
1224
				$shareUserId = (int) $row['share_userid'];
1225
				$shareIdUsers = [];
1226
				$shareIdUsers[] = $shareUserId;
1227
				if (1 === (int) $row['permission']) {
1228
					if (3 === $modDefOrgShare && !isset($grpReadPer[$shareUserId])) {
1229
						$grpReadPer[$shareUserId] = [$shareUserId];
1230
					}
1231
					if (!isset($grpWritePer[$shareUserId])) {
1232
						$grpWritePer[$shareUserId] = [$shareUserId];
1233
					}
1234
				} elseif (0 === (int) $row['permission'] && 3 === $modDefOrgShare) {
1235
					if (!isset($grpReadPer[$shareUserId])) {
1236
						$grpReadPer[$shareUserId] = [$shareUserId];
1237
					}
1238
				}
1239
				$shareIdMembers[$row['shareid']] = ['GROUP' => $shareIdUsers];
1240
			}
1241
			$modShareReadPermission['GROUP'] = $grpReadPer;
1242
			$modShareWritePermission['GROUP'] = $grpWritePer;
1243
		}
1244
		return [
1245
			'read' => $modShareReadPermission,
1246
			'write' => $modShareWritePermission,
1247
			'sharingrules' => $shareIdMembers,
1248
		];
1249
	}
1250
1251
	/**
1252
	 * Get all groups by user id.
1253
	 *
1254
	 * @param int $userId
1255
	 *
1256
	 * @return int[]
1257
	 */
1258
	public static function getAllGroupsByUser($userId)
1259
	{
1260
		if (Cache::has('getAllGroupsByUser', $userId)) {
1261
			return Cache::get('getAllGroupsByUser', $userId);
1262
		}
1263
		$userGroups = static::getUserGroups($userId);
1264
		$userRole = static::getRoleByUsers($userId);
1265
		$roleGroups = (new \App\Db\Query())->select(['groupid'])->from('vtiger_group2role')->where(['roleid' => $userRole])->column();
1266
		$roles = static::getParentRole($userRole);
1267
		$roles[] = $userRole;
1268
		$rsGroups = (new \App\Db\Query())->select(['groupid'])->from('vtiger_group2rs')->where(['roleandsubid' => $roles])->column();
1269
		$allGroups = array_unique(array_merge($userGroups, $roleGroups, $rsGroups));
1270
		$parentGroups = [];
1271
		foreach ($allGroups as $groupId) {
1272
			$parentGroups = array_merge($parentGroups, static::getParentGroups($groupId));
1273
		}
1274
		if ($parentGroups) {
1275
			$allGroups = array_unique(array_merge($allGroups, $parentGroups));
1276
		}
1277
		Cache::save('getAllGroupsByUser', $userId, $allGroups, Cache::LONG);
1278
1279
		return $allGroups;
1280
	}
1281
1282
	/**
1283
	 * Get parent grioups by group id.
1284
	 *
1285
	 * @param int $groupId
1286
	 * @param int $i
1287
	 *
1288
	 * @return int[]
1289
	 */
1290
	public static function getParentGroups($groupId, $i = 0)
1291
	{
1292
		$groups = [];
1293 4
		if ($i < 10) {
1294
			$dataReader = (new \App\Db\Query())->select(['groupid'])->from('vtiger_group2grouprel')->where(['containsgroupid' => $groupId])->createCommand()->query();
1295 4
			while ($parentGroupId = $dataReader->readColumn(0)) {
1296 4
				$groups = array_merge($groups, [$parentGroupId], static::getParentGroups($parentGroupId, $i++));
1297 4
			}
1298 4
		} else {
1299 4
			Log::warning('Exceeded the recursive limit, a loop might have been created. Group ID:' . $groupId);
1300 4
		}
1301 4
		return $groups;
1302 4
	}
1303
1304 4
	/**
1305 4
	 * Creates a query to all groups where the user is a member..
1306
	 *
1307
	 * @param int $userId
1308 4
	 *
1309
	 * @return Db\Query
1310 4
	 */
1311 4
	public static function getQueryToGroupsByUserId(int $userId): Db\Query
1312
	{
1313
		return (new \App\Db\Query())->select(['groupid'])->from('vtiger_groups')->where(['groupid' => self::getAllGroupsByUser($userId)]);
1314
	}
1315
1316
	/**
1317
	 * Returns the leaders of the groups where the user is a member.
1318 1
	 *
1319
	 * @param int $userId
1320 1
	 *
1321 1
	 * @return array
1322
	 */
1323
	public static function getLeadersGroupByUserId(int $userId): array
1324
	{
1325
		$db = \App\Db::getInstance();
1326
		$query = self::getQueryToGroupsByUserId($userId)->andWhere(['<>', 'parentid', 0])->andWhere(['not', ['parentid' => null]]);
1327
		$member = new \yii\db\Expression('CASE WHEN vtiger_users.id IS NOT NULL THEN CONCAT(' . $db->quoteValue(self::MEMBER_TYPE_USERS) . ',\':\', parentid) ELSE CONCAT(' . $db->quoteValue(self::MEMBER_TYPE_GROUPS) . ',\':\', parentid) END');
1328
		$query->select(['groupid', 'member' => $member])->leftJoin('vtiger_users', 'vtiger_groups.parentid=vtiger_users.id');
1329 1
1330
		return $query->createCommand()->queryAllByGroup(0);
1331 1
	}
1332 1
1333 1
	/**
1334 1
	 * Returns groups whose leader is the user.
1335 1
	 *
1336 1
	 * @param int $userId
1337 1
	 *
1338
	 * @return array
1339
	 */
1340
	public static function getGroupsWhereUserIsLeader(int $userId): array
1341
	{
1342
		return (new \App\Db\Query())->select(['groupid'])->from('vtiger_groups')->where(['or', ['parentid' => $userId], ['parentid' => self::getQueryToGroupsByUserId($userId)]])->column();
1343
	}
1344 1
1345 1
	/**
1346 1
	 * Tables to sharing rules.
1347
	 *
1348
	 * @var array
1349
	 */
1350
	private static $shareRulesTables = [
1351
		'US::GRP' => 'vtiger_datashare_us2grp',
1352
		'US::ROLE' => 'vtiger_datashare_us2role',
1353 1
		'US::RS' => 'vtiger_datashare_us2rs',
1354 1
		'US::US' => 'vtiger_datashare_us2us',
1355 1
		'GRP::GRP' => 'vtiger_datashare_grp2grp',
1356 1
		'GRP::ROLE' => 'vtiger_datashare_grp2role',
1357
		'GRP::RS' => 'vtiger_datashare_grp2rs',
1358
		'GRP::US' => 'vtiger_datashare_grp2us',
1359
		'ROLE::GRP' => 'vtiger_datashare_role2group',
1360
		'ROLE::ROLE' => 'vtiger_datashare_role2role',
1361
		'ROLE::RS' => 'vtiger_datashare_role2rs',
1362
		'ROLE::US' => 'vtiger_datashare_role2us',
1363
		'RS::GRP' => 'vtiger_datashare_rs2grp',
1364 1
		'RS::ROLE' => 'vtiger_datashare_rs2role',
1365 1
		'RS::RS' => 'vtiger_datashare_rs2rs',
1366
		'RS::US' => 'vtiger_datashare_rs2us',
1367
	];
1368
1369
	/**
1370
	 * List tables where sharing rules are save for users, groups and roles.
1371
	 *
1372
	 * @var array
1373
	 */
1374
	private static $shareRulesTablesIndex = [
1375
		'Users' => [
1376
			'vtiger_datashare_us2us' => 'share_userid::to_userid',
1377
			'vtiger_datashare_us2grp' => 'share_userid',
1378
			'vtiger_datashare_us2role' => 'share_userid',
1379
			'vtiger_datashare_us2rs' => 'share_userid',
1380
			'vtiger_datashare_grp2us' => 'to_userid',
1381
			'vtiger_datashare_rs2us' => 'to_userid',
1382
			'vtiger_datashare_role2us' => 'to_userid',
1383
		],
1384
		'Roles' => [
1385
			'vtiger_datashare_us2role' => 'to_roleid',
1386
			'vtiger_datashare_us2rs' => 'to_roleandsubid',
1387
			'vtiger_datashare_grp2role' => 'to_roleid',
1388
			'vtiger_datashare_grp2rs' => 'to_roleandsubid',
1389 1
			'vtiger_datashare_role2group' => 'share_roleid',
1390
			'vtiger_datashare_role2us' => 'share_roleid',
1391
			'vtiger_datashare_role2role' => 'share_roleid::to_roleid',
1392 1
			'vtiger_datashare_role2rs' => 'share_roleid::to_roleandsubid',
1393
			'vtiger_datashare_rs2grp' => 'share_roleandsubid',
1394
			'vtiger_datashare_rs2us' => 'share_roleandsubid',
1395
			'vtiger_datashare_rs2role' => 'share_roleandsubid::to_roleid',
1396
			'vtiger_datashare_rs2rs' => 'share_roleandsubid::to_roleandsubid',
1397
		],
1398
		'Groups' => [
1399
			'vtiger_datashare_grp2grp' => 'share_groupid::to_groupid',
1400
			'vtiger_datashare_grp2role' => 'share_groupid',
1401
			'vtiger_datashare_grp2rs' => 'share_groupid',
1402
			'vtiger_datashare_grp2us' => 'share_groupid',
1403
			'vtiger_datashare_role2group' => 'to_groupid',
1404
			'vtiger_datashare_rs2grp' => 'to_groupid',
1405
			'vtiger_datashare_us2grp' => 'to_groupid',
1406
		],
1407
	];
1408
1409
	/**
1410
	 * This function is to delete the organisation level sharing rule
1411
	 * It takes the following input parameters:.
1412
	 *
1413
	 * @param int $shareid Id of the Sharing Rule to be updated
1414
	 */
1415
	private static function deleteSharingRule($shareid)
1416
	{
1417
		Log::trace('Entering deleteSharingRule(' . $shareid . ') method ...');
1418
		$dbCommand = Db::getInstance()->createCommand();
1419
		$typestr = (new Db\Query())->select(['relationtype'])->from('vtiger_datashare_module_rel')->where(['shareid' => $shareid])->scalar();
1420
		$dbCommand->delete(static::$shareRulesTables[$typestr], ['shareid' => $shareid])->execute();
0 ignored issues
show
Bug introduced by
Since $shareRulesTables is declared private, accessing it with static will lead to errors in possible sub-classes; you can either use self, or increase the visibility of $shareRulesTables to at least protected.
Loading history...
1421
		$dbCommand->delete('vtiger_datashare_module_rel', ['shareid' => $shareid])->execute();
1422
		$dbCommand->delete('vtiger_datashare_relatedmodule_permission', ['shareid' => $shareid])->execute();
1423
		Log::trace('Exiting deleteSharingRule method ...');
1424
	}
1425
1426
	/**
1427
	 * Function to remove sharing rules from tables.
1428
	 *
1429
	 * @param int|string $id
1430
	 * @param string     $type
1431
	 */
1432
	public static function deleteRelatedSharingRules($id, $type)
1433
	{
1434
		Log::trace('Entering deleteRelatedSharingRules(' . $id . ') method ...');
1435
		foreach (static::$shareRulesTablesIndex[$type] as $tablename => $colname) {
0 ignored issues
show
Bug introduced by
Since $shareRulesTablesIndex is declared private, accessing it with static will lead to errors in possible sub-classes; you can either use self, or increase the visibility of $shareRulesTablesIndex to at least protected.
Loading history...
1436
			$colNameArr = explode('::', $colname);
1437
			$query = (new Db\Query())->select(['shareid'])
1438
				->from($tablename)
1439
				->where([$colNameArr[0] => $id]);
1440
			if (isset($colNameArr[1])) {
1441
				$query->orWhere([$colNameArr[1] => $id]);
1442
			}
1443
			$dataReader = $query->createCommand()->query();
1444
			while ($shareid = $dataReader->readColumn(0)) {
1445
				static::deleteSharingRule($shareid);
1446
			}
1447
			$dataReader->close();
1448
		}
1449
		Log::trace('Exiting deleteRelatedSharingRules method ...');
1450
	}
1451
1452
	/**
1453
	 * Function for test to check privilege utils.
1454
	 *
1455
	 * @param int $recordId
1456
	 */
1457
	public static function testPrivileges($recordId)
1458
	{
1459
		static::getHelpDeskRelatedAccounts($recordId);
1460
		return true;
1461
	}
1462
1463
	/**
1464
	 * Recalculate sharing rules by user id.
1465
	 *
1466
	 * @param int $id
1467
	 */
1468
	public static function recalculateSharingRulesByUser($id)
1469
	{
1470
		$userModel = \App\User::getUserModel($id);
1471
		if (!$userModel->getId()) {
1472
			return null;
1473
		}
1474
		$roles = explode('::', $userModel->getParentRolesSeq());
1475
		$groups = $userModel->getGroups();
1476
		$sharing = [];
1477
		foreach (\Settings_SharingAccess_Rule_Model::$dataShareTableColArr['ROLE'] as $key => $item) {
1478
			$row = (new \App\Db\Query())->select([$item['target_id']])->from($item['table'])->where([$item['source_id'] => $roles])->column();
1479
			if ($row) {
1480
				if (!isset($sharing[$key])) {
1481
					$sharing[$key] = [];
1482
				}
1483
				$sharing[$key] = array_merge($sharing[$key], $row);
1484
			}
1485
		}
1486
		foreach (\Settings_SharingAccess_Rule_Model::$dataShareTableColArr['RS'] as $key => $item) {
1487
			$row = (new \App\Db\Query())->select([$item['target_id']])->from($item['table'])->where([$item['source_id'] => $roles])->column();
1488
			if ($row) {
1489
				if (!isset($sharing[$key])) {
1490
					$sharing[$key] = [];
1491
				}
1492
				$sharing[$key] = array_merge($sharing[$key], $row);
1493
			}
1494
		}
1495
		if ($groups) {
1496
			foreach (\Settings_SharingAccess_Rule_Model::$dataShareTableColArr['GRP'] as $key => $item) {
1497
				$row = (new \App\Db\Query())->select([$item['target_id']])->from($item['table'])->where([$item['source_id'] => $groups])->column();
1498
				if ($row) {
1499
					if (!isset($sharing[$key])) {
1500
						$sharing[$key] = [];
1501
					}
1502
					$sharing[$key] = array_merge($sharing[$key], $row);
1503
				}
1504
			}
1505
		}
1506
		$users = [[]];
1507
		foreach ($sharing as $type => $item) {
1508
			switch ($type) {
1509
				case 'US':
1510
					$users[] = array_unique($item);
1511
					break;
1512
				case 'GRP':
1513
					foreach ($item as $grpId) {
1514
						$users[] = static::getUsersByGroup($grpId);
1515
					}
1516
					break;
1517
				case 'ROLE':
1518
					foreach ($item as $roleId) {
1519
						$users[] = static::getUsersByRole($roleId);
1520
					}
1521
					break;
1522
				case 'RS':
1523
					foreach ($item as $roleId) {
1524
						$users[] = static::getUsersByRoleAndSubordinate($roleId);
1525
					}
1526
					break;
1527
				default:
1528
					break;
1529
			}
1530
		}
1531
		foreach (array_unique(array_merge(...$users)) as $userId) {
1532
			UserPrivilegesFile::createUserSharingPrivilegesfile($userId);
1533
		}
1534
	}
1535
1536
	/**
1537
	 * Modify permissions for actions and views.
1538
	 *
1539
	 * @param string $moduleName
1540
	 * @param array  $actions
1541
	 * @param bool   $mode       true: add, false: remove
1542
	 *
1543
	 * @return bool
1544
	 */
1545
	public static function modifyPermissions(string $moduleName, array $actions, bool $mode): bool
1546
	{
1547
		$dbCommand = \App\Db::getInstance()->createCommand();
1548
		$result = false;
1549
		$tabId = Module::getModuleId($moduleName);
1550
		$actions = array_diff($actions, array_merge(\Vtiger_Action_Model::$nonConfigurableActions, \Vtiger_Action_Model::$standardActions));
1551
		$actionIds = array_filter(array_map('\App\Module::getActionId', $actions));
1552
		if ($mode) {
1553
			$profilesByAction = (new Db\Query())->select(['profileid', 'activityid'])
1554
				->from('vtiger_profile2utility')
1555
				->where(['tabid' => $tabId, 'activityid' => $actionIds])->createCommand()->queryAllByGroup(2);
1556
			foreach (\vtlib\Profile::getAllIds() as $profileId) {
1557
				$add = !isset($profilesByAction[$profileId]) ? $actionIds : array_diff($actionIds, $profilesByAction[$profileId]);
1558
				foreach ($add as $actionId) {
1559
					$result = $dbCommand->insert('vtiger_profile2utility', ['profileid' => $profileId, 'tabid' => $tabId, 'activityid' => $actionId, 'permission' => 1])->execute() || $result;
1560
				}
1561
			}
1562
		} else {
1563
			$result = $dbCommand->delete('vtiger_profile2utility', ['tabid' => $tabId, 'activityid' => $actionIds])->execute();
1564
		}
1565
		return $result;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $result could return the type integer which is incompatible with the type-hinted return boolean. Consider adding an additional type-check to rule them out.
Loading history...
1566
	}
1567
1568
	/**
1569
	 * Check if element exists in organization structure.
1570
	 *
1571
	 * @param int|string $member
1572
	 *
1573
	 * @return bool
1574
	 */
1575
	public static function isExists($member): bool
1576
	{
1577
		$type = is_numeric($member) ? \App\Fields\Owner::getType($member) : 'Roles';
1578
		switch ($type) {
1579
			case 'Users':
1580
				$exists = \App\User::isExists($member);
1581
				break;
1582
			case 'Groups':
1583
				$exists = (new \App\Db\Query())->from('vtiger_groups')->where(['groupid' => $member])->exists();
1584
				break;
1585
			case 'Roles':
1586
				$exists = !empty(self::getRoleDetail($member));
1587
				break;
1588
			default:
1589
				$exists = false;
1590
				break;
1591
		}
1592
1593
		return $exists;
1594
	}
1595
}
1596