1<?php
2/**
3 * Elgg groups plugin edit action.
4 *
5 * If editing an existing group, only the "group_guid" must be submitted. All other form
6 * elements may be omitted and the corresponding data will be left as is.
7 */
8
9elgg_make_sticky_form('groups');
10
11// Get group fields
12$input = [];
13foreach (elgg_get_config('group') as $shortname => $valuetype) {
14	$value = get_input($shortname);
15
16	if ($value === null) {
17		// only submitted fields should be updated
18		continue;
19	}
20
21	$input[$shortname] = $value;
22
23	// @todo treat profile fields as unescaped: don't filter, encode on output
24	if (is_array($input[$shortname])) {
25		array_walk_recursive($input[$shortname], function (&$v) {
26			$v = elgg_html_decode($v);
27		});
28	} else {
29		$input[$shortname] = elgg_html_decode($input[$shortname]);
30	}
31
32	if ($valuetype == 'tags') {
33		$input[$shortname] = string_to_tag_array($input[$shortname]);
34	}
35}
36
37// only set if submitted
38$name = elgg_get_title_input('name', null);
39if ($name !== null) {
40	$input['name'] = $name;
41}
42
43$user = elgg_get_logged_in_user_entity();
44
45$group_guid = (int) get_input('group_guid');
46
47if ($group_guid) {
48	$is_new_group = false;
49	$group = get_entity($group_guid);
50	if (!$group instanceof ElggGroup || !$group->canEdit()) {
51		$error = elgg_echo('groups:cantedit');
52		return elgg_error_response($error);
53	}
54} else {
55	if (elgg_get_plugin_setting('limited_groups', 'groups') == 'yes' && !$user->isAdmin()) {
56		$error = elgg_echo('groups:cantcreate');
57		return elgg_error_response($error);
58	}
59
60	$container_guid = get_input('container_guid', $user->guid);
61	$container = get_entity($container_guid);
62
63	if (!$container || !$container->canWriteToContainer($user->guid, 'group')) {
64		$error = elgg_echo('groups:cantcreate');
65		return elgg_error_response($error);
66	}
67
68	$is_new_group = true;
69	$group = new ElggGroup();
70	$group->container_guid = $container->guid;
71}
72
73// Assume we can edit or this is a new group
74foreach ($input as $shortname => $value) {
75	if ($value === '' && !in_array($shortname, ['name', 'description'])) {
76		// The group profile displays all profile fields that have a value.
77		// We don't want to display fields with empty string value, so we
78		// remove the metadata completely.
79		$group->deleteMetadata($shortname);
80		continue;
81	}
82
83	$group->$shortname = $value;
84}
85
86// Validate create
87if (!$group->name) {
88	return elgg_error_response(elgg_echo('groups:notitle'));
89}
90
91// Set group tool options (only pass along saved entities)
92// @todo: move this to an event handler to make sure groups created outside of the action
93// get their tools configured
94if ($is_new_group) {
95	$tools = elgg()->group_tools->all();
96} else {
97	$tools = elgg()->group_tools->group($group);
98}
99
100foreach ($tools as $tool) {
101	$prop_name = $tool->mapMetadataName();
102	$value = get_input($prop_name);
103
104	if (!isset($value)) {
105		continue;
106	}
107
108	if ($value === 'yes') {
109		$group->enableTool($tool->name);
110	} else {
111		$group->disableTool($tool->name);
112	}
113}
114
115// Group membership - should these be treated with same constants as access permissions?
116$value = get_input('membership');
117if ($group->membership === null || $value !== null) {
118	$is_public_membership = ($value == ACCESS_PUBLIC);
119	$group->membership = $is_public_membership ? ACCESS_PUBLIC : ACCESS_PRIVATE;
120}
121
122$group->setContentAccessMode((string) get_input('content_access_mode'));
123
124if ($is_new_group) {
125	$group->access_id = ACCESS_PUBLIC;
126}
127
128$old_owner_guid = $is_new_group ? 0 : $group->owner_guid;
129
130$value = (array) get_input('owner_guid');
131$new_owner_guid = empty($value) ? $old_owner_guid : (int) $value[0];
132
133if (!$is_new_group && $new_owner_guid && $new_owner_guid != $old_owner_guid) {
134	// verify new owner is member and old owner/admin is logged in
135	if ($group->isMember(get_user($new_owner_guid)) && ($old_owner_guid == $user->guid || $user->isAdmin())) {
136		$group->owner_guid = $new_owner_guid;
137		if ($group->container_guid == $old_owner_guid) {
138			// Even though this action defaults container_guid to the logged in user guid,
139			// the group may have initially been created with a custom script that assigned
140			// a different container entity. We want to make sure we preserve the original
141			// container if it the group is not contained by the original owner.
142			$group->container_guid = $new_owner_guid;
143		}
144	}
145}
146
147if ($is_new_group) {
148	// if new group, we need to save so group acl gets set in event handler
149	if (!$group->save()) {
150		return elgg_error_response(elgg_echo('groups:save_error'));
151	}
152}
153
154// Invisible group support
155// @todo this requires save to be called to create the acl for the group. This
156// is an odd requirement and should be removed. Either the acl creation happens
157// in the action or the visibility moves to a plugin hook
158if (elgg_get_plugin_setting('hidden_groups', 'groups') == 'yes') {
159	$value = get_input('vis');
160	if ($is_new_group || $value !== null) {
161		$visibility = (int) $value;
162
163		if ($visibility == ACCESS_PRIVATE) {
164			// Make this group visible only to group members. We need to use
165			// ACCESS_PRIVATE on the form and convert it to group_acl here
166			// because new groups do not have acl until they have been saved once.
167			$acl = _groups_get_group_acl($group);
168			if ($acl) {
169				$visibility = $acl->id;
170			}
171
172			// Force all new group content to be available only to members
173			$group->setContentAccessMode(ElggGroup::CONTENT_ACCESS_MODE_MEMBERS_ONLY);
174		}
175
176		$group->access_id = $visibility;
177	}
178}
179
180// group default content access
181$content_default_access = get_input('content_default_access');
182if (isset($content_default_access)) {
183	if (elgg_is_empty($content_default_access)) {
184		unset($group->content_default_access);
185	} else {
186		$group->content_default_access = (int) $content_default_access;
187	}
188}
189
190if (!$group->save()) {
191	return elgg_error_response(elgg_echo('groups:save_error'));
192}
193
194// group saved so clear sticky form
195elgg_clear_sticky_form('groups');
196
197// group creator needs to be member of new group and river entry created
198if ($is_new_group) {
199	// @todo this should not be necessary...
200	elgg_set_page_owner_guid($group->guid);
201
202	$group->join($user);
203	elgg_create_river_item([
204		'view' => 'river/group/create',
205		'action_type' => 'create',
206		'object_guid' => $group->guid,
207	]);
208}
209
210if (get_input('icon_remove')) {
211	$group->deleteIcon();
212} else {
213	// try to save new icon, will fail silently if no icon provided
214	$group->saveIconFromUploadedFile('icon');
215}
216
217$data = [
218	'entity' => $group,
219];
220return elgg_ok_response($data, elgg_echo('groups:saved'), $group->getURL());
221