1<?php
2/**
3 * @package tikiwiki
4 */
5// (c) Copyright by authors of the Tiki Wiki CMS Groupware Project
6//
7// All Rights Reserved. See copyright.txt for details and a complete list of authors.
8// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details.
9// $Id$
10
11$inputConfiguration = [
12	[
13		'staticKeyFilters' => [
14			'groupstracker'             => 'int',
15			'groupfield'                => 'int',
16			'userstracker'              => 'int',
17			'usersfield'                => 'int',
18			'registrationUsersFieldIds' => 'digitscolons',
19			'watch'                     => 'striptags',
20			'unwatch'                   => 'striptags',
21			'home'                      => 'pagename',
22			'defcat'                    => 'int',
23			'theme'                     => 'themename',
24			'color'                     => 'striptags',
25			'maxRecords'                => 'int',
26			'membersMax'                => 'int',
27			'bannedMax'                 => 'int',
28			'sort_mode'                 => 'alnumdash',
29			'sort_mode_member'          => 'alnumdash',
30			'bannedSort'                => 'alnumdash',
31			'offset'                    => 'int',
32			'membersOffset'             => 'int',
33			'bannedOffset'              => 'int',
34			'initial'                   => 'alpha',
35			'find'                      => 'groupname',
36			'group'                     => 'groupname',
37		]
38	]
39];
40
41require_once('tiki-setup.php');
42$access->check_permission('tiki_p_admin');
43
44$auto_query_args = ['group'];
45
46if (! isset($cookietab)) {
47	$cookietab = '1';
48}
49list($trackers, $ag_utracker, $ag_ufield, $ag_gtracker, $ag_gfield, $ag_rufields) = [[] ,	0, 0, 0, 0, ''];
50if (isset($prefs['groupTracker']) and $prefs['groupTracker'] == 'y') {
51	$trklib = TikiLib::lib('trk');
52	$trackerlist = $trklib->list_trackers(0, -1, 'name_asc', '');
53	$trackers = $trackerlist['list'];
54	if (isset($_REQUEST["groupstracker"]) and isset($trackers[$_REQUEST["groupstracker"]])) {
55		$ag_gtracker = $_REQUEST["groupstracker"];
56		if (isset($_REQUEST["groupfield"]) and $_REQUEST["groupfield"]) {
57			$ag_gfield = $_REQUEST["groupfield"];
58		}
59	}
60}
61if (isset($prefs['userTracker']) and $prefs['userTracker'] == 'y') {
62	$trklib = TikiLib::lib('trk');
63	if (! isset($trackerlist)) {
64		$trackerlist = $trklib->list_trackers(0, -1, 'name_asc', '');
65	}
66	$trackers = $trackerlist['list'];
67	if (isset($_REQUEST["userstracker"]) and isset($trackers[$_REQUEST["userstracker"]])) {
68		$ag_utracker = $_REQUEST["userstracker"];
69		if (isset($_REQUEST["usersfield"]) and $_REQUEST["usersfield"]) {
70			$ag_ufield = $_REQUEST["usersfield"];
71		}
72		if (! empty($_REQUEST['registrationUsersFieldIds'])) {
73			$ag_rufields = $_REQUEST['registrationUsersFieldIds'];
74		}
75	}
76}
77$smarty->assign('trackers', $trackers);
78
79if ($prefs['feature_user_watches'] == 'y') {
80	if (! empty($user)) {
81		$tikilib = TikiLib::lib('tiki');
82		if (isset($_REQUEST['watch']) && $access->checkOrigin()) {
83			$tikilib->add_user_watch($user, 'user_joins_group', $_REQUEST['watch'], 'group');
84		} elseif (isset($_REQUEST['unwatch']) && $access->checkOrigin()) {
85			$tikilib->remove_user_watch($user, 'user_joins_group', $_REQUEST['unwatch'], 'group');
86		}
87	}
88}
89
90$ag_home = '';
91$ag_defcat = 0;
92$ag_theme = '';
93if (isset($_REQUEST["home"])) {
94	$ag_home = $_REQUEST["home"];
95}
96if (! empty($_REQUEST["defcat"])) {
97	$ag_defcat = $_REQUEST["defcat"];
98}
99if (isset($_REQUEST["theme"])) {
100	$ag_theme = $_REQUEST["theme"];
101}
102
103if (isset($_REQUEST['clean']) && $access->checkOrigin()) {
104	$cachelib = TikiLib::lib('cache');
105	check_ticket('admin-groups');
106	$cachelib->invalidate('grouplist');
107	$cachelib->invalidate('groupIdlist');
108}
109if (! isset($_REQUEST['maxRecords'])) {
110	$numrows = $maxRecords;
111} else {
112	$numrows = $_REQUEST['maxRecords'];
113}
114$smarty->assign_by_ref('maxRecords', $numrows);
115if (! isset($_REQUEST["sort_mode"])) {
116	$sort_mode = 'groupName_asc';
117} else {
118	$sort_mode = $_REQUEST["sort_mode"];
119}
120$smarty->assign_by_ref('sort_mode', $sort_mode);
121if (! isset($_REQUEST["offset"])) {
122	$offset = 0;
123} else {
124	$offset = $_REQUEST["offset"];
125}
126$smarty->assign_by_ref('offset', $offset);
127if (isset($_REQUEST["initial"])) {
128	$initial = $_REQUEST["initial"];
129} else {
130	$initial = '';
131}
132$smarty->assign('initial', $initial);
133if (isset($_REQUEST["find"])) {
134	$find = $_REQUEST["find"];
135} else {
136	$find = '';
137}
138$smarty->assign('find', $find);
139$users = $userlib->get_groups($offset, $numrows, $sort_mode, $find, $initial);
140
141//add tablesorter sorting and filtering for main group list
142$ts = Table_Check::setVars('admingroups', true);
143if ($ts['enabled'] && ! $ts['ajax']) {
144	//set tablesorter code
145	Table_Factory::build('TikiAdminGroups', ['id' => $ts['tableid'], 'total' => $users['cant']]);
146}
147
148$inc = [];
149list(	$groupname, $groupdesc, $grouphome, $userstrackerid, $usersfieldid, $grouptrackerid,
150		$groupfieldid, $defcatfieldid, $themefieldid, $groupperms, $trackerinfo, $memberslist,
151		$userChoice, $groupdefcat, $grouptheme, $expireAfter, $emailPattern, $anniversary, $prorateInterval, $isRole, $isTplGroup) =
152		['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''];
153
154if (! empty($_REQUEST["group"])) {
155	$re = $userlib->get_group_info($_REQUEST["group"]);
156	if (isset($re["groupName"])) {
157		$groupname = $re["groupName"];
158	}
159	if (isset($re["groupDesc"])) {
160		$groupdesc = $re["groupDesc"];
161	}
162	if (isset($re["groupHome"])) {
163		$grouphome = $re["groupHome"];
164	}
165	if (isset($re["groupDefCat"])) {
166		$groupdefcat = $re["groupDefCat"];
167	}
168	if (isset($re["groupTheme"])) {
169		$grouptheme = $re["groupTheme"];
170	}
171	if (isset($re["groupColor"])) {
172		$groupcolor = $re["groupColor"];
173	}
174	if (isset($re['userChoice'])) {
175		$userChoice = $re['userChoice'];
176	}
177	if (isset($re['expireAfter'])) {
178		$expireAfter = $re['expireAfter'];
179	}
180	if (isset($re['anniversary'])) {
181		$anniversary = $re['anniversary'];
182	}
183	if (isset($re['prorateInterval'])) {
184		$prorateInterval = $re['prorateInterval'];
185	}
186	if (isset($re['isRole'])) {
187		$isRole = $re['isRole'];
188	}
189	if (isset($re['isTplGroup'])) {
190		$isTplGroup = $re['isTplGroup'];
191	}
192	if ($prefs['userTracker'] == 'y') {
193		if (isset($re["usersTrackerId"]) and $re["usersTrackerId"]) {
194			$trklib = TikiLib::lib('trk');
195			$userstrackerid = $re["usersTrackerId"];
196			$smarty->assign('userstrackerid', $userstrackerid);
197			$usersFields = $trklib->list_tracker_fields($userstrackerid, 0, -1, 'position_asc', '');
198			$smarty->assign_by_ref('usersFields', $usersFields['data']);
199			if (isset($re["usersFieldId"]) and $re["usersFieldId"]) {
200				$usersfieldid = $re["usersFieldId"];
201				$smarty->assign('usersfieldid', $usersfieldid);
202			}
203		}
204		! empty($re['registrationUsersFieldIds'])
205			? $smarty->assign('registrationUsersFieldIds', $re['registrationUsersFieldIds'])
206			: $smarty->assign('registrationUsersFieldIds', '');
207	}
208	if ($prefs['groupTracker'] == 'y') {
209		$groupFields = [];
210		if (isset($re["groupTrackerId"]) and $re["groupTrackerId"]) {
211			$trklib = TikiLib::lib('trk');
212			$grouptrackerid = $re["groupTrackerId"];
213			$smarty->assign('grouptrackerid', $grouptrackerid);
214			$groupFields = $trklib->list_tracker_fields($grouptrackerid, 0, -1, 'position_asc', '');
215			$smarty->assign_by_ref('groupFields', $groupFields['data']);
216			if (isset($re["groupFieldId"]) and $re["groupFieldId"]) {
217				$groupfieldid = $re["groupFieldId"];
218				$smarty->assign('groupfieldid', $groupfieldid);
219				$groupitemid = $trklib->get_item_id($grouptrackerid, $groupfieldid, $groupname);
220				$smarty->assign('groupitemid', $groupitemid);
221			}
222		}
223	}
224	$groupperms = $re["perms"];
225	//$allgroups = $userlib->list_all_groups();
226	$allgroups = $userlib->list_can_include_groups($re["groupName"]);
227	$rs = $userlib->get_included_groups($_REQUEST['group'], false);
228	foreach ($allgroups as $rr) {
229		$inc["$rr"] = "n";
230		if (in_array($rr, $rs)) {
231			$inc["$rr"] = "y";
232			$smarty->assign('hasOneIncludedGroup', "y");
233		}
234	}
235
236	//group members
237	if (! isset($_REQUEST['membersOffset'])) {
238		$_REQUEST['membersOffset'] = 0;
239	}
240	if (empty($_REQUEST['sort_mode_member'])) {
241		$_REQUEST['sort_mode_member'] = 'login_asc';
242	}
243	$membersMax = isset($_REQUEST['membersMax']) && is_numeric($_REQUEST['membersMax'])
244		? $_REQUEST['membersMax'] : $prefs['maxRecords'];
245	$memberslist = $userlib->get_group_users(
246		$_REQUEST['group'],
247		$_REQUEST['membersOffset'],
248		$membersMax,
249		'*',
250		$_REQUEST['sort_mode_member']
251	);
252	if ($re['expireAfter'] > 0) {
253		foreach ($memberslist as $i => $member) {
254			if (empty($member['expire'])) {
255				$memberslist[$i]['expire'] = $member['created'] + ($re['expireAfter'] * 24 * 60 * 60);
256			}
257		}
258	}
259	$membersCount = $userlib->count_users($_REQUEST['group']);
260	$smarty->assign('membersCount', $membersCount);
261	$smarty->assign('membersOffset', $_REQUEST['membersOffset']);
262	$smarty->assign('memberslist', $memberslist);
263
264	//banned members of a group
265	$bannedOffset = isset($_REQUEST['bannedOffset']) ? $_REQUEST['bannedOffset'] : 0;
266	$bannedMax = isset($_REQUEST['bannedMax']) ? $_REQUEST['bannedMax'] : $prefs['maxRecords'];
267	if (empty($_REQUEST['bannedSort'])) {
268		$bannedSort = ['source_itemId' => 'asc'];
269	} elseif (! empty($_REQUEST['bannedSort']) && substr($_REQUEST['bannedSort'], -4) === 'desc') {
270		$bannedSort = ['source_itemId' => 'desc'];
271	} else {
272		$bannedSort = ['source_itemId' => 'asc'];
273	}
274	$bannedlist = $userlib->get_group_banned_users($_REQUEST['group'], $bannedOffset, $bannedMax, null, $bannedSort);
275	$smarty->assign('bannedlist', $bannedlist['data']);
276	$smarty->assign('bannedCount', $bannedlist['cant']);
277
278	$userslist = $userlib->list_all_users();
279	if (! empty($memberslist)) {
280		foreach ($memberslist as $key => $values) {
281			if (in_array($values["login"], $userslist)) {
282				unset($userslist[array_search($values["login"], $userslist, true)]);
283			}
284		}
285		foreach ($bannedlist as $key => $value) {
286			if (in_array($value, $userslist)) {
287				unset($userslist[array_search($value, $userslist, true)]);
288			}
289		}
290	}
291	$smarty->assign('userslist', $userslist);
292
293	if ($ts['enabled'] && ! $ts['ajax']) {
294		Table_Factory::build(
295			'TikiAdminGroupsMembers',
296			[
297				'id' => 'groupsMembers',
298				'total' => $membersCount,
299				'ajax' => [
300					'requiredparams' => [
301						'group' => $_REQUEST['group']
302					]
303				]
304			]
305		);
306		Table_Factory::build(
307			'TikiAdminGroupsBanned',
308			[
309				'id' => 'bannedMembers',
310				'total' => $bannedlist['cant'],
311				'ajax' => [
312					'requiredparams' => [
313						'group' => $_REQUEST['group']
314					]
315				]
316			]
317		);
318	}
319
320	if (! empty($user)) {
321		 $re['isWatching'] = TikiLib::lib('tiki')->user_watches($user, 'user_joins_group', $groupname, 'group') > 0;
322	} else {
323		 $re['isWatching'] = false;
324	}
325	$cookietab = "2";
326} else {
327	$allgroups = $userlib->list_all_groups();
328	foreach ($allgroups as $rr) {
329		$inc["$rr"] = "n";
330	}
331	$_REQUEST["group"] = 0;
332}
333if (isset($_REQUEST['add'])) {
334	$cookietab = "2";
335}
336if (! empty($_REQUEST['group']) && isset($_REQUEST['export'])) {
337	$users = $userlib->get_users(0, -1, 'login_asc', '', '', false, $_REQUEST['group']);
338	$smarty->assign_by_ref('users', $users['data']);
339	$listfields = [];
340	if (isset($_REQUEST['username'])) {
341		$listfields[] = 'user';
342	}
343	if (isset($_REQUEST['email'])) {
344		$listfields[] = 'email';
345	}
346	if (isset($_REQUEST['lastLogin'])) {
347		$listfields[] = 'lastLogin';
348	}
349	$smarty->assign_by_ref('listfields', $listfields);
350	$data = $smarty->fetch('tiki-export_users.tpl');
351	if (! empty($_REQUEST['encoding']) && $_REQUEST['encoding'] == 'ISO-8859-1') {
352		$data = utf8_decode($data);
353	} else {
354		$_REQUEST['encoding'] = "UTF-8";
355	}
356	header("Content-type: text/comma-separated-values; charset:" . $_REQUEST['encoding']);
357	header("Content-Disposition: attachment; filename=" . tra('users') . "_" . $_REQUEST['group'] . ".csv");
358	header("Expires: 0");
359	header("Cache-Control: must-revalidate, post-check=0,pre-check=0");
360	header("Pragma: public");
361	echo $data;
362	die;
363}
364if (! empty($_REQUEST['group']) && isset($_REQUEST['import']) && $access->checkOrigin()) {
365	$fname = $_FILES['csvlist']['tmp_name'];
366	$fhandle = fopen($fname, 'r');
367	$fields = fgetcsv($fhandle, 1000);
368	if (! $fields[0]) {
369		Feedback::error(tr('The file has incorrect syntax or is not a CSV file'));
370		$cookietab = 5; // import/export members tab
371	} elseif ($fields[0] != 'user') {
372		Feedback::error(tr('The file does not have the required header:') . ' user');
373		$cookietab = 5; // import/export members tab
374	} else {
375		$successes = [];
376		$errors = [];
377		$data = @fgetcsv($fhandle, 1000);
378		while ($data != false) {
379			if (function_exists("mb_detect_encoding") && mb_detect_encoding($data[0], "ASCII, UTF-8, ISO-8859-1") == "ISO-8859-1") {
380				$data[0] = utf8_encode($data[0]);
381			}
382			$data[0] = trim($data[0]);
383			if (! $userlib->user_exists($data[0])) {
384				$errors[] = $data[0];
385			} else {
386				$res = $userlib->assign_user_to_group($data[0], $_REQUEST['group']);
387				if ($res) {
388					$successes[] = $data[0];
389				}
390			}
391			$data = fgetcsv($fhandle, 1000);
392		}
393		// feedback
394		if (! empty($successes)) {
395			$mes = count($successes) === 1 ? tr('The following user has been added to group %0:', htmlspecialchars($_REQUEST['group'])) :
396				tr('The following users have been added to group %0:', $_REQUEST['group']);
397			Feedback::success(['mes' => $mes, 'items' => $successes, 'tpl' => 'action']);
398		} else {
399			Feedback::note(tr('No users added to group %0', htmlspecialchars($_REQUEST['group'])));
400		}
401		if (! empty($errors)) {
402			$mes = count($errors) === 1 ? tr('The following user does not exist:') :
403				tr('The following users do not exist:');
404			Feedback::error(['mes' => $mes, 'items' => $errors, 'tpl' => 'action']);
405		}
406		// return to page
407		//$cookietab = 3;
408		// redirect to members list tab. Simply setting the $cookietab variable doesn't show refreshed list of
409		// group members for some reason
410		$access->redirect('tiki-admingroups.php?group=' . $_REQUEST['group'] . '&cookietab=3');
411	}
412}
413if ($prefs['feature_categories'] == 'y') {
414	$categlib = TikiLib::lib('categ');
415	$categories = $categlib->getCategories();
416	$smarty->assign_by_ref('categories', $categories);
417}
418
419if (isset($_REQUEST['group'])) {
420	$smarty->assign('indirectly_inherited_groups', indirectly_inherited_groups($inc));
421}
422//group theme - list themes
423$themelib = TikiLib::lib('theme');
424$group_themes = $themelib->list_themes_and_options();
425$smarty->assign_by_ref('group_themes', $group_themes);
426
427$smarty->assign('inc', $inc);
428$smarty->assign('group', $_REQUEST["group"]);
429$smarty->assign('groupname', $groupname);
430$smarty->assign('groupdesc', $groupdesc);
431$smarty->assign('grouphome', $grouphome);
432$smarty->assign('groupdefcat', $groupdefcat);
433$smarty->assign('grouptheme', $grouptheme);
434if (! empty($groupcolor)) {
435	$smarty->assign('groupcolor', $groupcolor);
436}
437$smarty->assign('groupperms', $groupperms);
438$smarty->assign_by_ref('userChoice', $userChoice);
439$smarty->assign_by_ref('cant_pages', $users["cant"]);
440$smarty->assign('group_info', $re);
441$smarty->assign('isRole', $isRole);
442$smarty->assign('isTplGroup', $isTplGroup);
443
444ask_ticket('admin-groups');
445
446// Assign the list of groups
447$smarty->assign_by_ref('users', $users["data"]);
448// disallow robots to index page:
449$smarty->assign('metatag_robots', 'NOINDEX, NOFOLLOW');
450// Display the template for group administration
451$smarty->assign('mid', 'tiki-admingroups.tpl');
452$smarty->display("tiki.tpl");
453
454/**
455 * @param $direct_groups
456 * @return array
457 */
458function indirectly_inherited_groups($direct_groups)
459{
460	$userlib = TikiLib::lib('user');
461	$indirect_groups = [];
462	foreach ($direct_groups as $a_direct_group => $does_inherit) {
463		if ($does_inherit === 'y') {
464			 $some_indirect_groups = $userlib->get_included_groups($a_direct_group);
465			foreach ($some_indirect_groups as $an_indirect_group) {
466				$indirect_groups[] = $an_indirect_group;
467			}
468		}
469	}
470	 return $indirect_groups;
471}
472