diff options
Diffstat (limited to 'mod/groups')
67 files changed, 4576 insertions, 0 deletions
diff --git a/mod/groups/actions/discussion/delete.php b/mod/groups/actions/discussion/delete.php new file mode 100644 index 000000000..f307aa091 --- /dev/null +++ b/mod/groups/actions/discussion/delete.php @@ -0,0 +1,29 @@ +<?php +/** + * Delete topic action + * + */ + +$topic_guid = (int) get_input('guid'); + +$topic = get_entity($topic_guid); +if (!$topic || !$topic->getSubtype() == "groupforumtopic") { +	register_error(elgg_echo('discussion:error:notdeleted')); +	forward(REFERER); +} + +if (!$topic->canEdit()) { +	register_error(elgg_echo('discussion:error:permissions')); +	forward(REFERER); +} + +$container = $topic->getContainerEntity(); + +$result = $topic->delete(); +if ($result) { +	system_message(elgg_echo('discussion:topic:deleted')); +} else { +	register_error(elgg_echo('discussion:error:notdeleted')); +} + +forward("discussion/owner/$container->guid"); diff --git a/mod/groups/actions/discussion/reply/delete.php b/mod/groups/actions/discussion/reply/delete.php new file mode 100644 index 000000000..88c6b79d6 --- /dev/null +++ b/mod/groups/actions/discussion/reply/delete.php @@ -0,0 +1,26 @@ +<?php +/** + * Delete discussion reply + */ + +$id = (int) get_input('annotation_id'); + +$reply = elgg_get_annotation_from_id($id); +if (!$reply || $reply->name != 'group_topic_post') { +	register_error(elgg_echo('discussion:reply:error:notdeleted')); +	forward(REFERER); +} + +if (!$reply->canEdit()) { +	register_error(elgg_echo('discussion:error:permissions')); +	forward(REFERER); +} + +$result = $reply->delete(); +if ($result) { +	system_message(elgg_echo('discussion:reply:deleted')); +} else { +	register_error(elgg_echo('discussion:reply:error:notdeleted')); +} + +forward(REFERER); diff --git a/mod/groups/actions/discussion/reply/save.php b/mod/groups/actions/discussion/reply/save.php new file mode 100644 index 000000000..f8be8aa2c --- /dev/null +++ b/mod/groups/actions/discussion/reply/save.php @@ -0,0 +1,58 @@ +<?php +/** + * Post a reply to discussion topic + * + */ + +// Get input +$entity_guid = (int) get_input('entity_guid'); +$text = get_input('group_topic_post'); +$annotation_id = (int) get_input('annotation_id'); + +// reply cannot be empty +if (empty($text)) { +	register_error(elgg_echo('grouppost:nopost')); +	forward(REFERER); +} + +$topic = get_entity($entity_guid); +if (!$topic) { +	register_error(elgg_echo('grouppost:nopost')); +	forward(REFERER); +} + +$user = elgg_get_logged_in_user_entity(); + +$group = $topic->getContainerEntity(); +if (!$group->canWriteToContainer()) { +	register_error(elgg_echo('groups:notmember')); +	forward(REFERER); +} + +// if editing a reply, make sure it's valid +if ($annotation_id) { +	$annotation = elgg_get_annotation_from_id($annotation_id); +	if (!$annotation->canEdit()) { +		register_error(elgg_echo('groups:notowner')); +		forward(REFERER); +	} + +	$annotation->value = $text; +	if (!$annotation->save()) { +		system_message(elgg_echo('groups:forumpost:error')); +		forward(REFERER); +	} +	system_message(elgg_echo('groups:forumpost:edited')); +} else { +	// add the reply to the forum topic +	$reply_id = $topic->annotate('group_topic_post', $text, $topic->access_id, $user->guid); +	if ($reply_id == false) { +		system_message(elgg_echo('groupspost:failure')); +		forward(REFERER); +	} + +	add_to_river('river/annotation/group_topic_post/reply', 'reply', $user->guid, $topic->guid, "", 0, $reply_id); +	system_message(elgg_echo('groupspost:success')); +} + +forward(REFERER); diff --git a/mod/groups/actions/discussion/save.php b/mod/groups/actions/discussion/save.php new file mode 100644 index 000000000..b3e9da654 --- /dev/null +++ b/mod/groups/actions/discussion/save.php @@ -0,0 +1,75 @@ +<?php +/** + * Topic save action + */ + +// Get variables +$title = htmlspecialchars(get_input('title', '', false), ENT_QUOTES, 'UTF-8'); +$desc = get_input("description"); +$status = get_input("status"); +$access_id = (int) get_input("access_id"); +$container_guid = (int) get_input('container_guid'); +$guid = (int) get_input('topic_guid'); +$tags = get_input("tags"); + +elgg_make_sticky_form('topic'); + +// validation of inputs +if (!$title || !$desc) { +	register_error(elgg_echo('discussion:error:missing')); +	forward(REFERER); +} + +$container = get_entity($container_guid); +if (!$container || !$container->canWriteToContainer(0, 'object', 'groupforumtopic')) { +	register_error(elgg_echo('discussion:error:permissions')); +	forward(REFERER); +} + +// check whether this is a new topic or an edit +$new_topic = true; +if ($guid > 0) { +	$new_topic = false; +} + +if ($new_topic) { +	$topic = new ElggObject(); +	$topic->subtype = 'groupforumtopic'; +} else { +	// load original file object +	$topic = new ElggObject($guid); +	if (!$topic || !$topic->canEdit()) { +		register_error(elgg_echo('discussion:topic:notfound')); +		forward(REFERER); +	} +} + +$topic->title = $title; +$topic->description = $desc; +$topic->status = $status; +$topic->access_id = $access_id; +$topic->container_guid = $container_guid; + +$tags = explode(",", $tags); +$topic->tags = $tags; + +$result = $topic->save(); + +if (!$result) { +	register_error(elgg_echo('discussion:error:notsaved')); +	forward(REFERER); +} + +// topic saved so clear sticky form +elgg_clear_sticky_form('topic'); + + +// handle results differently for new topics and topic edits +if ($new_topic) { +	system_message(elgg_echo('discussion:topic:created')); +	add_to_river('river/object/groupforumtopic/create', 'create', elgg_get_logged_in_user_guid(), $topic->guid); +} else { +	system_message(elgg_echo('discussion:topic:updated')); +} + +forward($topic->getURL()); diff --git a/mod/groups/actions/groups/delete.php b/mod/groups/actions/groups/delete.php new file mode 100644 index 000000000..2ff6c339c --- /dev/null +++ b/mod/groups/actions/groups/delete.php @@ -0,0 +1,42 @@ +<?php +/** + * Delete a group + */ +		 +$guid = (int) get_input('guid'); +if (!$guid) { +	// backward compatible +	elgg_deprecated_notice("Use 'guid' for group delete action", 1.8); +	$guid = (int)get_input('group_guid'); +} +$entity = get_entity($guid); + +if (!$entity->canEdit()) { +	register_error(elgg_echo('group:notdeleted')); +	forward(REFERER); +} + +if (($entity) && ($entity instanceof ElggGroup)) { +	// delete group icons +	$owner_guid = $entity->owner_guid; +	$prefix = "groups/" . $entity->guid; +	$imagenames = array('.jpg', 'tiny.jpg', 'small.jpg', 'medium.jpg', 'large.jpg'); +	$img = new ElggFile(); +	$img->owner_guid = $owner_guid; +	foreach ($imagenames as $name) { +		$img->setFilename($prefix . $name); +		$img->delete(); +	} + +	// delete group +	if ($entity->delete()) { +		system_message(elgg_echo('group:deleted')); +	} else { +		register_error(elgg_echo('group:notdeleted')); +	} +} else { +	register_error(elgg_echo('group:notdeleted')); +} + +$url_name = elgg_get_logged_in_user_entity()->username; +forward(elgg_get_site_url() . "groups/member/{$url_name}"); diff --git a/mod/groups/actions/groups/edit.php b/mod/groups/actions/groups/edit.php new file mode 100644 index 000000000..f19b90566 --- /dev/null +++ b/mod/groups/actions/groups/edit.php @@ -0,0 +1,235 @@ +<?php +/** + * Elgg groups plugin edit action. + * + * @package ElggGroups + */ + +elgg_make_sticky_form('groups'); + +/** + * wrapper for recursive array walk decoding + */ +function profile_array_decoder(&$v) { +	$v = _elgg_html_decode($v); +} + +// Get group fields +$input = array(); +foreach (elgg_get_config('group') as $shortname => $valuetype) { +	$input[$shortname] = get_input($shortname); + +	// @todo treat profile fields as unescaped: don't filter, encode on output +	if (is_array($input[$shortname])) { +		array_walk_recursive($input[$shortname], 'profile_array_decoder'); +	} else { +		$input[$shortname] = _elgg_html_decode($input[$shortname]); +	} + +	if ($valuetype == 'tags') { +		$input[$shortname] = string_to_tag_array($input[$shortname]); +	} +} + +$input['name'] = htmlspecialchars(get_input('name', '', false), ENT_QUOTES, 'UTF-8'); + +$user = elgg_get_logged_in_user_entity(); + +$group_guid = (int)get_input('group_guid'); +$is_new_group = $group_guid == 0; + +if ($is_new_group +		&& (elgg_get_plugin_setting('limited_groups', 'groups') == 'yes') +		&& !$user->isAdmin()) { +	register_error(elgg_echo("groups:cantcreate")); +	forward(REFERER); +} + +$group = new ElggGroup($group_guid); // load if present, if not create a new group +if ($group_guid && !$group->canEdit()) { +	register_error(elgg_echo("groups:cantedit")); +	forward(REFERER); +} + +// Assume we can edit or this is a new group +if (sizeof($input) > 0) { +	foreach($input as $shortname => $value) { +		// update access collection name if group name changes +		if (!$is_new_group && $shortname == 'name' && $value != $group->name) { +			$group_name = html_entity_decode($value, ENT_QUOTES, 'UTF-8'); +			$ac_name = sanitize_string(elgg_echo('groups:group') . ": " . $group_name); +			$acl = get_access_collection($group->group_acl); +			if ($acl) { +				// @todo Elgg api does not support updating access collection name +				$db_prefix = elgg_get_config('dbprefix'); +				$query = "UPDATE {$db_prefix}access_collections SET name = '$ac_name'  +					WHERE id = $group->group_acl"; +				update_data($query); +			} +		} + +		$group->$shortname = $value; +	} +} + +// Validate create +if (!$group->name) { +	register_error(elgg_echo("groups:notitle")); +	forward(REFERER); +} + + +// Set group tool options +$tool_options = elgg_get_config('group_tool_options'); +if ($tool_options) { +	foreach ($tool_options as $group_option) { +		$option_toggle_name = $group_option->name . "_enable"; +		$option_default = $group_option->default_on ? 'yes' : 'no'; +		$group->$option_toggle_name = get_input($option_toggle_name, $option_default); +	} +} + +// Group membership - should these be treated with same constants as access permissions? +$is_public_membership = (get_input('membership') == ACCESS_PUBLIC); +$group->membership = $is_public_membership ? ACCESS_PUBLIC : ACCESS_PRIVATE; + +if ($is_new_group) { +	$group->access_id = ACCESS_PUBLIC; +} + +$old_owner_guid = $is_new_group ? 0 : $group->owner_guid; +$new_owner_guid = (int) get_input('owner_guid'); + +$owner_has_changed = false; +$old_icontime = null; +if (!$is_new_group && $new_owner_guid && $new_owner_guid != $old_owner_guid) { +	// verify new owner is member and old owner/admin is logged in +	if (is_group_member($group_guid, $new_owner_guid) && ($old_owner_guid == $user->guid || $user->isAdmin())) { +		$group->owner_guid = $new_owner_guid; +		$group->container_guid = $new_owner_guid; + +		$metadata = elgg_get_metadata(array( +			'guid' => $group_guid, +			'limit' => false, +		)); +		if ($metadata) { +			foreach ($metadata as $md) { +				if ($md->owner_guid == $old_owner_guid) { +					$md->owner_guid = $new_owner_guid; +					$md->save(); +				} +			} +		} + +		// @todo Remove this when #4683 fixed +		$owner_has_changed = true; +		$old_icontime = $group->icontime; +	} +} + +$must_move_icons = ($owner_has_changed && $old_icontime); + +$group->save(); + +// Invisible group support +// @todo this requires save to be called to create the acl for the group. This +// is an odd requirement and should be removed. Either the acl creation happens +// in the action or the visibility moves to a plugin hook +if (elgg_get_plugin_setting('hidden_groups', 'groups') == 'yes') { +	$visibility = (int)get_input('vis', '', false); +	if ($visibility != ACCESS_PUBLIC && $visibility != ACCESS_LOGGED_IN) { +		$visibility = $group->group_acl; +	} + +	if ($group->access_id != $visibility) { +		$group->access_id = $visibility; +	} +} + +$group->save(); + +// group saved so clear sticky form +elgg_clear_sticky_form('groups'); + +// group creator needs to be member of new group and river entry created +if ($is_new_group) { + +	// @todo this should not be necessary... +	elgg_set_page_owner_guid($group->guid); + +	$group->join($user); +	add_to_river('river/group/create', 'create', $user->guid, $group->guid, $group->access_id); +} + +$has_uploaded_icon = (!empty($_FILES['icon']['type']) && substr_count($_FILES['icon']['type'], 'image/')); + +if ($has_uploaded_icon) { + +	$icon_sizes = elgg_get_config('icon_sizes'); + +	$prefix = "groups/" . $group->guid; + +	$filehandler = new ElggFile(); +	$filehandler->owner_guid = $group->owner_guid; +	$filehandler->setFilename($prefix . ".jpg"); +	$filehandler->open("write"); +	$filehandler->write(get_uploaded_file('icon')); +	$filehandler->close(); +	$filename = $filehandler->getFilenameOnFilestore(); + +	$sizes = array('tiny', 'small', 'medium', 'large'); + +	$thumbs = array(); +	foreach ($sizes as $size) { +		$thumbs[$size] = get_resized_image_from_existing_file( +			$filename, +			$icon_sizes[$size]['w'], +			$icon_sizes[$size]['h'], +			$icon_sizes[$size]['square'] +		); +	} + +	if ($thumbs['tiny']) { // just checking if resize successful +		$thumb = new ElggFile(); +		$thumb->owner_guid = $group->owner_guid; +		$thumb->setMimeType('image/jpeg'); + +		foreach ($sizes as $size) { +			$thumb->setFilename("{$prefix}{$size}.jpg"); +			$thumb->open("write"); +			$thumb->write($thumbs[$size]); +			$thumb->close(); +		} + +		$group->icontime = time(); +	} +} + +// @todo Remove this when #4683 fixed +if ($must_move_icons) { +	$filehandler = new ElggFile(); +	$filehandler->setFilename('groups'); +	$filehandler->owner_guid = $old_owner_guid; +	$old_path = $filehandler->getFilenameOnFilestore(); + +	$sizes = array('', 'tiny', 'small', 'medium', 'large'); + +	if ($has_uploaded_icon) { +		// delete those under old owner +		foreach ($sizes as $size) { +			unlink("$old_path/{$group_guid}{$size}.jpg"); +		} +	} else { +		// move existing to new owner +		$filehandler->owner_guid = $group->owner_guid; +		$new_path = $filehandler->getFilenameOnFilestore(); + +		foreach ($sizes as $size) { +			rename("$old_path/{$group_guid}{$size}.jpg", "$new_path/{$group_guid}{$size}.jpg"); +		} +	} +} + +system_message(elgg_echo("groups:saved")); + +forward($group->getUrl()); diff --git a/mod/groups/actions/groups/featured.php b/mod/groups/actions/groups/featured.php new file mode 100644 index 000000000..4cb9f8122 --- /dev/null +++ b/mod/groups/actions/groups/featured.php @@ -0,0 +1,27 @@ +<?php	 +/** + * Feature a group + * + * @package ElggGroups + */ + +$group_guid = get_input('group_guid'); +$action = get_input('action_type'); + +$group = get_entity($group_guid); + +if (!elgg_instanceof($group, 'group')) { +	register_error(elgg_echo('groups:featured_error')); +	forward(REFERER); +} + +//get the action, is it to feature or unfeature +if ($action == "feature") { +	$group->featured_group = "yes"; +	system_message(elgg_echo('groups:featuredon', array($group->name))); +} else { +	$group->featured_group = "no"; +	system_message(elgg_echo('groups:unfeatured', array($group->name))); +} + +forward(REFERER); diff --git a/mod/groups/actions/groups/membership/add.php b/mod/groups/actions/groups/membership/add.php new file mode 100644 index 000000000..de0cba613 --- /dev/null +++ b/mod/groups/actions/groups/membership/add.php @@ -0,0 +1,42 @@ +<?php +/** + * Add users to a group + * + * @package ElggGroups + */ +$logged_in_user = elgg_get_logged_in_user_entity(); + +$user_guid = get_input('user_guid'); +if (!is_array($user_guid)) { +	$user_guid = array($user_guid); +} +$group_guid = get_input('group_guid'); +$group = get_entity($group_guid); + +if (sizeof($user_guid)) { +	foreach ($user_guid as $u_id) { +		$user = get_user($u_id); + +		if ($user && $group && $group->canEdit()) { +			if (!$group->isMember($user)) { +				if (groups_join_group($group, $user)) { + +					// send welcome email to user +					notify_user($user->getGUID(), $group->owner_guid, +							elgg_echo('groups:welcome:subject', array($group->name)), +							elgg_echo('groups:welcome:body', array( +								$user->name, +								$group->name, +								$group->getURL()) +							)); + +					system_message(elgg_echo('groups:addedtogroup')); +				} else { +					// huh +				} +			} +		} +	} +} + +forward(REFERER); diff --git a/mod/groups/actions/groups/membership/delete_invite.php b/mod/groups/actions/groups/membership/delete_invite.php new file mode 100644 index 000000000..d21aa0309 --- /dev/null +++ b/mod/groups/actions/groups/membership/delete_invite.php @@ -0,0 +1,24 @@ +<?php +/** + * Delete an invitation to join a group. + * + * @package ElggGroups + */ + +$user_guid = get_input('user_guid', elgg_get_logged_in_user_guid()); +$group_guid = get_input('group_guid'); + +$user = get_entity($user_guid); + +// invisible groups require overriding access to delete invite +$old_access = elgg_set_ignore_access(true); +$group = get_entity($group_guid); +elgg_set_ignore_access($old_access); + +// If join request made +if (check_entity_relationship($group->guid, 'invited', $user->guid)) { +	remove_entity_relationship($group->guid, 'invited', $user->guid); +	system_message(elgg_echo("groups:invitekilled")); +} + +forward(REFERER); diff --git a/mod/groups/actions/groups/membership/delete_request.php b/mod/groups/actions/groups/membership/delete_request.php new file mode 100644 index 000000000..883c9d748 --- /dev/null +++ b/mod/groups/actions/groups/membership/delete_request.php @@ -0,0 +1,20 @@ +<?php +/** + * Delete a request to join a closed group. + * + * @package ElggGroups + */ + +$user_guid = get_input('user_guid', elgg_get_logged_in_user_guid()); +$group_guid = get_input('group_guid'); + +$user = get_entity($user_guid); +$group = get_entity($group_guid); + +// If join request made +if (check_entity_relationship($user->guid, 'membership_request', $group->guid)) { +	remove_entity_relationship($user->guid, 'membership_request', $group->guid); +	system_message(elgg_echo("groups:joinrequestkilled")); +} + +forward(REFERER); diff --git a/mod/groups/actions/groups/membership/invite.php b/mod/groups/actions/groups/membership/invite.php new file mode 100644 index 000000000..a96165b0e --- /dev/null +++ b/mod/groups/actions/groups/membership/invite.php @@ -0,0 +1,56 @@ +<?php +/** + * Invite users to join a group + * + * @package ElggGroups + */ + +$logged_in_user = elgg_get_logged_in_user_entity(); + +$user_guids = get_input('user_guid'); +if (!is_array($user_guids)) { +	$user_guids = array($user_guids); +} +$group_guid = get_input('group_guid'); +$group = get_entity($group_guid); + +if (count($user_guids) > 0 && elgg_instanceof($group, 'group') && $group->canEdit()) { +	foreach ($user_guids as $guid) { +		$user = get_user($guid); +		if (!$user) { +			continue; +		} + +		if (check_entity_relationship($group->guid, 'invited', $user->guid)) { +			register_error(elgg_echo("groups:useralreadyinvited")); +			continue; +		} + +		if (check_entity_relationship($user->guid, 'member', $group->guid)) { +			// @todo add error message +			continue; +		} + +		// Create relationship +		add_entity_relationship($group->guid, 'invited', $user->guid); + +		// Send notification +		$url = elgg_normalize_url("groups/invitations/$user->username"); +		$result = notify_user($user->getGUID(), $group->owner_guid, +				elgg_echo('groups:invite:subject', array($user->name, $group->name)), +				elgg_echo('groups:invite:body', array( +					$user->name, +					$logged_in_user->name, +					$group->name, +					$url, +				)), +				NULL); +		if ($result) { +			system_message(elgg_echo("groups:userinvited")); +		} else { +			register_error(elgg_echo("groups:usernotinvited")); +		} +	} +} + +forward(REFERER); diff --git a/mod/groups/actions/groups/membership/join.php b/mod/groups/actions/groups/membership/join.php new file mode 100644 index 000000000..b4f4e280c --- /dev/null +++ b/mod/groups/actions/groups/membership/join.php @@ -0,0 +1,72 @@ +<?php +/** + * Join a group + * + * Three states: + * open group so user joins + * closed group so request sent to group owner + * closed group with invite so user joins + *  + * @package ElggGroups + */ + +global $CONFIG; + +$user_guid = get_input('user_guid', elgg_get_logged_in_user_guid()); +$group_guid = get_input('group_guid'); + +$user = get_entity($user_guid); + +// access bypass for getting invisible group +$ia = elgg_set_ignore_access(true); +$group = get_entity($group_guid); +elgg_set_ignore_access($ia); + +if (($user instanceof ElggUser) && ($group instanceof ElggGroup)) { + +	// join or request +	$join = false; +	if ($group->isPublicMembership() || $group->canEdit($user->guid)) { +		// anyone can join public groups and admins can join any group +		$join = true; +	} else { +		if (check_entity_relationship($group->guid, 'invited', $user->guid)) { +			// user has invite to closed group +			$join = true; +		} +	} + +	if ($join) { +		if (groups_join_group($group, $user)) { +			system_message(elgg_echo("groups:joined")); +			forward($group->getURL()); +		} else { +			register_error(elgg_echo("groups:cantjoin")); +		} +	} else { +		add_entity_relationship($user->guid, 'membership_request', $group->guid); + +		// Notify group owner +		$url = "{$CONFIG->url}groups/requests/$group->guid"; +		$subject = elgg_echo('groups:request:subject', array( +			$user->name, +			$group->name, +		)); +		$body = elgg_echo('groups:request:body', array( +			$group->getOwnerEntity()->name, +			$user->name, +			$group->name, +			$user->getURL(), +			$url, +		)); +		if (notify_user($group->owner_guid, $user->getGUID(), $subject, $body)) { +			system_message(elgg_echo("groups:joinrequestmade")); +		} else { +			register_error(elgg_echo("groups:joinrequestnotmade")); +		} +	} +} else { +	register_error(elgg_echo("groups:cantjoin")); +} + +forward(REFERER); diff --git a/mod/groups/actions/groups/membership/leave.php b/mod/groups/actions/groups/membership/leave.php new file mode 100644 index 000000000..4f34c7dde --- /dev/null +++ b/mod/groups/actions/groups/membership/leave.php @@ -0,0 +1,36 @@ +<?php +/** + * Leave a group action. + * + * @package ElggGroups + */ + +$user_guid = get_input('user_guid'); +$group_guid = get_input('group_guid'); + +$user = NULL; +if (!$user_guid) { +	$user = elgg_get_logged_in_user_entity(); +} else { +	$user = get_entity($user_guid); +} + +$group = get_entity($group_guid); + +elgg_set_page_owner_guid($group->guid); + +if (($user instanceof ElggUser) && ($group instanceof ElggGroup)) { +	if ($group->getOwnerGUID() != elgg_get_logged_in_user_guid()) { +		if ($group->leave($user)) { +			system_message(elgg_echo("groups:left")); +		} else { +			register_error(elgg_echo("groups:cantleave")); +		} +	} else { +		register_error(elgg_echo("groups:cantleave")); +	} +} else { +	register_error(elgg_echo("groups:cantleave")); +} + +forward(REFERER); diff --git a/mod/groups/actions/groups/membership/remove.php b/mod/groups/actions/groups/membership/remove.php new file mode 100644 index 000000000..650d35286 --- /dev/null +++ b/mod/groups/actions/groups/membership/remove.php @@ -0,0 +1,31 @@ +<?php +/** + * Remove a user from a group + * + * @package ElggGroups + */ + +$user_guid = get_input('user_guid'); +$group_guid = get_input('group_guid'); + +$user = get_entity($user_guid); +$group = get_entity($group_guid); + +elgg_set_page_owner_guid($group->guid); + +if (($user instanceof ElggUser) && ($group instanceof ElggGroup) && $group->canEdit()) { +	// Don't allow removing group owner +	if ($group->getOwnerGUID() != $user->getGUID()) { +		if ($group->leave($user)) { +			system_message(elgg_echo("groups:removed", array($user->name))); +		} else { +			register_error(elgg_echo("groups:cantremove")); +		} +	} else { +		register_error(elgg_echo("groups:cantremove")); +	} +} else { +	register_error(elgg_echo("groups:cantremove")); +} + +forward(REFERER); diff --git a/mod/groups/graphics/defaultlarge.gif b/mod/groups/graphics/defaultlarge.gif Binary files differnew file mode 100644 index 000000000..b0921b8d8 --- /dev/null +++ b/mod/groups/graphics/defaultlarge.gif diff --git a/mod/groups/graphics/defaultmedium.gif b/mod/groups/graphics/defaultmedium.gif Binary files differnew file mode 100644 index 000000000..ae230a3d7 --- /dev/null +++ b/mod/groups/graphics/defaultmedium.gif diff --git a/mod/groups/graphics/defaultsmall.gif b/mod/groups/graphics/defaultsmall.gif Binary files differnew file mode 100644 index 000000000..81d89110d --- /dev/null +++ b/mod/groups/graphics/defaultsmall.gif diff --git a/mod/groups/graphics/defaulttiny.gif b/mod/groups/graphics/defaulttiny.gif Binary files differnew file mode 100644 index 000000000..86dc96ae4 --- /dev/null +++ b/mod/groups/graphics/defaulttiny.gif diff --git a/mod/groups/icon.php b/mod/groups/icon.php new file mode 100644 index 000000000..ebdc1eb6d --- /dev/null +++ b/mod/groups/icon.php @@ -0,0 +1,54 @@ +<?php +/** + * Icon display + * + * @package ElggGroups + */ + +require_once(dirname(dirname(dirname(__FILE__))) . "/engine/start.php"); + +$group_guid = get_input('group_guid'); + +/* @var ElggGroup $group */ +$group = get_entity($group_guid); +if (!($group instanceof ElggGroup)) { +	header("HTTP/1.1 404 Not Found"); +	exit; +} + +// If is the same ETag, content didn't changed. +$etag = $group->icontime . $group_guid; +if (isset($_SERVER['HTTP_IF_NONE_MATCH']) && trim($_SERVER['HTTP_IF_NONE_MATCH']) == "\"$etag\"") { +	header("HTTP/1.1 304 Not Modified"); +	exit; +} + +$size = strtolower(get_input('size')); +if (!in_array($size, array('large', 'medium', 'small', 'tiny', 'master', 'topbar'))) +	$size = "medium"; + +$success = false; + +$filehandler = new ElggFile(); +$filehandler->owner_guid = $group->owner_guid; +$filehandler->setFilename("groups/" . $group->guid . $size . ".jpg"); + +$success = false; +if ($filehandler->open("read")) { +	if ($contents = $filehandler->read($filehandler->size())) { +		$success = true; +	} +} + +if (!$success) { +	$location = elgg_get_plugins_path() . "groups/graphics/default{$size}.gif"; +	$contents = @file_get_contents($location); +} + +header("Content-type: image/jpeg"); +header('Expires: ' . gmdate('D, d M Y H:i:s \G\M\T', strtotime("+10 days")), true); +header("Pragma: public"); +header("Cache-Control: public"); +header("Content-Length: " . strlen($contents)); +header("ETag: \"$etag\""); +echo $contents; diff --git a/mod/groups/languages/en.php b/mod/groups/languages/en.php new file mode 100644 index 000000000..9e0799b3a --- /dev/null +++ b/mod/groups/languages/en.php @@ -0,0 +1,299 @@ +<?php +/** + * Elgg groups plugin language pack + * + * @package ElggGroups + */ + +$english = array( + +	/** +	 * Menu items and titles +	 */ +	'groups' => "Groups", +	'groups:owned' => "Groups I own", +	'groups:owned:user' => 'Groups %s owns', +	'groups:yours' => "My groups", +	'groups:user' => "%s's groups", +	'groups:all' => "All groups", +	'groups:add' => "Create a new group", +	'groups:edit' => "Edit group", +	'groups:delete' => 'Delete group', +	'groups:membershiprequests' => 'Manage join requests', +	'groups:membershiprequests:pending' => 'Manage join requests (%s)', +	'groups:invitations' => 'Group invitations', +	'groups:invitations:pending' => 'Group invitations (%s)', + +	'groups:icon' => 'Group icon (leave blank to leave unchanged)', +	'groups:name' => 'Group name', +	'groups:username' => 'Group short name (displayed in URLs, alphanumeric characters only)', +	'groups:description' => 'Description', +	'groups:briefdescription' => 'Brief description', +	'groups:interests' => 'Tags', +	'groups:website' => 'Website', +	'groups:members' => 'Group members', +	'groups:my_status' => 'My status', +	'groups:my_status:group_owner' => 'You own this group', +	'groups:my_status:group_member' => 'You are in this group', +	'groups:subscribed' => 'Group notifications on', +	'groups:unsubscribed' => 'Group notifications off', + +	'groups:members:title' => 'Members of %s', +	'groups:members:more' => "View all members", +	'groups:membership' => "Group membership permissions", +	'groups:access' => "Access permissions", +	'groups:owner' => "Owner", +	'groups:owner:warning' => "Warning: if you change this value, you will no longer be the owner of this group.", +	'groups:widget:num_display' => 'Number of groups to display', +	'groups:widget:membership' => 'Group membership', +	'groups:widgets:description' => 'Display the groups you are a member of on your profile', +	'groups:noaccess' => 'No access to group', +	'groups:permissions:error' => 'You do not have the permissions for this', +	'groups:ingroup' => 'in the group', +	'groups:cantcreate' => 'You can not create a group. Only admins can.', +	'groups:cantedit' => 'You can not edit this group', +	'groups:saved' => 'Group saved', +	'groups:featured' => 'Featured groups', +	'groups:makeunfeatured' => 'Unfeature', +	'groups:makefeatured' => 'Make featured', +	'groups:featuredon' => '%s is now a featured group.', +	'groups:unfeatured' => '%s has been removed from the featured groups.', +	'groups:featured_error' => 'Invalid group.', +	'groups:joinrequest' => 'Request membership', +	'groups:join' => 'Join group', +	'groups:leave' => 'Leave group', +	'groups:invite' => 'Invite friends', +	'groups:invite:title' => 'Invite friends to this group', +	'groups:inviteto' => "Invite friends to '%s'", +	'groups:nofriends' => "You have no friends left who have not been invited to this group.", +	'groups:nofriendsatall' => 'You have no friends to invite!', +	'groups:viagroups' => "via groups", +	'groups:group' => "Group", +	'groups:search:tags' => "tag", +	'groups:search:title' => "Search for groups tagged with '%s'", +	'groups:search:none' => "No matching groups were found", +	'groups:search_in_group' => "Search in this group", +	'groups:acl' => "Group: %s", + +	'discussion:notification:topic:subject' => 'New group discussion post', +	'groups:notification' => +'%s added a new discussion topic to %s: + +%s +%s + +View and reply to the discussion: +%s +', + +	'discussion:notification:reply:body' => +'%s replied to the discussion topic %s in the group %s: + +%s + +View and reply to the discussion: +%s +', + +	'groups:activity' => "Group activity", +	'groups:enableactivity' => 'Enable group activity', +	'groups:activity:none' => "There is no group activity yet", + +	'groups:notfound' => "Group not found", +	'groups:notfound:details' => "The requested group either does not exist or you do not have access to it", + +	'groups:requests:none' => 'There are no current membership requests.', + +	'groups:invitations:none' => 'There are no current invitations.', + +	'item:object:groupforumtopic' => "Discussion topics", + +	'groupforumtopic:new' => "Add discussion post", + +	'groups:count' => "groups created", +	'groups:open' => "open group", +	'groups:closed' => "closed group", +	'groups:member' => "members", +	'groups:searchtag' => "Search for groups by tag", + +	'groups:more' => 'More groups', +	'groups:none' => 'No groups', + + +	/* +	 * Access +	 */ +	'groups:access:private' => 'Closed - Users must be invited', +	'groups:access:public' => 'Open - Any user may join', +	'groups:access:group' => 'Group members only', +	'groups:closedgroup' => 'This group has a closed membership.', +	'groups:closedgroup:request' => 'To ask to be added, click the "request membership" menu link.', +	'groups:visibility' => 'Who can see this group?', + +	/* +	Group tools +	*/ +	'groups:enableforum' => 'Enable group discussion', +	'groups:yes' => 'yes', +	'groups:no' => 'no', +	'groups:lastupdated' => 'Last updated %s by %s', +	'groups:lastcomment' => 'Last comment %s by %s', + +	/* +	Group discussion +	*/ +	'discussion' => 'Discussion', +	'discussion:add' => 'Add discussion topic', +	'discussion:latest' => 'Latest discussion', +	'discussion:group' => 'Group discussion', +	'discussion:none' => 'No discussion', +	'discussion:reply:title' => 'Reply by %s', + +	'discussion:topic:created' => 'The discussion topic was created.', +	'discussion:topic:updated' => 'The discussion topic was updated.', +	'discussion:topic:deleted' => 'Discussion topic has been deleted.', + +	'discussion:topic:notfound' => 'Discussion topic not found', +	'discussion:error:notsaved' => 'Unable to save this topic', +	'discussion:error:missing' => 'Both title and message are required fields', +	'discussion:error:permissions' => 'You do not have permissions to perform this action', +	'discussion:error:notdeleted' => 'Could not delete the discussion topic', + +	'discussion:reply:deleted' => 'Discussion reply has been deleted.', +	'discussion:reply:error:notdeleted' => 'Could not delete the discussion reply', + +	'reply:this' => 'Reply to this', + +	'group:replies' => 'Replies', +	'groups:forum:created' => 'Created %s with %d comments', +	'groups:forum:created:single' => 'Created %s with %d reply', +	'groups:forum' => 'Discussion', +	'groups:addtopic' => 'Add a topic', +	'groups:forumlatest' => 'Latest discussion', +	'groups:latestdiscussion' => 'Latest discussion', +	'groups:newest' => 'Newest', +	'groups:popular' => 'Popular', +	'groupspost:success' => 'Your reply was succesfully posted', +	'groups:alldiscussion' => 'Latest discussion', +	'groups:edittopic' => 'Edit topic', +	'groups:topicmessage' => 'Topic message', +	'groups:topicstatus' => 'Topic status', +	'groups:reply' => 'Post a comment', +	'groups:topic' => 'Topic', +	'groups:posts' => 'Posts', +	'groups:lastperson' => 'Last person', +	'groups:when' => 'When', +	'grouptopic:notcreated' => 'No topics have been created.', +	'groups:topicopen' => 'Open', +	'groups:topicclosed' => 'Closed', +	'groups:topicresolved' => 'Resolved', +	'grouptopic:created' => 'Your topic was created.', +	'groupstopic:deleted' => 'The topic has been deleted.', +	'groups:topicsticky' => 'Sticky', +	'groups:topicisclosed' => 'This discussion is closed.', +	'groups:topiccloseddesc' => 'This discussion is closed and is not accepting new comments.', +	'grouptopic:error' => 'Your group topic could not be created. Please try again or contact a system administrator.', +	'groups:forumpost:edited' => "You have successfully edited the forum post.", +	'groups:forumpost:error' => "There was a problem editing the forum post.", + + +	'groups:privategroup' => 'This group is closed. Requesting membership.', +	'groups:notitle' => 'Groups must have a title', +	'groups:cantjoin' => 'Can not join group', +	'groups:cantleave' => 'Could not leave group', +	'groups:removeuser' => 'Remove from group', +	'groups:cantremove' => 'Cannot remove user from group', +	'groups:removed' => 'Successfully removed %s from group', +	'groups:addedtogroup' => 'Successfully added the user to the group', +	'groups:joinrequestnotmade' => 'Could not request to join group', +	'groups:joinrequestmade' => 'Requested to join group', +	'groups:joined' => 'Successfully joined group!', +	'groups:left' => 'Successfully left group', +	'groups:notowner' => 'Sorry, you are not the owner of this group.', +	'groups:notmember' => 'Sorry, you are not a member of this group.', +	'groups:alreadymember' => 'You are already a member of this group!', +	'groups:userinvited' => 'User has been invited.', +	'groups:usernotinvited' => 'User could not be invited.', +	'groups:useralreadyinvited' => 'User has already been invited', +	'groups:invite:subject' => "%s you have been invited to join %s!", +	'groups:updated' => "Last reply by %s %s", +	'groups:started' => "Started by %s", +	'groups:joinrequest:remove:check' => 'Are you sure you want to remove this join request?', +	'groups:invite:remove:check' => 'Are you sure you want to remove this invitation?', +	'groups:invite:body' => "Hi %s, + +%s invited you to join the '%s' group. Click below to view your invitations: + +%s", + +	'groups:welcome:subject' => "Welcome to the %s group!", +	'groups:welcome:body' => "Hi %s! + +You are now a member of the '%s' group! Click below to begin posting! + +%s", + +	'groups:request:subject' => "%s has requested to join %s", +	'groups:request:body' => "Hi %s, + +%s has requested to join the '%s' group. Click below to view their profile: + +%s + +or click below to view the group's join requests: + +%s", + +	/* +		Forum river items +	*/ + +	'river:create:group:default' => '%s created the group %s', +	'river:join:group:default' => '%s joined the group %s', +	'river:create:object:groupforumtopic' => '%s added a new discussion topic %s', +	'river:reply:object:groupforumtopic' => '%s replied on the discussion topic %s', +	 +	'groups:nowidgets' => 'No widgets have been defined for this group.', + + +	'groups:widgets:members:title' => 'Group members', +	'groups:widgets:members:description' => 'List the members of a group.', +	'groups:widgets:members:label:displaynum' => 'List the members of a group.', +	'groups:widgets:members:label:pleaseedit' => 'Please configure this widget.', + +	'groups:widgets:entities:title' => "Objects in group", +	'groups:widgets:entities:description' => "List the objects saved in this group", +	'groups:widgets:entities:label:displaynum' => 'List the objects of a group.', +	'groups:widgets:entities:label:pleaseedit' => 'Please configure this widget.', + +	'groups:forumtopic:edited' => 'Forum topic successfully edited.', + +	'groups:allowhiddengroups' => 'Do you want to allow private (invisible) groups?', +	'groups:whocancreate' => 'Who can create new groups?', + +	/** +	 * Action messages +	 */ +	'group:deleted' => 'Group and group contents deleted', +	'group:notdeleted' => 'Group could not be deleted', + +	'group:notfound' => 'Could not find the group', +	'grouppost:deleted' => 'Group posting successfully deleted', +	'grouppost:notdeleted' => 'Group posting could not be deleted', +	'groupstopic:deleted' => 'Topic deleted', +	'groupstopic:notdeleted' => 'Topic not deleted', +	'grouptopic:blank' => 'No topic', +	'grouptopic:notfound' => 'Could not find the topic', +	'grouppost:nopost' => 'Empty post', +	'groups:deletewarning' => "Are you sure you want to delete this group? There is no undo!", + +	'groups:invitekilled' => 'The invite has been deleted.', +	'groups:joinrequestkilled' => 'The join request has been deleted.', + +	// ecml +	'groups:ecml:discussion' => 'Group Discussions', +	'groups:ecml:groupprofile' => 'Group profiles', + +); + +add_translation("en", $english); diff --git a/mod/groups/lib/discussion.php b/mod/groups/lib/discussion.php new file mode 100644 index 000000000..874e21b2d --- /dev/null +++ b/mod/groups/lib/discussion.php @@ -0,0 +1,235 @@ +<?php +/** + * Discussion function library + */ + +/** + * List all discussion topics + */ +function discussion_handle_all_page() { + +	elgg_pop_breadcrumb(); +	elgg_push_breadcrumb(elgg_echo('discussion')); + +	$content = elgg_list_entities(array( +		'type' => 'object', +		'subtype' => 'groupforumtopic', +		'order_by' => 'e.last_action desc', +		'limit' => 20, +		'full_view' => false, +	)); + +	$params = array( +		'content' => $content, +		'title' => elgg_echo('discussion:latest'), +		'filter' => '', +	); +	$body = elgg_view_layout('content', $params); + +	echo elgg_view_page($title, $body); +} + +/** + * List discussion topics in a group + * + * @param int $guid Group entity GUID + */ +function discussion_handle_list_page($guid) { + +	elgg_set_page_owner_guid($guid); + +	$group = get_entity($guid); +	if (!elgg_instanceof($group, 'group')) { +		forward('', '404'); +	} +	elgg_push_breadcrumb($group->name); + +	elgg_register_title_button(); + +	group_gatekeeper(); + +	$title = elgg_echo('item:object:groupforumtopic'); +	 +	$options = array( +		'type' => 'object', +		'subtype' => 'groupforumtopic', +		'limit' => 20, +		'order_by' => 'e.last_action desc', +		'container_guid' => $guid, +		'full_view' => false, +	); +	$content = elgg_list_entities($options); +	if (!$content) { +		$content = elgg_echo('discussion:none'); +	} + + +	$params = array( +		'content' => $content, +		'title' => $title, +		'filter' => '', +	); + +	$body = elgg_view_layout('content', $params); + +	echo elgg_view_page($title, $body); +} + +/** + * Edit or add a discussion topic + * + * @param string $type 'add' or 'edit' + * @param int    $guid GUID of group or topic + */ +function discussion_handle_edit_page($type, $guid) { +	gatekeeper(); + +	if ($type == 'add') { +		$group = get_entity($guid); +		if (!$group) { +			register_error(elgg_echo('group:notfound')); +			forward(); +		} + +		// make sure user has permissions to add a topic to container +		if (!$group->canWriteToContainer(0, 'object', 'groupforumtopic')) { +			register_error(elgg_echo('groups:permissions:error')); +			forward($group->getURL()); +		} + +		$title = elgg_echo('groups:addtopic'); + +		elgg_push_breadcrumb($group->name, "discussion/owner/$group->guid"); +		elgg_push_breadcrumb($title); + +		$body_vars = discussion_prepare_form_vars(); +		$content = elgg_view_form('discussion/save', array(), $body_vars); +	} else { +		$topic = get_entity($guid); +		if (!$topic || !$topic->canEdit()) { +			register_error(elgg_echo('discussion:topic:notfound')); +			forward(); +		} +		$group = $topic->getContainerEntity(); +		if (!$group) { +			register_error(elgg_echo('group:notfound')); +			forward(); +		} + +		$title = elgg_echo('groups:edittopic'); + +		elgg_push_breadcrumb($group->name, "discussion/owner/$group->guid"); +		elgg_push_breadcrumb($topic->title, $topic->getURL()); +		elgg_push_breadcrumb($title); + +		$body_vars = discussion_prepare_form_vars($topic); +		$content = elgg_view_form('discussion/save', array(), $body_vars); +	} + +	$params = array( +		'content' => $content, +		'title' => $title, +		'filter' => '', +	); +	$body = elgg_view_layout('content', $params); + +	echo elgg_view_page($title, $body); +} + +/** + * View a discussion topic + * + * @param int $guid GUID of topic + */ +function discussion_handle_view_page($guid) { +	// We now have RSS on topics +	global $autofeed; +	$autofeed = true; + +	$topic = get_entity($guid); +	if (!$topic) { +		register_error(elgg_echo('noaccess')); +		$_SESSION['last_forward_from'] = current_page_url(); +		forward(''); +	} + +	$group = $topic->getContainerEntity(); +	if (!$group) { +		register_error(elgg_echo('group:notfound')); +		forward(); +	} + +	elgg_set_page_owner_guid($group->getGUID()); + +	group_gatekeeper(); + +	elgg_push_breadcrumb($group->name, "discussion/owner/$group->guid"); +	elgg_push_breadcrumb($topic->title); + +	$content = elgg_view_entity($topic, array('full_view' => true)); +	if ($topic->status == 'closed') { +		$content .= elgg_view('discussion/replies', array( +			'entity' => $topic, +			'show_add_form' => false, +		)); +		$content .= elgg_view('discussion/closed'); +	} elseif ($group->canWriteToContainer(0, 'object', 'groupforumtopic') || elgg_is_admin_logged_in()) { +		$content .= elgg_view('discussion/replies', array( +			'entity' => $topic, +			'show_add_form' => true, +		)); +	} else { +		$content .= elgg_view('discussion/replies', array( +			'entity' => $topic, +			'show_add_form' => false, +		)); +	} + +	$params = array( +		'content' => $content, +		'title' => $topic->title, +		'filter' => '', +	); +	$body = elgg_view_layout('content', $params); + +	echo elgg_view_page($topic->title, $body); +} + +/** + * Prepare discussion topic form variables + * + * @param ElggObject $topic Topic object if editing + * @return array + */ +function discussion_prepare_form_vars($topic = NULL) { +	// input names => defaults +	$values = array( +		'title' => '', +		'description' => '', +		'status' => '', +		'access_id' => ACCESS_DEFAULT, +		'tags' => '', +		'container_guid' => elgg_get_page_owner_guid(), +		'guid' => null, +		'entity' => $topic, +	); + +	if ($topic) { +		foreach (array_keys($values) as $field) { +			if (isset($topic->$field)) { +				$values[$field] = $topic->$field; +			} +		} +	} + +	if (elgg_is_sticky_form('topic')) { +		$sticky_values = elgg_get_sticky_values('topic'); +		foreach ($sticky_values as $key => $value) { +			$values[$key] = $value; +		} +	} + +	elgg_clear_sticky_form('topic'); + +	return $values; +} diff --git a/mod/groups/lib/groups.php b/mod/groups/lib/groups.php new file mode 100644 index 000000000..d5bec1862 --- /dev/null +++ b/mod/groups/lib/groups.php @@ -0,0 +1,590 @@ +<?php +/** + * Groups function library + */ + +/** + * List all groups + */ +function groups_handle_all_page() { + +	// all groups doesn't get link to self +	elgg_pop_breadcrumb(); +	elgg_push_breadcrumb(elgg_echo('groups')); + +	if (elgg_get_plugin_setting('limited_groups', 'groups') != 'yes' || elgg_is_admin_logged_in()) { +		elgg_register_title_button(); +	} + +	$selected_tab = get_input('filter', 'newest'); + +	switch ($selected_tab) { +		case 'popular': +			$content = elgg_list_entities_from_relationship_count(array( +				'type' => 'group', +				'relationship' => 'member', +				'inverse_relationship' => false, +				'full_view' => false, +			)); +			if (!$content) { +				$content = elgg_echo('groups:none'); +			} +			break; +		case 'discussion': +			$content = elgg_list_entities(array( +				'type' => 'object', +				'subtype' => 'groupforumtopic', +				'order_by' => 'e.last_action desc', +				'limit' => 40, +				'full_view' => false, +			)); +			if (!$content) { +				$content = elgg_echo('discussion:none'); +			} +			break; +		case 'newest': +		default: +			$content = elgg_list_entities(array( +				'type' => 'group', +				'full_view' => false, +			)); +			if (!$content) { +				$content = elgg_echo('groups:none'); +			} +			break; +	} + +	$filter = elgg_view('groups/group_sort_menu', array('selected' => $selected_tab)); + +	$sidebar = elgg_view('groups/sidebar/find'); +	$sidebar .= elgg_view('groups/sidebar/featured'); + +	$params = array( +		'content' => $content, +		'sidebar' => $sidebar, +		'filter' => $filter, +	); +	$body = elgg_view_layout('content', $params); + +	echo elgg_view_page(elgg_echo('groups:all'), $body); +} + +function groups_search_page() { +	elgg_push_breadcrumb(elgg_echo('search')); + +	$tag = get_input("tag"); +	$display_query = _elgg_get_display_query($tag); +	$title = elgg_echo('groups:search:title', array($display_query)); + +	// groups plugin saves tags as "interests" - see groups_fields_setup() in start.php +	$params = array( +		'metadata_name' => 'interests', +		'metadata_value' => $tag, +		'type' => 'group', +		'full_view' => FALSE, +	); +	$content = elgg_list_entities_from_metadata($params); +	if (!$content) { +		$content = elgg_echo('groups:search:none'); +	} + +	$sidebar = elgg_view('groups/sidebar/find'); +	$sidebar .= elgg_view('groups/sidebar/featured'); + +	$params = array( +		'content' => $content, +		'sidebar' => $sidebar, +		'filter' => false, +		'title' => $title, +	); +	$body = elgg_view_layout('content', $params); + +	echo elgg_view_page($title, $body); +} + +/** + * List owned groups + */ +function groups_handle_owned_page() { + +	$page_owner = elgg_get_page_owner_entity(); + +	if ($page_owner->guid == elgg_get_logged_in_user_guid()) { +		$title = elgg_echo('groups:owned'); +	} else { +		$title = elgg_echo('groups:owned:user', array($page_owner->name)); +	} +	elgg_push_breadcrumb($title); + +	if (elgg_get_plugin_setting('limited_groups', 'groups') != 'yes' || elgg_is_admin_logged_in()) { +		elgg_register_title_button(); +	} + +	$content = elgg_list_entities(array( +		'type' => 'group', +		'owner_guid' => elgg_get_page_owner_guid(), +		'full_view' => false, +	)); +	if (!$content) { +		$content = elgg_echo('groups:none'); +	} + +	$params = array( +		'content' => $content, +		'title' => $title, +		'filter' => '', +	); +	$body = elgg_view_layout('content', $params); + +	echo elgg_view_page($title, $body); +} + +/** + * List groups the user is memober of + */ +function groups_handle_mine_page() { + +	$page_owner = elgg_get_page_owner_entity(); + +	if ($page_owner->guid == elgg_get_logged_in_user_guid()) { +		$title = elgg_echo('groups:yours'); +	} else { +		$title = elgg_echo('groups:user', array($page_owner->name)); +	} +	elgg_push_breadcrumb($title); + +	if (elgg_get_plugin_setting('limited_groups', 'groups') != 'yes' || elgg_is_admin_logged_in()) { +		elgg_register_title_button(); +	} + +	$content = elgg_list_entities_from_relationship(array( +		'type' => 'group', +		'relationship' => 'member', +		'relationship_guid' => elgg_get_page_owner_guid(), +		'inverse_relationship' => false, +		'full_view' => false, +	)); +	if (!$content) { +		$content = elgg_echo('groups:none'); +	} + +	$params = array( +		'content' => $content, +		'title' => $title, +		'filter' => '', +	); +	$body = elgg_view_layout('content', $params); + +	echo elgg_view_page($title, $body); +} + +/** + * Create or edit a group + * + * @param string $page + * @param int $guid + */ +function groups_handle_edit_page($page, $guid = 0) { +	gatekeeper(); + +	if ($page == 'add') { +		elgg_set_page_owner_guid(elgg_get_logged_in_user_guid()); +		$title = elgg_echo('groups:add'); +		elgg_push_breadcrumb($title); +		if (elgg_get_plugin_setting('limited_groups', 'groups') != 'yes' || elgg_is_admin_logged_in()) { +			$content = elgg_view('groups/edit'); +		} else { +			$content = elgg_echo('groups:cantcreate'); +		} +	} else { +		$title = elgg_echo("groups:edit"); +		$group = get_entity($guid); + +		if ($group && $group->canEdit()) { +			elgg_set_page_owner_guid($group->getGUID()); +			elgg_push_breadcrumb($group->name, $group->getURL()); +			elgg_push_breadcrumb($title); +			$content = elgg_view("groups/edit", array('entity' => $group)); +		} else { +			$content = elgg_echo('groups:noaccess'); +		} +	} + +	$params = array( +		'content' => $content, +		'title' => $title, +		'filter' => '', +	); +	$body = elgg_view_layout('content', $params); + +	echo elgg_view_page($title, $body); +} + +/** + * Group invitations for a user + */ +function groups_handle_invitations_page() { +	gatekeeper(); + +	$user = elgg_get_page_owner_entity(); + +	$title = elgg_echo('groups:invitations'); +	elgg_push_breadcrumb($title); + +	// @todo temporary workaround for exts #287. +	$invitations = groups_get_invited_groups(elgg_get_logged_in_user_guid()); +	$content = elgg_view('groups/invitationrequests', array('invitations' => $invitations)); + +	$params = array( +		'content' => $content, +		'title' => $title, +		'filter' => '', +	); +	$body = elgg_view_layout('content', $params); + +	echo elgg_view_page($title, $body); +} + +/** + * Group profile page + * + * @param int $guid Group entity GUID + */ +function groups_handle_profile_page($guid) { +	elgg_set_page_owner_guid($guid); + +	// turn this into a core function +	global $autofeed; +	$autofeed = true; + +	elgg_push_context('group_profile'); + +	$group = get_entity($guid); +	if (!elgg_instanceof($group, 'group')) { +		forward('', '404'); +	} + +	elgg_push_breadcrumb($group->name); + +	groups_register_profile_buttons($group); + +	$content = elgg_view('groups/profile/layout', array('entity' => $group)); +	$sidebar = ''; + +	if (group_gatekeeper(false)) { +		if (elgg_is_active_plugin('search')) { +			$sidebar .= elgg_view('groups/sidebar/search', array('entity' => $group)); +		} +		$sidebar .= elgg_view('groups/sidebar/members', array('entity' => $group)); + +		$subscribed = false; +		if (elgg_is_active_plugin('notifications')) { +			global $NOTIFICATION_HANDLERS; + +			foreach ($NOTIFICATION_HANDLERS as $method => $foo) { +				$relationship = check_entity_relationship(elgg_get_logged_in_user_guid(), +						'notify' . $method, $guid); + +				if ($relationship) { +					$subscribed = true; +					break; +				} +			} +		} + +		$sidebar .= elgg_view('groups/sidebar/my_status', array( +			'entity' => $group, +			'subscribed' => $subscribed +		)); +	} + +	$params = array( +		'content' => $content, +		'sidebar' => $sidebar, +		'title' => $group->name, +		'filter' => '', +	); +	$body = elgg_view_layout('content', $params); + +	echo elgg_view_page($group->name, $body); +} + +/** + * Group activity page + * + * @param int $guid Group entity GUID + */ +function groups_handle_activity_page($guid) { + +	elgg_set_page_owner_guid($guid); + +	$group = get_entity($guid); +	if (!$group || !elgg_instanceof($group, 'group')) { +		forward(); +	} + +	group_gatekeeper(); + +	$title = elgg_echo('groups:activity'); + +	elgg_push_breadcrumb($group->name, $group->getURL()); +	elgg_push_breadcrumb($title); + +	$db_prefix = elgg_get_config('dbprefix'); + +	$content = elgg_list_river(array( +		'joins' => array("JOIN {$db_prefix}entities e ON e.guid = rv.object_guid"), +		'wheres' => array("e.container_guid = $guid") +	)); +	if (!$content) { +		$content = '<p>' . elgg_echo('groups:activity:none') . '</p>'; +	} + +	$params = array( +		'content' => $content, +		'title' => $title, +		'filter' => '', +	); +	$body = elgg_view_layout('content', $params); + +	echo elgg_view_page($title, $body); +} + +/** + * Group members page + * + * @param int $guid Group entity GUID + */ +function groups_handle_members_page($guid) { + +	elgg_set_page_owner_guid($guid); + +	$group = get_entity($guid); +	if (!$group || !elgg_instanceof($group, 'group')) { +		forward(); +	} + +	group_gatekeeper(); + +	$title = elgg_echo('groups:members:title', array($group->name)); + +	elgg_push_breadcrumb($group->name, $group->getURL()); +	elgg_push_breadcrumb(elgg_echo('groups:members')); + +	$db_prefix = elgg_get_config('dbprefix'); +	$content = elgg_list_entities_from_relationship(array( +		'relationship' => 'member', +		'relationship_guid' => $group->guid, +		'inverse_relationship' => true, +		'type' => 'user', +		'limit' => 20, +		'joins' => array("JOIN {$db_prefix}users_entity u ON e.guid=u.guid"), +		'order_by' => 'u.name ASC', +	)); + +	$params = array( +		'content' => $content, +		'title' => $title, +		'filter' => '', +	); +	$body = elgg_view_layout('content', $params); + +	echo elgg_view_page($title, $body); +} + +/** + * Invite users to a group + * + * @param int $guid Group entity GUID + */ +function groups_handle_invite_page($guid) { +	gatekeeper(); + +	elgg_set_page_owner_guid($guid); + +	$group = get_entity($guid); + +	$title = elgg_echo('groups:invite:title'); + +	elgg_push_breadcrumb($group->name, $group->getURL()); +	elgg_push_breadcrumb(elgg_echo('groups:invite')); + +	if ($group && $group->canEdit()) { +		$content = elgg_view_form('groups/invite', array( +			'id' => 'invite_to_group', +			'class' => 'elgg-form-alt mtm', +		), array( +			'entity' => $group, +		)); +	} else { +		$content .= elgg_echo('groups:noaccess'); +	} + +	$params = array( +		'content' => $content, +		'title' => $title, +		'filter' => '', +	); +	$body = elgg_view_layout('content', $params); + +	echo elgg_view_page($title, $body); +} + +/** + * Manage requests to join a group + * + * @param int $guid Group entity GUID + */ +function groups_handle_requests_page($guid) { + +	gatekeeper(); + +	elgg_set_page_owner_guid($guid); + +	$group = get_entity($guid); + +	$title = elgg_echo('groups:membershiprequests'); + +	if ($group && $group->canEdit()) { +		elgg_push_breadcrumb($group->name, $group->getURL()); +		elgg_push_breadcrumb($title); + +		$requests = elgg_get_entities_from_relationship(array( +			'type' => 'user', +			'relationship' => 'membership_request', +			'relationship_guid' => $guid, +			'inverse_relationship' => true, +			'limit' => 0, +		)); +		$content = elgg_view('groups/membershiprequests', array( +			'requests' => $requests, +			'entity' => $group, +		)); + +	} else { +		$content = elgg_echo("groups:noaccess"); +	} + +	$params = array( +		'content' => $content, +		'title' => $title, +		'filter' => '', +	); +	$body = elgg_view_layout('content', $params); + +	echo elgg_view_page($title, $body); +} + +/** + * Registers the buttons for title area of the group profile page + * + * @param ElggGroup $group + */ +function groups_register_profile_buttons($group) { + +	$actions = array(); + +	// group owners +	if ($group->canEdit()) { +		// edit and invite +		$url = elgg_get_site_url() . "groups/edit/{$group->getGUID()}"; +		$actions[$url] = 'groups:edit'; +		$url = elgg_get_site_url() . "groups/invite/{$group->getGUID()}"; +		$actions[$url] = 'groups:invite'; +	} + +	// group members +	if ($group->isMember(elgg_get_logged_in_user_entity())) { +		if ($group->getOwnerGUID() != elgg_get_logged_in_user_guid()) { +			// leave +			$url = elgg_get_site_url() . "action/groups/leave?group_guid={$group->getGUID()}"; +			$url = elgg_add_action_tokens_to_url($url); +			$actions[$url] = 'groups:leave'; +		} +	} elseif (elgg_is_logged_in()) { +		// join - admins can always join. +		$url = elgg_get_site_url() . "action/groups/join?group_guid={$group->getGUID()}"; +		$url = elgg_add_action_tokens_to_url($url); +		if ($group->isPublicMembership() || $group->canEdit()) { +			$actions[$url] = 'groups:join'; +		} else { +			// request membership +			$actions[$url] = 'groups:joinrequest'; +		} +	} + +	if ($actions) { +		foreach ($actions as $url => $text) { +			elgg_register_menu_item('title', array( +				'name' => $text, +				'href' => $url, +				'text' => elgg_echo($text), +				'link_class' => 'elgg-button elgg-button-action', +			)); +		} +	} +} + +/** + * Prepares variables for the group edit form view. + * + * @param mixed $group ElggGroup or null. If a group, uses values from the group. + * @return array + */ +function groups_prepare_form_vars($group = null) { +	$values = array( +		'name' => '', +		'membership' => ACCESS_PUBLIC, +		'vis' => ACCESS_PUBLIC, +		'guid' => null, +		'entity' => null +	); + +	// handle customizable profile fields +	$fields = elgg_get_config('group'); + +	if ($fields) { +		foreach ($fields as $name => $type) { +			$values[$name] = ''; +		} +	} + +	// handle tool options +	$tools = elgg_get_config('group_tool_options'); +	if ($tools) { +		foreach ($tools as $group_option) { +			$option_name = $group_option->name . "_enable"; +			$values[$option_name] = $group_option->default_on ? 'yes' : 'no'; +		} +	} + +	// get current group settings +	if ($group) { +		foreach (array_keys($values) as $field) { +			if (isset($group->$field)) { +				$values[$field] = $group->$field; +			} +		} + +		if ($group->access_id != ACCESS_PUBLIC && $group->access_id != ACCESS_LOGGED_IN) { +			// group only access - this is done to handle access not created when group is created +			$values['vis'] = ACCESS_PRIVATE; +		} else { +			$values['vis'] = $group->access_id; +		} + +		$values['entity'] = $group; +	} + +	// get any sticky form settings +	if (elgg_is_sticky_form('groups')) { +		$sticky_values = elgg_get_sticky_values('groups'); +		foreach ($sticky_values as $key => $value) { +			$values[$key] = $value; +		} +	} + +	elgg_clear_sticky_form('groups'); + +	return $values; +} diff --git a/mod/groups/manifest.xml b/mod/groups/manifest.xml new file mode 100644 index 000000000..fd28360d0 --- /dev/null +++ b/mod/groups/manifest.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="UTF-8"?> +<plugin_manifest xmlns="http://www.elgg.org/plugin_manifest/1.8"> +	<name>Groups</name> +	<author>Core developers</author> +	<version>1.8</version> +	<category>bundled</category> +	<category>social</category> +	<category>widget</category> +	<description>Provides group support for elgg</description> +	<website>http://www.elgg.org/</website> +	<copyright>See COPYRIGHT.txt</copyright> +	<license>GNU General Public License version 2</license> +	<requires> +		<type>elgg_release</type> +		<version>1.8</version> +	</requires> +	<activate_on_install>true</activate_on_install> +</plugin_manifest> diff --git a/mod/groups/start.php b/mod/groups/start.php new file mode 100644 index 000000000..6002a535c --- /dev/null +++ b/mod/groups/start.php @@ -0,0 +1,1073 @@ +<?php +/** + * Elgg groups plugin + * + * @package ElggGroups + */ + +elgg_register_event_handler('init', 'system', 'groups_init'); + +// Ensure this runs after other plugins +elgg_register_event_handler('init', 'system', 'groups_fields_setup', 10000); + +/** + * Initialize the groups plugin. + */ +function groups_init() { + +	elgg_register_library('elgg:groups', elgg_get_plugins_path() . 'groups/lib/groups.php'); + +	// register group entities for search +	elgg_register_entity_type('group', ''); + +	// Set up the menu +	$item = new ElggMenuItem('groups', elgg_echo('groups'), 'groups/all'); +	elgg_register_menu_item('site', $item); + +	// Register a page handler, so we can have nice URLs +	elgg_register_page_handler('groups', 'groups_page_handler'); + +	// Register URL handlers for groups +	elgg_register_entity_url_handler('group', 'all', 'groups_url'); +	elgg_register_plugin_hook_handler('entity:icon:url', 'group', 'groups_icon_url_override'); + +	// Register an icon handler for groups +	elgg_register_page_handler('groupicon', 'groups_icon_handler'); + +	// Register some actions +	$action_base = elgg_get_plugins_path() . 'groups/actions/groups'; +	elgg_register_action("groups/edit", "$action_base/edit.php"); +	elgg_register_action("groups/delete", "$action_base/delete.php"); +	elgg_register_action("groups/featured", "$action_base/featured.php", 'admin'); + +	$action_base .= '/membership'; +	elgg_register_action("groups/invite", "$action_base/invite.php"); +	elgg_register_action("groups/join", "$action_base/join.php"); +	elgg_register_action("groups/leave", "$action_base/leave.php"); +	elgg_register_action("groups/remove", "$action_base/remove.php"); +	elgg_register_action("groups/killrequest", "$action_base/delete_request.php"); +	elgg_register_action("groups/killinvitation", "$action_base/delete_invite.php"); +	elgg_register_action("groups/addtogroup", "$action_base/add.php"); + +	// Add some widgets +	elgg_register_widget_type('a_users_groups', elgg_echo('groups:widget:membership'), elgg_echo('groups:widgets:description')); + +	// add group activity tool option +	add_group_tool_option('activity', elgg_echo('groups:enableactivity'), true); +	elgg_extend_view('groups/tool_latest', 'groups/profile/activity_module'); + +	// add link to owner block +	elgg_register_plugin_hook_handler('register', 'menu:owner_block', 'groups_activity_owner_block_menu'); + +	// group entity menu +	elgg_register_plugin_hook_handler('register', 'menu:entity', 'groups_entity_menu_setup'); +	 +	// group user hover menu	 +	elgg_register_plugin_hook_handler('register', 'menu:user_hover', 'groups_user_entity_menu_setup'); + +	// delete and edit annotations for topic replies +	elgg_register_plugin_hook_handler('register', 'menu:annotation', 'groups_annotation_menu_setup'); + +	//extend some views +	elgg_extend_view('css/elgg', 'groups/css'); +	elgg_extend_view('js/elgg', 'groups/js'); + +	// Access permissions +	elgg_register_plugin_hook_handler('access:collections:write', 'all', 'groups_write_acl_plugin_hook'); +	//elgg_register_plugin_hook_handler('access:collections:read', 'all', 'groups_read_acl_plugin_hook'); + +	// Register profile menu hook +	elgg_register_plugin_hook_handler('profile_menu', 'profile', 'forum_profile_menu'); +	elgg_register_plugin_hook_handler('profile_menu', 'profile', 'activity_profile_menu'); + +	// allow ecml in discussion and profiles +	elgg_register_plugin_hook_handler('get_views', 'ecml', 'groups_ecml_views_hook'); +	elgg_register_plugin_hook_handler('get_views', 'ecml', 'groupprofile_ecml_views_hook'); + +	// Register a handler for create groups +	elgg_register_event_handler('create', 'group', 'groups_create_event_listener'); + +	// Register a handler for delete groups +	elgg_register_event_handler('delete', 'group', 'groups_delete_event_listener'); +	 +	elgg_register_event_handler('join', 'group', 'groups_user_join_event_listener'); +	elgg_register_event_handler('leave', 'group', 'groups_user_leave_event_listener'); +	elgg_register_event_handler('pagesetup', 'system', 'groups_setup_sidebar_menus'); + +	elgg_register_plugin_hook_handler('access:collections:add_user', 'collection', 'groups_access_collection_override'); + +	elgg_register_event_handler('upgrade', 'system', 'groups_run_upgrades'); +} + +/** + * This function loads a set of default fields into the profile, then triggers + * a hook letting other plugins to edit add and delete fields. + * + * Note: This is a system:init event triggered function and is run at a super + * low priority to guarantee that it is called after all other plugins have + * initialized. + */ +function groups_fields_setup() { + +	$profile_defaults = array( +		'description' => 'longtext', +		'briefdescription' => 'text', +		'interests' => 'tags', +		//'website' => 'url', +	); + +	$profile_defaults = elgg_trigger_plugin_hook('profile:fields', 'group', NULL, $profile_defaults); + +	elgg_set_config('group', $profile_defaults); + +	// register any tag metadata names +	foreach ($profile_defaults as $name => $type) { +		if ($type == 'tags') { +			elgg_register_tag_metadata_name($name); + +			// only shows up in search but why not just set this in en.php as doing it here +			// means you cannot override it in a plugin +			add_translation(get_current_language(), array("tag_names:$name" => elgg_echo("groups:$name"))); +		} +	} +} + +/** + * Configure the groups sidebar menu. Triggered on page setup + * + */ +function groups_setup_sidebar_menus() { + +	// Get the page owner entity +	$page_owner = elgg_get_page_owner_entity(); + +	if (elgg_in_context('group_profile')) { +		if (!elgg_instanceof($page_owner, 'group')) { +			forward('', '404'); +		} + +		if (elgg_is_logged_in() && $page_owner->canEdit() && !$page_owner->isPublicMembership()) { +			$url = elgg_get_site_url() . "groups/requests/{$page_owner->getGUID()}"; + +			$count = elgg_get_entities_from_relationship(array( +				'type' => 'user', +				'relationship' => 'membership_request', +				'relationship_guid' => $page_owner->getGUID(), +				'inverse_relationship' => true, +				'count' => true, +			)); + +			if ($count) { +				$text = elgg_echo('groups:membershiprequests:pending', array($count)); +			} else { +				$text = elgg_echo('groups:membershiprequests'); +			} + +			elgg_register_menu_item('page', array( +				'name' => 'membership_requests', +				'text' => $text, +				'href' => $url, +			)); +		} +	} +	if (elgg_get_context() == 'groups' && !elgg_instanceof($page_owner, 'group')) { +		elgg_register_menu_item('page', array( +			'name' => 'groups:all', +			'text' => elgg_echo('groups:all'), +			'href' => 'groups/all', +		)); + +		$user = elgg_get_logged_in_user_entity(); +		if ($user) { +			$url =  "groups/owner/$user->username"; +			$item = new ElggMenuItem('groups:owned', elgg_echo('groups:owned'), $url); +			elgg_register_menu_item('page', $item); +			 +			$url = "groups/member/$user->username"; +			$item = new ElggMenuItem('groups:member', elgg_echo('groups:yours'), $url); +			elgg_register_menu_item('page', $item); + +			$url = "groups/invitations/$user->username"; +			$invitations = groups_get_invited_groups($user->getGUID()); +			if (is_array($invitations) && !empty($invitations)) { +				$invitation_count = count($invitations); +				$text = elgg_echo('groups:invitations:pending', array($invitation_count)); +			} else { +				$text = elgg_echo('groups:invitations'); +			} + +			$item = new ElggMenuItem('groups:user:invites', $text, $url); +			elgg_register_menu_item('page', $item); +		} +	} +} + +/** + * Groups page handler + * + * URLs take the form of + *  All groups:           groups/all + *  User's owned groups:  groups/owner/<username> + *  User's member groups: groups/member/<username> + *  Group profile:        groups/profile/<guid>/<title> + *  New group:            groups/add/<guid> + *  Edit group:           groups/edit/<guid> + *  Group invitations:    groups/invitations/<username> + *  Invite to group:      groups/invite/<guid> + *  Membership requests:  groups/requests/<guid> + *  Group activity:       groups/activity/<guid> + *  Group members:        groups/members/<guid> + * + * @param array $page Array of url segments for routing + * @return bool + */ +function groups_page_handler($page) { + +	// forward old profile urls +	if (is_numeric($page[0])) { +		$group = get_entity($page[0]); +		if (elgg_instanceof($group, 'group', '', 'ElggGroup')) { +			system_message(elgg_echo('changebookmark')); +			forward($group->getURL()); +		} +	} +	 +	elgg_load_library('elgg:groups'); + +	if (!isset($page[0])) { +		$page[0] = 'all'; +	} + +	elgg_push_breadcrumb(elgg_echo('groups'), "groups/all"); + +	switch ($page[0]) { +		case 'all': +			groups_handle_all_page(); +			break; +		case 'search': +			groups_search_page(); +			break; +		case 'owner': +			groups_handle_owned_page(); +			break; +		case 'member': +			set_input('username', $page[1]); +			groups_handle_mine_page(); +			break; +		case 'invitations': +			set_input('username', $page[1]); +			groups_handle_invitations_page(); +			break; +		case 'add': +			groups_handle_edit_page('add'); +			break; +		case 'edit': +			groups_handle_edit_page('edit', $page[1]); +			break; +		case 'profile': +			groups_handle_profile_page($page[1]); +			break; +		case 'activity': +			groups_handle_activity_page($page[1]); +			break; +		case 'members': +			groups_handle_members_page($page[1]); +			break; +		case 'invite': +			groups_handle_invite_page($page[1]); +			break; +		case 'requests': +			groups_handle_requests_page($page[1]); +			break; +		default: +			return false; +	} +	return true; +} + +/** + * Handle group icons. + * + * @param array $page + * @return void + */ +function groups_icon_handler($page) { + +	// The username should be the file we're getting +	if (isset($page[0])) { +		set_input('group_guid', $page[0]); +	} +	if (isset($page[1])) { +		set_input('size', $page[1]); +	} +	// Include the standard profile index +	$plugin_dir = elgg_get_plugins_path(); +	include("$plugin_dir/groups/icon.php"); +	return true; +} + +/** + * Populates the ->getUrl() method for group objects + * + * @param ElggEntity $entity File entity + * @return string File URL + */ +function groups_url($entity) { +	$title = elgg_get_friendly_title($entity->name); + +	return "groups/profile/{$entity->guid}/$title"; +} + +/** + * Override the default entity icon for groups + * + * @return string Relative URL + */ +function groups_icon_url_override($hook, $type, $returnvalue, $params) { +	/* @var ElggGroup $group */ +	$group = $params['entity']; +	$size = $params['size']; + +	$icontime = $group->icontime; +	// handle missing metadata (pre 1.7 installations) +	if (null === $icontime) { +		$file = new ElggFile(); +		$file->owner_guid = $group->owner_guid; +		$file->setFilename("groups/" . $group->guid . "large.jpg"); +		$icontime = $file->exists() ? time() : 0; +		create_metadata($group->guid, 'icontime', $icontime, 'integer', $group->owner_guid, ACCESS_PUBLIC); +	} +	if ($icontime) { +		// return thumbnail +		return "groupicon/$group->guid/$size/$icontime.jpg"; +	} + +	return "mod/groups/graphics/default{$size}.gif"; +} + +/** + * Add owner block link + */ +function groups_activity_owner_block_menu($hook, $type, $return, $params) { +	if (elgg_instanceof($params['entity'], 'group')) { +		if ($params['entity']->activity_enable != "no") { +			$url = "groups/activity/{$params['entity']->guid}"; +			$item = new ElggMenuItem('activity', elgg_echo('groups:activity'), $url); +			$return[] = $item; +		} +	} + +	return $return; +} + +/** + * Add links/info to entity menu particular to group entities + */ +function groups_entity_menu_setup($hook, $type, $return, $params) { +	if (elgg_in_context('widgets')) { +		return $return; +	} + +	$entity = $params['entity']; +	$handler = elgg_extract('handler', $params, false); +	if ($handler != 'groups') { +		return $return; +	} + +	foreach ($return as $index => $item) { +		if (in_array($item->getName(), array('access', 'likes', 'edit', 'delete'))) { +			unset($return[$index]); +		} +	} + +	// membership type +	$membership = $entity->membership; +	if ($membership == ACCESS_PUBLIC) { +		$mem = elgg_echo("groups:open"); +	} else { +		$mem = elgg_echo("groups:closed"); +	} +	$options = array( +		'name' => 'membership', +		'text' => $mem, +		'href' => false, +		'priority' => 100, +	); +	$return[] = ElggMenuItem::factory($options); + +	// number of members +	$num_members = get_group_members($entity->guid, 10, 0, 0, true); +	$members_string = elgg_echo('groups:member'); +	$options = array( +		'name' => 'members', +		'text' => $num_members . ' ' . $members_string, +		'href' => false, +		'priority' => 200, +	); +	$return[] = ElggMenuItem::factory($options); + +	// feature link +	if (elgg_is_admin_logged_in()) { +		if ($entity->featured_group == "yes") { +			$url = "action/groups/featured?group_guid={$entity->guid}&action_type=unfeature"; +			$wording = elgg_echo("groups:makeunfeatured"); +		} else { +			$url = "action/groups/featured?group_guid={$entity->guid}&action_type=feature"; +			$wording = elgg_echo("groups:makefeatured"); +		} +		$options = array( +			'name' => 'feature', +			'text' => $wording, +			'href' => $url, +			'priority' => 300, +			'is_action' => true +		); +		$return[] = ElggMenuItem::factory($options); +	} + +	return $return; +} + +/** + * Add a remove user link to user hover menu when the page owner is a group + */ +function groups_user_entity_menu_setup($hook, $type, $return, $params) { +	if (elgg_is_logged_in()) { +		$group = elgg_get_page_owner_entity(); +		 +		// Check for valid group +		if (!elgg_instanceof($group, 'group')) { +			return $return; +		} +	 +		$entity = $params['entity']; +		 +		// Make sure we have a user and that user is a member of the group +		if (!elgg_instanceof($entity, 'user') || !$group->isMember($entity)) { +			return $return; +		} + +		// Add remove link if we can edit the group, and if we're not trying to remove the group owner +		if ($group->canEdit() && $group->getOwnerGUID() != $entity->guid) { +			$remove = elgg_view('output/confirmlink', array( +				'href' => "action/groups/remove?user_guid={$entity->guid}&group_guid={$group->guid}", +				'text' => elgg_echo('groups:removeuser'), +			)); + +			$options = array( +				'name' => 'removeuser', +				'text' => $remove, +				'priority' => 999, +			); +			$return[] = ElggMenuItem::factory($options); +		}  +	} + +	return $return; +} + +/** + * Add edit and delete links for forum replies + */ +function groups_annotation_menu_setup($hook, $type, $return, $params) { +	if (elgg_in_context('widgets')) { +		return $return; +	} +	 +	$annotation = $params['annotation']; + +	if ($annotation->name != 'group_topic_post') { +		return $return; +	} + +	if ($annotation->canEdit()) { +		$url = elgg_http_add_url_query_elements('action/discussion/reply/delete', array( +			'annotation_id' => $annotation->id, +		)); + +		$options = array( +			'name' => 'delete', +			'href' => $url, +			'text' => "<span class=\"elgg-icon elgg-icon-delete\"></span>", +			'confirm' => elgg_echo('deleteconfirm'), +			'encode_text' => false +		); +		$return[] = ElggMenuItem::factory($options); + +		$url = elgg_http_add_url_query_elements('discussion', array( +			'annotation_id' => $annotation->id, +		)); + +		$options = array( +			'name' => 'edit', +			'href' => "#edit-annotation-$annotation->id", +			'text' => elgg_echo('edit'), +			'encode_text' => false, +			'rel' => 'toggle', +		); +		$return[] = ElggMenuItem::factory($options); +	} + +	return $return; +} + +/** + * Groups created so create an access list for it + */ +function groups_create_event_listener($event, $object_type, $object) { +	$ac_name = elgg_echo('groups:group') . ": " . $object->name; +	$group_id = create_access_collection($ac_name, $object->guid); +	if ($group_id) { +		$object->group_acl = $group_id; +	} else { +		// delete group if access creation fails +		return false; +	} + +	return true; +} + +/** + * Hook to listen to read access control requests and return all the groups you are a member of. + */ +function groups_read_acl_plugin_hook($hook, $entity_type, $returnvalue, $params) { +	//error_log("READ: " . var_export($returnvalue)); +	$user = elgg_get_logged_in_user_entity(); +	if ($user) { +		// Not using this because of recursion. +		// Joining a group automatically add user to ACL, +		// So just see if they're a member of the ACL. +		//$membership = get_users_membership($user->guid); + +		$members = get_members_of_access_collection($group->group_acl); +		print_r($members); +		exit; + +		if ($membership) { +			foreach ($membership as $group) +				$returnvalue[$user->guid][$group->group_acl] = elgg_echo('groups:group') . ": " . $group->name; +			return $returnvalue; +		} +	} +} + +/** + * Return the write access for the current group if the user has write access to it. + */ +function groups_write_acl_plugin_hook($hook, $entity_type, $returnvalue, $params) { +	$page_owner = elgg_get_page_owner_entity(); +	$user_guid = $params['user_id']; +	$user = get_entity($user_guid); +	if (!$user) { +		return $returnvalue; +	} + +	// only insert group access for current group +	if ($page_owner instanceof ElggGroup) { +		if ($page_owner->canWriteToContainer($user_guid)) { +			$returnvalue[$page_owner->group_acl] = elgg_echo('groups:group') . ': ' . $page_owner->name; + +			unset($returnvalue[ACCESS_FRIENDS]); +		} +	} else { +		// if the user owns the group, remove all access collections manually +		// this won't be a problem once the group itself owns the acl. +		$groups = elgg_get_entities_from_relationship(array( +					'relationship' => 'member', +					'relationship_guid' => $user_guid, +					'inverse_relationship' => FALSE, +					'limit' => false +				)); + +		if ($groups) { +			foreach ($groups as $group) { +				unset($returnvalue[$group->group_acl]); +			} +		} +	} + +	return $returnvalue; +} + +/** + * Groups deleted, so remove access lists. + */ +function groups_delete_event_listener($event, $object_type, $object) { +	delete_access_collection($object->group_acl); + +	return true; +} + +/** + * Listens to a group join event and adds a user to the group's access control + * + */ +function groups_user_join_event_listener($event, $object_type, $object) { + +	$group = $object['group']; +	$user = $object['user']; +	$acl = $group->group_acl; + +	add_user_to_access_collection($user->guid, $acl); + +	return true; +} + +/** + * Make sure users are added to the access collection + */ +function groups_access_collection_override($hook, $entity_type, $returnvalue, $params) { +	if (isset($params['collection'])) { +		if (elgg_instanceof(get_entity($params['collection']->owner_guid), 'group')) { +			return true; +		} +	} +} + +/** + * Listens to a group leave event and removes a user from the group's access control + * + */ +function groups_user_leave_event_listener($event, $object_type, $object) { + +	$group = $object['group']; +	$user = $object['user']; +	$acl = $group->group_acl; + +	remove_user_from_access_collection($user->guid, $acl); + +	return true; +} + +/** + * Grabs groups by invitations + * Have to override all access until there's a way override access to getter functions. + * + * @param int  $user_guid    The user's guid + * @param bool $return_guids Return guids rather than ElggGroup objects + * + * @return array ElggGroups or guids depending on $return_guids + */ +function groups_get_invited_groups($user_guid, $return_guids = FALSE) { +	$ia = elgg_set_ignore_access(TRUE); +	$groups = elgg_get_entities_from_relationship(array( +		'relationship' => 'invited', +		'relationship_guid' => $user_guid, +		'inverse_relationship' => TRUE, +		'limit' => 0, +	)); +	elgg_set_ignore_access($ia); + +	if ($return_guids) { +		$guids = array(); +		foreach ($groups as $group) { +			$guids[] = $group->getGUID(); +		} + +		return $guids; +	} + +	return $groups; +} + +/** + * Join a user to a group, add river event, clean-up invitations + * + * @param ElggGroup $group + * @param ElggUser  $user + * @return bool + */ +function groups_join_group($group, $user) { + +	// access ignore so user can be added to access collection of invisible group +	$ia = elgg_set_ignore_access(TRUE); +	$result = $group->join($user); +	elgg_set_ignore_access($ia); +	 +	if ($result) { +		// flush user's access info so the collection is added +		get_access_list($user->guid, 0, true); + +		// Remove any invite or join request flags +		remove_entity_relationship($group->guid, 'invited', $user->guid); +		remove_entity_relationship($user->guid, 'membership_request', $group->guid); + +		add_to_river('river/relationship/member/create', 'join', $user->guid, $group->guid); + +		return true; +	} + +	return false; +} + +/** + * Function to use on groups for access. It will house private, loggedin, public, + * and the group itself. This is when you don't want other groups or access lists + * in the access options available. + * + * @return array + */ +function group_access_options($group) { +	$access_array = array( +		ACCESS_PRIVATE => 'private', +		ACCESS_LOGGED_IN => 'logged in users', +		ACCESS_PUBLIC => 'public', +		$group->group_acl => elgg_echo('groups:acl', array($group->name)), +	); +	return $access_array; +} + +function activity_profile_menu($hook, $entity_type, $return_value, $params) { + +	if ($params['owner'] instanceof ElggGroup) { +		$return_value[] = array( +			'text' => elgg_echo('Activity'), +			'href' => "groups/activity/{$params['owner']->getGUID()}" +		); +	} +	return $return_value; +} + +/** + * Parse ECML on group discussion views + */ +function groups_ecml_views_hook($hook, $entity_type, $return_value, $params) { +	$return_value['forum/viewposts'] = elgg_echo('groups:ecml:discussion'); + +	return $return_value; +} + +/** + * Parse ECML on group profiles + */ +function groupprofile_ecml_views_hook($hook, $entity_type, $return_value, $params) { +	$return_value['groups/groupprofile'] = elgg_echo('groups:ecml:groupprofile'); + +	return $return_value; +} + + + +/** + * Discussion + * + */ + +elgg_register_event_handler('init', 'system', 'discussion_init'); + +/** + * Initialize the discussion component + */ +function discussion_init() { + +	elgg_register_library('elgg:discussion', elgg_get_plugins_path() . 'groups/lib/discussion.php'); + +	elgg_register_page_handler('discussion', 'discussion_page_handler'); +	elgg_register_page_handler('forum', 'discussion_forum_page_handler'); + +	elgg_register_entity_url_handler('object', 'groupforumtopic', 'discussion_override_topic_url'); + +	// commenting not allowed on discussion topics (use a different annotation) +	elgg_register_plugin_hook_handler('permissions_check:comment', 'object', 'discussion_comment_override'); +	 +	$action_base = elgg_get_plugins_path() . 'groups/actions/discussion'; +	elgg_register_action('discussion/save', "$action_base/save.php"); +	elgg_register_action('discussion/delete', "$action_base/delete.php"); +	elgg_register_action('discussion/reply/save', "$action_base/reply/save.php"); +	elgg_register_action('discussion/reply/delete', "$action_base/reply/delete.php"); + +	// add link to owner block +	elgg_register_plugin_hook_handler('register', 'menu:owner_block', 'discussion_owner_block_menu'); + +	// Register for search. +	elgg_register_entity_type('object', 'groupforumtopic'); + +	// because replies are not comments, need of our menu item +	elgg_register_plugin_hook_handler('register', 'menu:river', 'discussion_add_to_river_menu'); + +	// add the forum tool option +	add_group_tool_option('forum', elgg_echo('groups:enableforum'), true); +	elgg_extend_view('groups/tool_latest', 'discussion/group_module'); + +	// notifications +	register_notification_object('object', 'groupforumtopic', elgg_echo('discussion:notification:topic:subject')); +	elgg_register_plugin_hook_handler('notify:entity:message', 'object', 'groupforumtopic_notify_message'); +	elgg_register_event_handler('create', 'annotation', 'discussion_reply_notifications'); +	elgg_register_plugin_hook_handler('notify:annotation:message', 'group_topic_post', 'discussion_create_reply_notification'); +} + +/** + * Exists for backwards compatibility for Elgg 1.7 + */ +function discussion_forum_page_handler($page) { +	switch ($page[0]) { +		case 'topic': +			header('Status: 301 Moved Permanently'); +			forward("/discussion/view/{$page[1]}/{$page[2]}"); +			break; +		default: +			return false; +	} +} + +/** + * Discussion page handler + * + * URLs take the form of + *  All topics in site:    discussion/all + *  List topics in forum:  discussion/owner/<guid> + *  View discussion topic: discussion/view/<guid> + *  Add discussion topic:  discussion/add/<guid> + *  Edit discussion topic: discussion/edit/<guid> + * + * @param array $page Array of url segments for routing + * @return bool + */ +function discussion_page_handler($page) { + +	elgg_load_library('elgg:discussion'); + +	if (!isset($page[0])) { +		$page[0] = 'all'; +	} + +	elgg_push_breadcrumb(elgg_echo('discussion'), 'discussion/all'); + +	switch ($page[0]) { +		case 'all': +			discussion_handle_all_page(); +			break; +		case 'owner': +			discussion_handle_list_page($page[1]); +			break; +		case 'add': +			discussion_handle_edit_page('add', $page[1]); +			break; +		case 'edit': +			discussion_handle_edit_page('edit', $page[1]); +			break; +		case 'view': +			discussion_handle_view_page($page[1]); +			break; +		default: +			return false; +	} +	return true; +} + +/** + * Override the discussion topic url + * + * @param ElggObject $entity Discussion topic + * @return string + */ +function discussion_override_topic_url($entity) { +	return 'discussion/view/' . $entity->guid . '/' . elgg_get_friendly_title($entity->title); +} + +/** + * We don't want people commenting on topics in the river + */ +function discussion_comment_override($hook, $type, $return, $params) { +	if (elgg_instanceof($params['entity'], 'object', 'groupforumtopic')) { +		return false; +	} +} + +/** + * Add owner block link + */ +function discussion_owner_block_menu($hook, $type, $return, $params) { +	if (elgg_instanceof($params['entity'], 'group')) { +		if ($params['entity']->forum_enable != "no") { +			$url = "discussion/owner/{$params['entity']->guid}"; +			$item = new ElggMenuItem('discussion', elgg_echo('discussion:group'), $url); +			$return[] = $item; +		} +	} + +	return $return; +} + +/** + * Add the reply button for the river + */ +function discussion_add_to_river_menu($hook, $type, $return, $params) { +	if (elgg_is_logged_in() && !elgg_in_context('widgets')) { +		$item = $params['item']; +		$object = $item->getObjectEntity(); +		if (elgg_instanceof($object, 'object', 'groupforumtopic')) { +			if ($item->annotation_id == 0) { +				$group = $object->getContainerEntity(); +				if ($group && ($group->canWriteToContainer() || elgg_is_admin_logged_in())) { +					$options = array( +						'name' => 'reply', +						'href' => "#groups-reply-$object->guid", +						'text' => elgg_view_icon('speech-bubble'), +						'title' => elgg_echo('reply:this'), +						'rel' => 'toggle', +						'priority' => 50, +					); +					$return[] = ElggMenuItem::factory($options); +				} +			} +		} +	} + +	return $return; +} + +/** + * Create discussion notification body + * + * @todo namespace method with 'discussion' + * + * @param string $hook + * @param string $type + * @param string $message + * @param array  $params + */ +function groupforumtopic_notify_message($hook, $type, $message, $params) { +	$entity = $params['entity']; +	$to_entity = $params['to_entity']; +	$method = $params['method']; + +	if (($entity instanceof ElggEntity) && ($entity->getSubtype() == 'groupforumtopic')) { +		$descr = $entity->description; +		$title = $entity->title; +		$url = $entity->getURL(); +		$owner = $entity->getOwnerEntity(); +		$group = $entity->getContainerEntity(); + +		return elgg_echo('groups:notification', array( +			$owner->name, +			$group->name, +			$entity->title, +			$entity->description, +			$entity->getURL() +		)); +	} + +	return null; +} + +/** + * Create discussion reply notification body + * + * @param string $hook + * @param string $type + * @param string $message + * @param array  $params + */ +function discussion_create_reply_notification($hook, $type, $message, $params) { +	$reply = $params['annotation']; +	$method = $params['method']; +	$topic = $reply->getEntity(); +	$poster = $reply->getOwnerEntity(); +	$group = $topic->getContainerEntity(); + +	return elgg_echo('discussion:notification:reply:body', array( +		$poster->name, +		$topic->title, +		$group->name, +		$reply->value, +		$topic->getURL(), +	)); +} + +/** + * Catch reply to discussion topic and generate notifications + * + * @todo this will be replaced in Elgg 1.9 and is a clone of object_notifications() + * + * @param string         $event + * @param string         $type + * @param ElggAnnotation $annotation + * @return void + */ +function discussion_reply_notifications($event, $type, $annotation) { +	global $CONFIG, $NOTIFICATION_HANDLERS; + +	if ($annotation->name !== 'group_topic_post') { +		return; +	} + +	// Have we registered notifications for this type of entity? +	$object_type = 'object'; +	$object_subtype = 'groupforumtopic'; + +	$topic = $annotation->getEntity(); +	if (!$topic) { +		return; +	} + +	$poster = $annotation->getOwnerEntity(); +	if (!$poster) { +		return; +	} + +	if (isset($CONFIG->register_objects[$object_type][$object_subtype])) { +		$subject = $CONFIG->register_objects[$object_type][$object_subtype]; +		$string = $subject . ": " . $topic->getURL(); + +		// Get users interested in content from this person and notify them +		// (Person defined by container_guid so we can also subscribe to groups if we want) +		foreach ($NOTIFICATION_HANDLERS as $method => $foo) { +			$interested_users = elgg_get_entities_from_relationship(array( +				'relationship' => 'notify' . $method, +				'relationship_guid' => $topic->getContainerGUID(), +				'inverse_relationship' => true, +				'type' => 'user', +				'limit' => 0, +			)); + +			if ($interested_users && is_array($interested_users)) { +				foreach ($interested_users as $user) { +					if ($user instanceof ElggUser && !$user->isBanned()) { +						if (($user->guid != $poster->guid) && has_access_to_entity($topic, $user) && $topic->access_id != ACCESS_PRIVATE) { +							$body = elgg_trigger_plugin_hook('notify:annotation:message', $annotation->getSubtype(), array( +								'annotation' => $annotation, +								'to_entity' => $user, +								'method' => $method), $string); +							if (empty($body) && $body !== false) { +								$body = $string; +							} +							if ($body !== false) { +								notify_user($user->guid, $topic->getContainerGUID(), $subject, $body, null, array($method)); +							} +						} +					} +				} +			} +		} +	} +} + +/** + * A simple function to see who can edit a group discussion post + * @param the comment $entity + * @param user who owns the group $group_owner + * @return boolean + */ +function groups_can_edit_discussion($entity, $group_owner) { + +	//logged in user +	$user = elgg_get_logged_in_user_guid(); + +	if (($entity->owner_guid == $user) || $group_owner == $user || elgg_is_admin_logged_in()) { +		return true; +	} else { +		return false; +	} +} + +/** + * Process upgrades for the groups plugin + */ +function groups_run_upgrades() { +	$path = elgg_get_plugins_path() . 'groups/upgrades/'; +	$files = elgg_get_upgrade_files($path); +	foreach ($files as $file) { +		include "$path{$file}"; +	} +} diff --git a/mod/groups/topicposts.php b/mod/groups/topicposts.php new file mode 100644 index 000000000..d0137e2f5 --- /dev/null +++ b/mod/groups/topicposts.php @@ -0,0 +1,19 @@ +<?php +/** + * Elgg Groups topic posts page + *  + * @package ElggGroups + * + * @deprecated 1.8 + */ + +// Load Elgg engine +require_once(dirname(dirname(dirname(__FILE__))) . "/engine/start.php"); + +elgg_load_library('elgg:discussion'); + +$guid = get_input('topic'); + +register_error(elgg_echo('changebookmark')); + +forward("/discussion/view/$guid"); diff --git a/mod/groups/upgrades/2011030101.php b/mod/groups/upgrades/2011030101.php new file mode 100644 index 000000000..3199d76ba --- /dev/null +++ b/mod/groups/upgrades/2011030101.php @@ -0,0 +1,66 @@ +<?php +/** + * Move text of first annotation to group forum topic object and delete annotation + * + * First determine if the upgrade is needed and then if needed, batch the update + */ + +$topics = elgg_get_entities(array( +	'type' => 'object', +	'subtype' => 'groupforumtopic', +	'limit' => 5, +	'order_by' => 'e.time_created asc', +)); + +// if not topics, no upgrade required +if (!$topics) { +	return; +} + +// if all five of the topics have empty descriptions, we need to upgrade +foreach ($topics as $topic) { +	if ($topic->description) { +		return; +	} +} + + +/** + * Condense first annotation into object + * + * @param ElggObject $topic + */ +function groups_2011030101($topic) { + +	// do not upgrade topics that have already been upgraded +	if ($topic->description) { +		return true; +	} + +	$annotation = $topic->getAnnotations('group_topic_post', 1); +	if (!$annotation) { +		// no text for this forum post so we delete (probably caused by #2624) +		$topic->delete(); +		return; +	} + +	$topic->description = $annotation[0]->value; +	$topic->save(); + +	return $annotation[0]->delete(); +} + +$previous_access = elgg_set_ignore_access(true); +$options = array( +	'type' => 'object', +	'subtype' => 'groupforumtopic', +	'limit' => 0, +); +$batch = new ElggBatch('elgg_get_entities', $options, 'groups_2011030101', 100); +elgg_set_ignore_access($previous_access); + +if ($batch->callbackResult) { +	error_log("Elgg Groups upgrade (2011030101) succeeded"); +} else { +	error_log("Elgg Groups upgrade (2011030101) failed"); +} diff --git a/mod/groups/views/default/annotation/group_topic_post.php b/mod/groups/views/default/annotation/group_topic_post.php new file mode 100644 index 000000000..f38d2a77a --- /dev/null +++ b/mod/groups/views/default/annotation/group_topic_post.php @@ -0,0 +1,19 @@ +<?php +/* + * Embeds an edit link for the annotation + */ + +$annotation = elgg_extract('annotation', $vars); + +echo elgg_view('annotation/default', $vars); + +if ($annotation->canEdit()) { +	$form = elgg_view_form('discussion/reply/save', array(), array_merge(array( +			'entity' => get_entity($annotation->entity_guid), +			'annotation' => $annotation +		), $vars) +	); + +	echo "<div class=\"hidden mbm\" id=\"edit-annotation-$annotation->id\">$form</div>"; +} + diff --git a/mod/groups/views/default/discussion/closed.php b/mod/groups/views/default/discussion/closed.php new file mode 100644 index 000000000..78bca108b --- /dev/null +++ b/mod/groups/views/default/discussion/closed.php @@ -0,0 +1,6 @@ +<?php +/** + * Topic is closed + */ +echo "<h3>" . elgg_echo("groups:topicisclosed") . "</h3>"; +echo "<p>" . elgg_echo("groups:topiccloseddesc") . "</p>";
\ No newline at end of file diff --git a/mod/groups/views/default/discussion/group_module.php b/mod/groups/views/default/discussion/group_module.php new file mode 100644 index 000000000..e0bcd55d6 --- /dev/null +++ b/mod/groups/views/default/discussion/group_module.php @@ -0,0 +1,48 @@ +<?php +/** + * Latest forum posts + * + * @uses $vars['entity'] + */ + +if ($vars['entity']->forum_enable == 'no') { +	return true; +} + +$group = $vars['entity']; + + +$all_link = elgg_view('output/url', array( +	'href' => "discussion/owner/$group->guid", +	'text' => elgg_echo('link:view:all'), +	'is_trusted' => true, +)); + +elgg_push_context('widgets'); +$options = array( +	'type' => 'object', +	'subtype' => 'groupforumtopic', +	'container_guid' => $group->getGUID(), +	'limit' => 6, +	'full_view' => false, +	'pagination' => false, +); +$content = elgg_list_entities($options); +elgg_pop_context(); + +if (!$content) { +	$content = '<p>' . elgg_echo('discussion:none') . '</p>'; +} + +$new_link = elgg_view('output/url', array( +	'href' => "discussion/add/" . $group->getGUID(), +	'text' => elgg_echo('groups:addtopic'), +	'is_trusted' => true, +)); + +echo elgg_view('groups/profile/module', array( +	'title' => elgg_echo('discussion:group'), +	'content' => $content, +	'all_link' => $all_link, +	'add_link' => $new_link, +));
\ No newline at end of file diff --git a/mod/groups/views/default/discussion/replies.php b/mod/groups/views/default/discussion/replies.php new file mode 100644 index 000000000..2bfb6f0cd --- /dev/null +++ b/mod/groups/views/default/discussion/replies.php @@ -0,0 +1,28 @@ +<?php +/** + * List replies with optional add form + * + * @uses $vars['entity']        ElggEntity + * @uses $vars['show_add_form'] Display add form or not + */ + +$show_add_form = elgg_extract('show_add_form', $vars, true); + +echo '<div id="group-replies" class="mtl">'; + +$options = array( +	'guid' => $vars['entity']->getGUID(), +	'annotation_name' => 'group_topic_post', +); +$html = elgg_list_annotations($options); +if ($html) { +	echo '<h3>' . elgg_echo('group:replies') . '</h3>'; +	echo $html; +} + +if ($show_add_form) { +	$form_vars = array('class' => 'mtm'); +	echo elgg_view_form('discussion/reply/save', $form_vars, $vars); +} + +echo '</div>'; diff --git a/mod/groups/views/default/forms/discussion/reply/save.php b/mod/groups/views/default/forms/discussion/reply/save.php new file mode 100644 index 000000000..083fefb78 --- /dev/null +++ b/mod/groups/views/default/forms/discussion/reply/save.php @@ -0,0 +1,57 @@ +<?php +/** + * Discussion topic reply form body + * + * @uses $vars['entity'] A discussion topic object + * @uses $vars['inline'] Display a shortened form? + */ + +if (isset($vars['entity']) && elgg_is_logged_in()) { +	echo elgg_view('input/hidden', array( +		'name' => 'entity_guid', +		'value' => $vars['entity']->getGUID(), +	)); + +	$inline = elgg_extract('inline', $vars, false); + +	$annotation = elgg_extract('annotation', $vars); +	 +	$value = ''; + +	if ($annotation) { +		$value = $annotation->value; +		echo elgg_view('input/hidden', array( +			'name' => 'annotation_id', +			'value' => $annotation->id +		)); +	} + +	if ($inline) { +		echo elgg_view('input/text', array('name' => 'group_topic_post', 'value' => $value)); +		echo elgg_view('input/submit', array('value' => elgg_echo('reply'))); +	} else { +?> +	<div> +		<label> +		<?php +			if ($annotation) { +				echo elgg_echo('edit'); +			} else { +				echo elgg_echo("reply"); +			} +		?> +		</label> +		<?php echo elgg_view('input/longtext', array('name' => 'group_topic_post', 'value' => $value)); ?> +	</div> +	<div class="elgg-foot"> +<?php +	if ($annotation) { +		echo elgg_view('input/submit', array('value' => elgg_echo('save'))); +	} else { +		echo elgg_view('input/submit', array('value' => elgg_echo('reply'))); +	} +?> +	</div> +<?php +	} +} diff --git a/mod/groups/views/default/forms/discussion/save.php b/mod/groups/views/default/forms/discussion/save.php new file mode 100644 index 000000000..a6582ede7 --- /dev/null +++ b/mod/groups/views/default/forms/discussion/save.php @@ -0,0 +1,57 @@ +<?php +/** + * Discussion topic add/edit form body + *  + */ + +$title = elgg_extract('title', $vars, ''); +$desc = elgg_extract('description', $vars, ''); +$status = elgg_extract('status', $vars, ''); +$tags = elgg_extract('tags', $vars, ''); +$access_id = elgg_extract('access_id', $vars, ACCESS_DEFAULT); +$container_guid = elgg_extract('container_guid', $vars); +$guid = elgg_extract('guid', $vars, null); + +?> +<div> +	<label><?php echo elgg_echo('title'); ?></label><br /> +	<?php echo elgg_view('input/text', array('name' => 'title', 'value' => $title)); ?> +</div> +<div> +	<label><?php echo elgg_echo('groups:topicmessage'); ?></label> +	<?php echo elgg_view('input/longtext', array('name' => 'description', 'value' => $desc)); ?> +</div> +<div> +	<label><?php echo elgg_echo('tags'); ?></label> +	<?php echo elgg_view('input/tags', array('name' => 'tags', 'value' => $tags)); ?> +</div> +<div> +    <label><?php echo elgg_echo("groups:topicstatus"); ?></label><br /> +	<?php +		echo elgg_view('input/dropdown', array( +			'name' => 'status', +			'value' => $status, +			'options_values' => array( +				'open' => elgg_echo('groups:topicopen'), +				'closed' => elgg_echo('groups:topicclosed'), +			), +		)); +	?> +</div> +<div> +	<label><?php echo elgg_echo('access'); ?></label><br /> +	<?php echo elgg_view('input/access', array('name' => 'access_id', 'value' => $access_id)); ?> +</div> +<div class="elgg-foot"> +<?php + +echo elgg_view('input/hidden', array('name' => 'container_guid', 'value' => $container_guid)); + +if ($guid) { +	echo elgg_view('input/hidden', array('name' => 'topic_guid', 'value' => $guid)); +} + +echo elgg_view('input/submit', array('value' => elgg_echo("save"))); + +?> +</div> diff --git a/mod/groups/views/default/forms/groups/edit.php b/mod/groups/views/default/forms/groups/edit.php new file mode 100644 index 000000000..e2dc5455a --- /dev/null +++ b/mod/groups/views/default/forms/groups/edit.php @@ -0,0 +1,178 @@ +<?php +/** + * Group edit form + *  + * @package ElggGroups + */ + +// only extract these elements. +$name = $membership = $vis = $entity = null; +extract($vars, EXTR_IF_EXISTS); + +?> +<div> +	<label><?php echo elgg_echo("groups:icon"); ?></label><br /> +	<?php echo elgg_view("input/file", array('name' => 'icon')); ?> +</div> +<div> +	<label><?php echo elgg_echo("groups:name"); ?></label><br /> +	<?php echo elgg_view("input/text", array( +		'name' => 'name', +		'value' => $name +	)); +	?> +</div> +<?php + +$group_profile_fields = elgg_get_config('group'); +if ($group_profile_fields > 0) { +	foreach ($group_profile_fields as $shortname => $valtype) { +		$line_break = '<br />'; +		if ($valtype == 'longtext') { +			$line_break = ''; +		} +		echo '<div><label>'; +		echo elgg_echo("groups:{$shortname}"); +		echo "</label>$line_break"; +		echo elgg_view("input/{$valtype}", array( +			'name' => $shortname, +			'value' => elgg_extract($shortname, $vars) +		)); +		echo '</div>'; +	} +} +?> + +<div> +	<label> +		<?php echo elgg_echo('groups:membership'); ?><br /> +		<?php echo elgg_view('input/dropdown', array( +			'name' => 'membership', +			'value' => $membership, +			'options_values' => array( +				ACCESS_PRIVATE => elgg_echo('groups:access:private'), +				ACCESS_PUBLIC => elgg_echo('groups:access:public') +			) +		)); +		?> +	</label> +</div> +	 +<?php + +if (elgg_get_plugin_setting('hidden_groups', 'groups') == 'yes') { +	$access_options = array( +		ACCESS_PRIVATE => elgg_echo('groups:access:group'), +		ACCESS_LOGGED_IN => elgg_echo("LOGGED_IN"), +		ACCESS_PUBLIC => elgg_echo("PUBLIC") +	); +?> + +<div> +	<label> +			<?php echo elgg_echo('groups:visibility'); ?><br /> +			<?php echo elgg_view('input/access', array( +				'name' => 'vis', +				'value' =>  $vis, +				'options_values' => $access_options, +			)); +			?> +	</label> +</div> + +<?php 	 +} + +if (isset($vars['entity'])) { +	$entity     = $vars['entity']; +	$owner_guid = $vars['entity']->owner_guid; +} else { +	$entity = false; +} + +if ($entity && ($owner_guid == elgg_get_logged_in_user_guid() || elgg_is_admin_logged_in())) { +	$members = array(); + +	$options = array( +		'relationship' => 'member', +		'relationship_guid' => $vars['entity']->getGUID(), +		'inverse_relationship' => true, +		'type' => 'user', +		'limit' => 0, +	); + +	$batch = new ElggBatch('elgg_get_entities_from_relationship', $options); +	foreach ($batch as $member) { +		$members[$member->guid] = "$member->name (@$member->username)"; +	} +?> + +<div> +	<label> +			<?php echo elgg_echo('groups:owner'); ?><br /> +			<?php echo elgg_view('input/dropdown', array( +				'name' => 'owner_guid', +				'value' =>  $owner_guid, +				'options_values' => $members, +				'class' => 'groups-owner-input', +			)); +			?> +	</label> +	<?php +	if ($owner_guid == elgg_get_logged_in_user_guid()) { +		echo '<span class="elgg-text-help">' . elgg_echo('groups:owner:warning') . '</span>'; +	} +	?> +</div> + +<?php 	 +} + +$tools = elgg_get_config('group_tool_options'); +if ($tools) { +	usort($tools, create_function('$a,$b', 'return strcmp($a->label,$b->label);')); +	foreach ($tools as $group_option) { +		$group_option_toggle_name = $group_option->name . "_enable"; +		$value = elgg_extract($group_option_toggle_name, $vars); +?>	 +<div> +	<label> +		<?php echo $group_option->label; ?><br /> +	</label> +		<?php echo elgg_view("input/radio", array( +			"name" => $group_option_toggle_name, +			"value" => $value, +			'options' => array( +				elgg_echo('groups:yes') => 'yes', +				elgg_echo('groups:no') => 'no', +			), +		)); +		?> +</div> +<?php +	} +} +?> +<div class="elgg-foot"> +<?php + +if ($entity) { +	echo elgg_view('input/hidden', array( +		'name' => 'group_guid', +		'value' => $entity->getGUID(), +	)); +} + +echo elgg_view('input/submit', array('value' => elgg_echo('save'))); + +if ($entity) { +	$delete_url = 'action/groups/delete?guid=' . $entity->getGUID(); +	echo elgg_view('output/confirmlink', array( +		'text' => elgg_echo('groups:delete'), +		'href' => $delete_url, +		'confirm' => elgg_echo('groups:deletewarning'), +		'class' => 'elgg-button elgg-button-delete float-alt', +	)); +} +?> +</div> diff --git a/mod/groups/views/default/forms/groups/find.php b/mod/groups/views/default/forms/groups/find.php new file mode 100644 index 000000000..ddf639b74 --- /dev/null +++ b/mod/groups/views/default/forms/groups/find.php @@ -0,0 +1,16 @@ +<?php +/** + * Group tag-based search form body + */ + +$tag_string = elgg_echo('groups:search:tags'); + +$params = array( +	'name' => 'tag', +	'class' => 'elgg-input-search mbm', +	'value' => $tag_string, +	'onclick' => "if (this.value=='$tag_string') { this.value='' }", +); +echo elgg_view('input/text', $params); + +echo elgg_view('input/submit', array('value' => elgg_echo('search:go'))); diff --git a/mod/groups/views/default/forms/groups/invite.php b/mod/groups/views/default/forms/groups/invite.php new file mode 100644 index 000000000..ef3131782 --- /dev/null +++ b/mod/groups/views/default/forms/groups/invite.php @@ -0,0 +1,22 @@ +<?php +/** + * Elgg groups invite form + * + * @package ElggGroups + */ + +$group = $vars['entity']; +$owner = $group->getOwnerEntity(); +$forward_url = $group->getURL(); +$friends = elgg_get_logged_in_user_entity()->getFriends('', 0); + +if ($friends) { +	echo elgg_view('input/friendspicker', array('entities' => $friends, 'name' => 'user_guid', 'highlight' => 'all')); +	echo '<div class="elgg-foot">'; +	echo elgg_view('input/hidden', array('name' => 'forward_url', 'value' => $forward_url)); +	echo elgg_view('input/hidden', array('name' => 'group_guid', 'value' => $group->guid)); +	echo elgg_view('input/submit', array('value' => elgg_echo('invite'))); +	echo '</div>'; +} else { +	echo elgg_echo('groups:nofriendsatall'); +}
\ No newline at end of file diff --git a/mod/groups/views/default/forms/groups/search.php b/mod/groups/views/default/forms/groups/search.php new file mode 100644 index 000000000..850b6088e --- /dev/null +++ b/mod/groups/views/default/forms/groups/search.php @@ -0,0 +1,20 @@ +<?php +/** + * Group search form + * + * @uses $vars['entity'] ElggGroup + */ + +$params = array( +	'name' => 'q', +	'class' => 'elgg-input-search mbm', +	'value' => $tag_string, +); +echo elgg_view('input/text', $params); + +echo elgg_view('input/hidden', array( +	'name' => 'container_guid', +	'value' => $vars['entity']->getGUID(), +)); + +echo elgg_view('input/submit', array('value' => elgg_echo('search:go'))); diff --git a/mod/groups/views/default/group/default.php b/mod/groups/views/default/group/default.php new file mode 100644 index 000000000..d9460dff4 --- /dev/null +++ b/mod/groups/views/default/group/default.php @@ -0,0 +1,37 @@ +<?php  +/** + * Group entity view + *  + * @package ElggGroups + */ + +$group = $vars['entity']; + +$icon = elgg_view_entity_icon($group, 'tiny'); + +$metadata = elgg_view_menu('entity', array( +	'entity' => $group, +	'handler' => 'groups', +	'sort_by' => 'priority', +	'class' => 'elgg-menu-hz', +)); + +if (elgg_in_context('owner_block') || elgg_in_context('widgets')) { +	$metadata = ''; +} + + +if ($vars['full_view']) { +	echo elgg_view('groups/profile/summary', $vars); +} else { +	// brief view +	$params = array( +		'entity' => $group, +		'metadata' => $metadata, +		'subtitle' => $group->briefdescription, +	); +	$params = $params + $vars; +	$list_body = elgg_view('group/elements/summary', $params); + +	echo elgg_view_image_block($icon, $list_body, $vars); +} diff --git a/mod/groups/views/default/groups/css.php b/mod/groups/views/default/groups/css.php new file mode 100644 index 000000000..32dd2b74d --- /dev/null +++ b/mod/groups/views/default/groups/css.php @@ -0,0 +1,76 @@ +<?php +/** + * Elgg Groups css + *  + * @package groups + */ + +?> +.groups-profile > .elgg-image { +	margin-right: 10px; +} +.groups-stats { +	background: #eeeeee; +	padding: 5px; +	margin-top: 10px; +	 +	-webkit-border-radius: 5px; +	-moz-border-radius: 5px; +	border-radius: 5px; +} + +.groups-profile-fields .odd, +.groups-profile-fields .even { +	background: #f4f4f4; +	 +	-webkit-border-radius: 4px; +	-moz-border-radius: 4px; +	border-radius: 4px; +	 +	padding: 2px 4px; +	margin-bottom: 7px; +} + +.groups-profile-fields .elgg-output { +	margin: 0; +} + +#groups-tools > li { +	width: 48%; +	min-height: 200px; +	margin-bottom: 40px; +} + +#groups-tools > li:nth-child(odd) { +	margin-right: 4%; +} + +.groups-widget-viewall { +	float: right; +	font-size: 85%; +} + +.groups-latest-reply { +	float: right; +} + +.elgg-menu-groups-my-status li a { +	display: block; + +	-webkit-border-radius: 8px; +	-moz-border-radius: 8px; +	border-radius: 8px; + +	background-color: white; +	margin: 3px 0 5px 0; +	padding: 2px 4px 2px 8px; +} +.elgg-menu-groups-my-status li a:hover { +	background-color: #0054A7; +	color: white; +	text-decoration: none; +} +.elgg-menu-groups-my-status li.elgg-state-selected > a { +	background-color: #4690D6; +	color: white; +} diff --git a/mod/groups/views/default/groups/edit.php b/mod/groups/views/default/groups/edit.php new file mode 100644 index 000000000..5579ad54a --- /dev/null +++ b/mod/groups/views/default/groups/edit.php @@ -0,0 +1,15 @@ +<?php +/** + * Edit/create a group wrapper + * + * @uses $vars['entity'] ElggGroup object + */ + +$entity = elgg_extract('entity', $vars, null); + +$form_vars = array( +	'enctype' => 'multipart/form-data', +	'class' => 'elgg-form-alt', +); + +echo elgg_view_form('groups/edit', $form_vars, groups_prepare_form_vars($entity)); diff --git a/mod/groups/views/default/groups/group_sort_menu.php b/mod/groups/views/default/groups/group_sort_menu.php new file mode 100644 index 000000000..f5631a31f --- /dev/null +++ b/mod/groups/views/default/groups/group_sort_menu.php @@ -0,0 +1,36 @@ +<?php +/** + * All groups listing page navigation + * + * @uses $vars['selected'] Name of the tab that has been selected + */ + +$tabs = array( +	'newest' => array( +		'text' => elgg_echo('groups:newest'), +		'href' => 'groups/all?filter=newest', +		'priority' => 200, +	), +	'popular' => array( +		'text' => elgg_echo('groups:popular'), +		'href' => 'groups/all?filter=popular', +		'priority' => 300, +	), +	'discussion' => array( +		'text' => elgg_echo('groups:latestdiscussion'), +		'href' => 'groups/all?filter=discussion', +		'priority' => 400, +	), +); + +foreach ($tabs as $name => $tab) { +	$tab['name'] = $name; + +	if ($vars['selected'] == $name) { +		$tab['selected'] = true; +	} + +	elgg_register_menu_item('filter', $tab); +} + +echo elgg_view_menu('filter', array('sort_by' => 'priority', 'class' => 'elgg-menu-hz')); diff --git a/mod/groups/views/default/groups/invitationrequests.php b/mod/groups/views/default/groups/invitationrequests.php new file mode 100644 index 000000000..94dbdf1f2 --- /dev/null +++ b/mod/groups/views/default/groups/invitationrequests.php @@ -0,0 +1,51 @@ +<?php +/** + * A user's group invitations + * + * @uses $vars['invitations'] Array of ElggGroups + */ + +if (!empty($vars['invitations']) && is_array($vars['invitations'])) { +	$user = elgg_get_logged_in_user_entity(); +	echo '<ul class="elgg-list">'; +	foreach ($vars['invitations'] as $group) { +		if ($group instanceof ElggGroup) { +			$icon = elgg_view_entity_icon($group, 'tiny', array('use_hover' => 'true')); + +			$group_title = elgg_view('output/url', array( +				'href' => $group->getURL(), +				'text' => $group->name, +				'is_trusted' => true, +			)); + +			$url = elgg_add_action_tokens_to_url(elgg_get_site_url()."action/groups/join?user_guid={$user->guid}&group_guid={$group->guid}"); +			$accept_button = elgg_view('output/url', array( +				'href' => $url, +				'text' => elgg_echo('accept'), +				'class' => 'elgg-button elgg-button-submit', +				'is_trusted' => true, +			)); + +			$url = "action/groups/killinvitation?user_guid={$user->getGUID()}&group_guid={$group->getGUID()}"; +			$delete_button = elgg_view('output/confirmlink', array( +					'href' => $url, +					'confirm' => elgg_echo('groups:invite:remove:check'), +					'text' => elgg_echo('delete'), +					'class' => 'elgg-button elgg-button-delete mlm', +			)); + +			$body = <<<HTML +<h4>$group_title</h4> +<p class="elgg-subtext">$group->briefdescription</p> +HTML; +			$alt = $accept_button . $delete_button; + +			echo '<li class="pvs">'; +			echo elgg_view_image_block($icon, $body, array('image_alt' => $alt)); +			echo '</li>'; +		} +	} +	echo '</ul>'; +} else { +		echo '<p class="mtm">' . elgg_echo('groups:invitations:none') . "</p>"; +} diff --git a/mod/groups/views/default/groups/js.php b/mod/groups/views/default/groups/js.php new file mode 100644 index 000000000..0319be14a --- /dev/null +++ b/mod/groups/views/default/groups/js.php @@ -0,0 +1,13 @@ +<?php +/** + * Javascript for Groups forms + * + * @package ElggGroups + */ +?> + +// this adds a class to support IE8 and older +elgg.register_hook_handler('init', 'system', function() { +	// jQuery uses 0-based indexing +	$('#groups-tools').children('li:even').addClass('odd'); +}); diff --git a/mod/groups/views/default/groups/membershiprequests.php b/mod/groups/views/default/groups/membershiprequests.php new file mode 100644 index 000000000..2bac0e32b --- /dev/null +++ b/mod/groups/views/default/groups/membershiprequests.php @@ -0,0 +1,47 @@ +<?php +/** + * A group's member requests + * + * @uses $vars['entity']   ElggGroup + * @uses $vars['requests'] Array of ElggUsers + */ + +if (!empty($vars['requests']) && is_array($vars['requests'])) { +	echo '<ul class="elgg-list">'; +	foreach ($vars['requests'] as $user) { +		$icon = elgg_view_entity_icon($user, 'tiny', array('use_hover' => 'true')); + +		$user_title = elgg_view('output/url', array( +			'href' => $user->getURL(), +			'text' => $user->name, +			'is_trusted' => true, +		)); + +		$url = "action/groups/addtogroup?user_guid={$user->guid}&group_guid={$vars['entity']->guid}"; +		$url = elgg_add_action_tokens_to_url($url); +		$accept_button = elgg_view('output/url', array( +			'href' => $url, +			'text' => elgg_echo('accept'), +			'class' => 'elgg-button elgg-button-submit', +			'is_trusted' => true, +		)); + +		$url = 'action/groups/killrequest?user_guid=' . $user->guid . '&group_guid=' . $vars['entity']->guid; +		$delete_button = elgg_view('output/confirmlink', array( +				'href' => $url, +				'confirm' => elgg_echo('groups:joinrequest:remove:check'), +				'text' => elgg_echo('delete'), +				'class' => 'elgg-button elgg-button-delete mlm', +		)); + +		$body = "<h4>$user_title</h4>"; +		$alt = $accept_button . $delete_button; + +		echo '<li class="pvs">'; +		echo elgg_view_image_block($icon, $body, array('image_alt' => $alt)); +		echo '</li>'; +	} +	echo '</ul>'; +} else { +	echo '<p class="mtm">' . elgg_echo('groups:requests:none') . '</p>'; +} diff --git a/mod/groups/views/default/groups/profile/activity_module.php b/mod/groups/views/default/groups/profile/activity_module.php new file mode 100644 index 000000000..832ff4a4b --- /dev/null +++ b/mod/groups/views/default/groups/profile/activity_module.php @@ -0,0 +1,44 @@ +<?php +/** + * Groups latest activity + * + * @todo add people joining group to activity + *  + * @package Groups + */ + +if ($vars['entity']->activity_enable == 'no') { +	return true; +} + +$group = $vars['entity']; +if (!$group) { +	return true; +} + +$all_link = elgg_view('output/url', array( +	'href' => "groups/activity/$group->guid", +	'text' => elgg_echo('link:view:all'), +	'is_trusted' => true, +)); + + +elgg_push_context('widgets'); +$db_prefix = elgg_get_config('dbprefix'); +$content = elgg_list_river(array( +	'limit' => 4, +	'pagination' => false, +	'joins' => array("JOIN {$db_prefix}entities e1 ON e1.guid = rv.object_guid"), +	'wheres' => array("(e1.container_guid = $group->guid)"), +)); +elgg_pop_context(); + +if (!$content) { +	$content = '<p>' . elgg_echo('groups:activity:none') . '</p>'; +} + +echo elgg_view('groups/profile/module', array( +	'title' => elgg_echo('groups:activity'), +	'content' => $content, +	'all_link' => $all_link, +)); diff --git a/mod/groups/views/default/groups/profile/closed_membership.php b/mod/groups/views/default/groups/profile/closed_membership.php new file mode 100644 index 000000000..24526d378 --- /dev/null +++ b/mod/groups/views/default/groups/profile/closed_membership.php @@ -0,0 +1,16 @@ +<?php +/** + * Display message about closed membership + *  + * @package ElggGroups + */ + +?> +<p class="mtm"> +<?php  +echo elgg_echo('groups:closedgroup'); +if (elgg_is_logged_in()) { +	echo ' ' . elgg_echo('groups:closedgroup:request'); +} +?> +</p> diff --git a/mod/groups/views/default/groups/profile/fields.php b/mod/groups/views/default/groups/profile/fields.php new file mode 100644 index 000000000..14827f11a --- /dev/null +++ b/mod/groups/views/default/groups/profile/fields.php @@ -0,0 +1,38 @@ +<?php +/** + * Group profile fields + */ + +$group = $vars['entity']; + +$profile_fields = elgg_get_config('group'); + +if (is_array($profile_fields) && count($profile_fields) > 0) { + +	$even_odd = 'odd'; +	foreach ($profile_fields as $key => $valtype) { +		// do not show the name +		if ($key == 'name') { +			continue; +		} + +		$value = $group->$key; +		if (empty($value)) { +			continue; +		} + +		$options = array('value' => $group->$key); +		if ($valtype == 'tags') { +			$options['tag_names'] = $key; +		} + +		echo "<div class=\"{$even_odd}\">"; +		echo "<b>"; +		echo elgg_echo("groups:$key"); +		echo ": </b>"; +		echo elgg_view("output/$valtype", $options); +		echo "</div>"; + +		$even_odd = ($even_odd == 'even') ? 'odd' : 'even'; +	} +} diff --git a/mod/groups/views/default/groups/profile/layout.php b/mod/groups/views/default/groups/profile/layout.php new file mode 100644 index 000000000..f513f10ae --- /dev/null +++ b/mod/groups/views/default/groups/profile/layout.php @@ -0,0 +1,13 @@ +<?php +/** + * Layout of the groups profile page + * + * @uses $vars['entity'] + */ + +echo elgg_view('groups/profile/summary', $vars); +if (group_gatekeeper(false)) { +	echo elgg_view('groups/profile/widgets', $vars); +} else { +	echo elgg_view('groups/profile/closed_membership'); +} diff --git a/mod/groups/views/default/groups/profile/module.php b/mod/groups/views/default/groups/profile/module.php new file mode 100644 index 000000000..9d0b18266 --- /dev/null +++ b/mod/groups/views/default/groups/profile/module.php @@ -0,0 +1,25 @@ +<?php +/** + * Group module (also called a group widget) + * + * @uses $vars['title']    The title of the module + * @uses $vars['content']  The module content + * @uses $vars['all_link'] A link to list content + * @uses $vars['add_link'] A link to create content + */ + +$group = elgg_get_page_owner_entity(); + +$header = "<span class=\"groups-widget-viewall\">{$vars['all_link']}</span>"; +$header .= '<h3>' . $vars['title'] . '</h3>'; + +if ($group->canWriteToContainer() && isset($vars['add_link'])) { +	$vars['content'] .= "<span class='elgg-widget-more'>{$vars['add_link']}</span>"; +} + +echo '<li>'; +echo elgg_view_module('info', '', $vars['content'], array( +	'header' => $header, +	'class' => 'elgg-module-group', +)); +echo '</li>'; diff --git a/mod/groups/views/default/groups/profile/summary.php b/mod/groups/views/default/groups/profile/summary.php new file mode 100644 index 000000000..3f7496871 --- /dev/null +++ b/mod/groups/views/default/groups/profile/summary.php @@ -0,0 +1,64 @@ +<?php +/** + * Group profile summary + * + * Icon and profile fields + * + * @uses $vars['group'] + */ + +if (!isset($vars['entity']) || !$vars['entity']) { +	echo elgg_echo('groups:notfound'); +	return true; +} + +$group = $vars['entity']; +$owner = $group->getOwnerEntity(); + +if (!$owner) { +	// not having an owner is very bad so we throw an exception +	$msg = elgg_echo('InvalidParameterException:IdNotExistForGUID', array('group owner', $group->guid)); +	throw new InvalidParameterException($msg); +} + +?> +<div class="groups-profile clearfix elgg-image-block"> +	<div class="elgg-image"> +		<div class="groups-profile-icon"> +			<?php +				// we don't force icons to be square so don't set width/height +				echo elgg_view_entity_icon($group, 'large', array( +					'href' => '', +					'width' => '', +					'height' => '', +				));  +			?> +		</div> +		<div class="groups-stats"> +			<p> +				<b><?php echo elgg_echo("groups:owner"); ?>: </b> +				<?php +					echo elgg_view('output/url', array( +						'text' => $owner->name, +						'value' => $owner->getURL(), +						'is_trusted' => true, +					)); +				?> +			</p> +			<p> +			<?php +				echo elgg_echo('groups:members') . ": " . $group->getMembers(0, 0, TRUE); +			?> +			</p> +		</div> +	</div> + +	<div class="groups-profile-fields elgg-body"> +		<?php +			echo elgg_view('groups/profile/fields', $vars); +		?> +	</div> +</div> +<?php +?> + diff --git a/mod/groups/views/default/groups/profile/widgets.php b/mod/groups/views/default/groups/profile/widgets.php new file mode 100644 index 000000000..7635cad4f --- /dev/null +++ b/mod/groups/views/default/groups/profile/widgets.php @@ -0,0 +1,24 @@ +<?php +/** +* Profile widgets/tools +*  +* @package ElggGroups +*/  +	 +// tools widget area +echo '<ul id="groups-tools" class="elgg-gallery elgg-gallery-fluid mtl clearfix">'; + +// enable tools to extend this area +echo elgg_view("groups/tool_latest", $vars); + +// backward compatibility +$right = elgg_view('groups/right_column', $vars); +$left = elgg_view('groups/left_column', $vars); +if ($right || $left) { +	elgg_deprecated_notice('The views groups/right_column and groups/left_column have been replaced by groups/tool_latest', 1.8); +	echo $left; +	echo $right; +} + +echo "</ul>"; + diff --git a/mod/groups/views/default/groups/sidebar/featured.php b/mod/groups/views/default/groups/sidebar/featured.php new file mode 100644 index 000000000..f3f8f8d2d --- /dev/null +++ b/mod/groups/views/default/groups/sidebar/featured.php @@ -0,0 +1,25 @@ +<?php +/** + * Featured groups + * + * @package ElggGroups + */ + +$featured_groups = elgg_get_entities_from_metadata(array( +	'metadata_name' => 'featured_group', +	'metadata_value' => 'yes', +	'type' => 'group', +	'limit' => 10, +)); + +if ($featured_groups) { + +	elgg_push_context('widgets'); +	$body = ''; +	foreach ($featured_groups as $group) { +		$body .= elgg_view_entity($group, array('full_view' => false)); +	} +	elgg_pop_context(); + +	echo elgg_view_module('aside', elgg_echo("groups:featured"), $body); +} diff --git a/mod/groups/views/default/groups/sidebar/find.php b/mod/groups/views/default/groups/sidebar/find.php new file mode 100644 index 000000000..c1a8da3c2 --- /dev/null +++ b/mod/groups/views/default/groups/sidebar/find.php @@ -0,0 +1,14 @@ +<?php +/** + * Group search + * + * @package ElggGroups + */ +$url = elgg_get_site_url() . 'groups/search'; +$body = elgg_view_form('groups/find', array( +	'action' => $url, +	'method' => 'get', +	'disable_security' => true, +)); + +echo elgg_view_module('aside', elgg_echo('groups:searchtag'), $body); diff --git a/mod/groups/views/default/groups/sidebar/members.php b/mod/groups/views/default/groups/sidebar/members.php new file mode 100644 index 000000000..1199a0c34 --- /dev/null +++ b/mod/groups/views/default/groups/sidebar/members.php @@ -0,0 +1,32 @@ +<?php +/** + * Group members sidebar + * + * @package ElggGroups + * + * @uses $vars['entity'] Group entity + * @uses $vars['limit']  The number of members to display + */ + +$limit = elgg_extract('limit', $vars, 14); + +$all_link = elgg_view('output/url', array( +	'href' => 'groups/members/' . $vars['entity']->guid, +	'text' => elgg_echo('groups:members:more'), +	'is_trusted' => true, +)); + +$body = elgg_list_entities_from_relationship(array( +	'relationship' => 'member', +	'relationship_guid' => $vars['entity']->guid, +	'inverse_relationship' => true, +	'type' => 'user', +	'limit' => $limit, +	'list_type' => 'gallery', +	'gallery_class' => 'elgg-gallery-users', +	'pagination' => false +)); + +$body .= "<div class='center mts'>$all_link</div>"; + +echo elgg_view_module('aside', elgg_echo('groups:members'), $body); diff --git a/mod/groups/views/default/groups/sidebar/my_status.php b/mod/groups/views/default/groups/sidebar/my_status.php new file mode 100644 index 000000000..1e4e84b80 --- /dev/null +++ b/mod/groups/views/default/groups/sidebar/my_status.php @@ -0,0 +1,62 @@ +<?php +/** + * Group status for logged in user + * + * @package ElggGroups + * + * @uses $vars['entity'] Group entity + */ + +$group = elgg_extract('entity', $vars); +$user = elgg_get_logged_in_user_entity(); +$subscribed = elgg_extract('subscribed', $vars); + +if (!elgg_is_logged_in()) { +	return true; +} + +// membership status +$is_member = $group->isMember($user); +$is_owner = $group->getOwnerEntity() == $user; + +if ($is_owner) { +	elgg_register_menu_item('groups:my_status', array( +		'name' => 'membership_status', +		'text' => '<a>' . elgg_echo('groups:my_status:group_owner') . '</a>', +		'href' => false +	)); +} elseif ($is_member) { +	elgg_register_menu_item('groups:my_status', array( +		'name' => 'membership_status', +		'text' => '<a>' . elgg_echo('groups:my_status:group_member') . '</a>', +		'href' => false +	)); +} else { +	elgg_register_menu_item('groups:my_status', array( +		'name' => 'membership_status', +		'text' => elgg_echo('groups:join'), +		'href' => "/action/groups/join?group_guid={$group->getGUID()}", +		'is_action' => true +	)); +} + +// notification info +if (elgg_is_active_plugin('notifications') && $is_member) { +	if ($subscribed) { +		elgg_register_menu_item('groups:my_status', array( +			'name' => 'subscription_status', +			'text' => elgg_echo('groups:subscribed'), +			'href' => "notifications/group/$user->username", +			'is_action' => true +		)); +	} else { +		elgg_register_menu_item('groups:my_status', array( +			'name' => 'subscription_status', +			'text' => elgg_echo('groups:unsubscribed'), +			'href' => "notifications/group/$user->username" +		)); +	} +} + +$body = elgg_view_menu('groups:my_status'); +echo elgg_view_module('aside', elgg_echo('groups:my_status'), $body); diff --git a/mod/groups/views/default/groups/sidebar/search.php b/mod/groups/views/default/groups/sidebar/search.php new file mode 100644 index 000000000..226835715 --- /dev/null +++ b/mod/groups/views/default/groups/sidebar/search.php @@ -0,0 +1,15 @@ +<?php +/** + * Search for content in this group + * + * @uses vars['entity'] ElggGroup + */ + +$url = elgg_get_site_url() . 'search'; +$body = elgg_view_form('groups/search', array( +	'action' => $url, +	'method' => 'get', +	'disable_security' => true, +), $vars); + +echo elgg_view_module('aside', elgg_echo('groups:search_in_group'), $body);
\ No newline at end of file diff --git a/mod/groups/views/default/object/groupforumtopic.php b/mod/groups/views/default/object/groupforumtopic.php new file mode 100644 index 000000000..e6988d16e --- /dev/null +++ b/mod/groups/views/default/object/groupforumtopic.php @@ -0,0 +1,101 @@ +<?php +/** + * Forum topic entity view + * + * @package ElggGroups +*/ + +$full = elgg_extract('full_view', $vars, FALSE); +$topic = elgg_extract('entity', $vars, FALSE); + +if (!$topic) { +	return true; +} + +$poster = $topic->getOwnerEntity(); +$group = $topic->getContainerEntity(); +$excerpt = elgg_get_excerpt($topic->description); + +$poster_icon = elgg_view_entity_icon($poster, 'tiny'); +$poster_link = elgg_view('output/url', array( +	'href' => $poster->getURL(), +	'text' => $poster->name, +	'is_trusted' => true, +)); +$poster_text = elgg_echo('groups:started', array($poster->name)); + +$tags = elgg_view('output/tags', array('tags' => $topic->tags)); +$date = elgg_view_friendly_time($topic->time_created); + +$replies_link = ''; +$reply_text = ''; +$num_replies = elgg_get_annotations(array( +	'annotation_name' => 'group_topic_post', +	'guid' => $topic->getGUID(), +	'count' => true, +)); +if ($num_replies != 0) { +	$last_reply = $topic->getAnnotations('group_topic_post', 1, 0, 'desc'); +	$poster = $last_reply[0]->getOwnerEntity(); +	$reply_time = elgg_view_friendly_time($last_reply[0]->time_created); +	$reply_text = elgg_echo('groups:updated', array($poster->name, $reply_time)); +	 +	$replies_link = elgg_view('output/url', array( +		'href' => $topic->getURL() . '#group-replies', +		'text' => elgg_echo('group:replies') . " ($num_replies)", +		'is_trusted' => true, +	)); +} + +$metadata = elgg_view_menu('entity', array( +	'entity' => $vars['entity'], +	'handler' => 'discussion', +	'sort_by' => 'priority', +	'class' => 'elgg-menu-hz', +)); + +// do not show the metadata and controls in widget view +if (elgg_in_context('widgets')) { +	$metadata = ''; +} + +if ($full) { +	$subtitle = "$poster_text $date $replies_link"; + +	$params = array( +		'entity' => $topic, +		'metadata' => $metadata, +		'subtitle' => $subtitle, +		'tags' => $tags, +	); +	$params = $params + $vars; +	$list_body = elgg_view('object/elements/summary', $params); + +	$info = elgg_view_image_block($poster_icon, $list_body); + +	$body = elgg_view('output/longtext', array( +		'value' => $topic->description, +		'class' => 'clearfix', +	)); + +	echo <<<HTML +$info +$body +HTML; + +} else { +	// brief view +	$subtitle = "$poster_text $date $replies_link <span class=\"groups-latest-reply\">$reply_text</span>"; + +	$params = array( +		'entity' => $topic, +		'metadata' => $metadata, +		'subtitle' => $subtitle, +		'tags' => $tags, +		'content' => $excerpt, +	); +	$params = $params + $vars; +	$list_body = elgg_view('object/elements/summary', $params); + +	echo elgg_view_image_block($poster_icon, $list_body); +} diff --git a/mod/groups/views/default/plugins/groups/settings.php b/mod/groups/views/default/plugins/groups/settings.php new file mode 100644 index 000000000..41ea146db --- /dev/null +++ b/mod/groups/views/default/plugins/groups/settings.php @@ -0,0 +1,40 @@ +<?php +/** + * Groups plugin settings + */ + +// set default value +if (!isset($vars['entity']->hidden_groups)) { +	$vars['entity']->hidden_groups = 'no'; +} + +// set default value +if (!isset($vars['entity']->limited_groups)) { +	$vars['entity']->limited_groups = 'no'; +} + +echo '<div>'; +echo elgg_echo('groups:allowhiddengroups'); +echo ' '; +echo elgg_view('input/dropdown', array( +	'name' => 'params[hidden_groups]', +	'options_values' => array( +		'no' => elgg_echo('option:no'), +		'yes' => elgg_echo('option:yes') +	), +	'value' => $vars['entity']->hidden_groups, +)); +echo '</div>'; + +echo '<div>'; +echo elgg_echo('groups:whocancreate'); +echo ' '; +echo elgg_view('input/dropdown', array( +	'name' => 'params[limited_groups]', +	'options_values' => array( +		'no' => elgg_echo('LOGGED_IN'), +		'yes' => elgg_echo('admin') +	), +	'value' => $vars['entity']->limited_groups, +)); +echo '</div>'; diff --git a/mod/groups/views/default/river/annotation/group_topic_post/reply.php b/mod/groups/views/default/river/annotation/group_topic_post/reply.php new file mode 100644 index 000000000..afc823bde --- /dev/null +++ b/mod/groups/views/default/river/annotation/group_topic_post/reply.php @@ -0,0 +1,12 @@ +<?php +/** + * Reply river view + */ +$object = $vars['item']->getObjectEntity(); +$reply = $vars['item']->getAnnotation(); +$excerpt = elgg_get_excerpt($reply->value); + +echo elgg_view('river/elements/layout', array( +	'item' => $vars['item'], +	'message' => $excerpt, +));
\ No newline at end of file diff --git a/mod/groups/views/default/river/group/create.php b/mod/groups/views/default/river/group/create.php new file mode 100644 index 000000000..ea42b5b00 --- /dev/null +++ b/mod/groups/views/default/river/group/create.php @@ -0,0 +1,13 @@ +<?php +/** + * Group creation river view. + */ + +$object = $vars['item']->getObjectEntity(); +$excerpt = strip_tags($object->description); +$excerpt = elgg_get_excerpt($excerpt); + +echo elgg_view('river/elements/layout', array( +	'item' => $vars['item'], +	'message' => $excerpt, +));
\ No newline at end of file diff --git a/mod/groups/views/default/river/object/groupforumtopic/create.php b/mod/groups/views/default/river/object/groupforumtopic/create.php new file mode 100644 index 000000000..e7d92bc08 --- /dev/null +++ b/mod/groups/views/default/river/object/groupforumtopic/create.php @@ -0,0 +1,22 @@ +<?php +/** + * Group forum topic create river view. + */ + +$object = $vars['item']->getObjectEntity(); +$excerpt = strip_tags($object->description); +$excerpt = elgg_get_excerpt($excerpt); + +$responses = ''; +if (elgg_is_logged_in() && $object->canAnnotate(0, 'group_topic_post')) { +	// inline comment form +	$form_vars = array('id' => "groups-reply-{$object->getGUID()}", 'class' => 'hidden'); +	$body_vars = array('entity' => $object, 'inline' => true); +	$responses = elgg_view_form('discussion/reply/save', $form_vars, $body_vars); +} + +echo elgg_view('river/elements/layout', array( +	'item' => $vars['item'], +	'message' => $excerpt, +	'responses' => $responses, +)); diff --git a/mod/groups/views/default/river/relationship/member/create.php b/mod/groups/views/default/river/relationship/member/create.php new file mode 100644 index 000000000..0afd87e4b --- /dev/null +++ b/mod/groups/views/default/river/relationship/member/create.php @@ -0,0 +1,8 @@ +<?php +/** + * Group join river view. + */ + +echo elgg_view('river/elements/layout', array( +	'item' => $vars['item'], +)); diff --git a/mod/groups/views/default/widgets/a_users_groups/content.php b/mod/groups/views/default/widgets/a_users_groups/content.php new file mode 100644 index 000000000..fe1a46e39 --- /dev/null +++ b/mod/groups/views/default/widgets/a_users_groups/content.php @@ -0,0 +1,33 @@ +<?php +/** + * Elgg file widget view + * + * @package ElggFile + */ + + +$num = $vars['entity']->num_display; + +$options = array( +	'type' => 'group', +	'relationship' => 'member', +	'relationship_guid' => $vars['entity']->owner_guid, +	'limit' => $num, +	'full_view' => FALSE, +	'pagination' => FALSE, +); +$content = elgg_list_entities_from_relationship($options); + +echo $content; + +if ($content) { +	$url = "groups/member/" . elgg_get_page_owner_entity()->username; +	$more_link = elgg_view('output/url', array( +		'href' => $url, +		'text' => elgg_echo('groups:more'), +		'is_trusted' => true, +	)); +	echo "<span class=\"elgg-widget-more\">$more_link</span>"; +} else { +	echo elgg_echo('groups:none'); +} diff --git a/mod/groups/views/default/widgets/a_users_groups/edit.php b/mod/groups/views/default/widgets/a_users_groups/edit.php new file mode 100644 index 000000000..e49a996b7 --- /dev/null +++ b/mod/groups/views/default/widgets/a_users_groups/edit.php @@ -0,0 +1,25 @@ +<?php +/** + * Elgg group widget edit view + * + * @package ElggGroups + */ + + +// set default value +if (!isset($vars['entity']->num_display)) { +	$vars['entity']->num_display = 4; +} + +$params = array( +	'name' => 'params[num_display]', +	'value' => $vars['entity']->num_display, +	'options' => array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20), +); +$dropdown = elgg_view('input/dropdown', $params); + +?> +<div> +	<?php echo elgg_echo('groups:widget:num_display'); ?>: +	<?php echo $dropdown; ?> +</div> diff --git a/mod/groups/views/rss/annotation/group_topic_post.php b/mod/groups/views/rss/annotation/group_topic_post.php new file mode 100644 index 000000000..0d3a40117 --- /dev/null +++ b/mod/groups/views/rss/annotation/group_topic_post.php @@ -0,0 +1,32 @@ +<?php +/** + * RSS view for a discussion reply + * + * @uses $vars['annotation'] + */ + +$annotation = $vars['annotation']; + +$poster = $annotation->getOwnerEntity(); +$poster_name = htmlspecialchars($poster->name, ENT_NOQUOTES, 'UTF-8'); +$pubdate = date('r', $annotation->getTimeCreated()); +$permalink = $annotation->getURL(); + +$title = elgg_echo('discussion:reply:title', array($poster_name)); + +$creator = elgg_view('page/components/creator', array('entity' => $annotation)); +$extensions = elgg_view('extensions/item', $vars); + +$item = <<<__HTML +<item> +	<guid isPermaLink='true'>$permalink</guid> +	<pubDate>$pubdate</pubDate> +	<link>$permalink</link> +	<title><![CDATA[$title]]></title> +	<description><![CDATA[{$vars['annotation']->value}]]></description> +	$creator$extensions +</item> + +__HTML; + +echo $item; diff --git a/mod/groups/views/rss/discussion/replies.php b/mod/groups/views/rss/discussion/replies.php new file mode 100644 index 000000000..419003b21 --- /dev/null +++ b/mod/groups/views/rss/discussion/replies.php @@ -0,0 +1,12 @@ +<?php +/** + * List replies RSS view + * + * @uses $vars['entity'] ElggEntity + */ + +$options = array( +	'guid' => $vars['entity']->getGUID(), +	'annotation_name' => 'group_topic_post', +); +echo elgg_list_annotations($options); diff --git a/mod/groups/views/rss/groups/profile/layout.php b/mod/groups/views/rss/groups/profile/layout.php new file mode 100644 index 000000000..0dafe78ad --- /dev/null +++ b/mod/groups/views/rss/groups/profile/layout.php @@ -0,0 +1,18 @@ +<?php +/** + * Group profile RSS view + * + * Displays a list of the latest content in the group + * + * @uses $vars['entity'] ElggGroup object + */ + +$entities = elgg_get_config('registered_entities'); + +if (!empty($entities['object'])) { +	echo elgg_list_entities(array( +		'type' => 'object', +		'subtypes' => $entities['object'], +		'container_guid' => $vars['entity']->getGUID(), +	)); +} diff --git a/mod/groups/views/rss/object/groupforumtopic.php b/mod/groups/views/rss/object/groupforumtopic.php new file mode 100644 index 000000000..b2d05d488 --- /dev/null +++ b/mod/groups/views/rss/object/groupforumtopic.php @@ -0,0 +1,35 @@ +<?php +/** + * Elgg groupforumtopic RSS view + * + * @package ElggGroups + */ + +$title = $vars['entity']->title; +if (empty($title)) { +	$title = strip_tags($vars['entity']->description); +	$title = elgg_get_excerpt($title, 32); +} + +$permalink = htmlspecialchars($vars['entity']->getURL(), ENT_NOQUOTES, 'UTF-8'); +$pubdate = date('r', $vars['entity']->getTimeCreated()); + +$description = elgg_autop($vars['entity']->description); + +$creator = elgg_view('page/components/creator', $vars); +$georss = elgg_view('page/components/georss', $vars); +$extension = elgg_view('extensions/item', $vars); + +$item = <<<__HTML +<item> +	<guid isPermaLink="true">$permalink</guid> +	<pubDate>$pubdate</pubDate> +	<link>$permalink</link> +	<title><![CDATA[$title]]></title> +	<description><![CDATA[$description]]></description> +	$creator$georss$extension +</item> + +__HTML; + +echo $item;  | 
