aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--actions/subgroups/add.php33
-rw-r--r--actions/subgroups/remove.php13
-rw-r--r--activate.php16
-rw-r--r--deactivate.php18
-rw-r--r--languages/ca.php22
-rwxr-xr-xlanguages/en.php30
-rw-r--r--languages/es.php22
-rw-r--r--languages/gl.php27
-rw-r--r--languages/pt.php7
-rw-r--r--lib/groups.php564
-rw-r--r--lib/subgroups.php84
-rw-r--r--manifest.xml24
-rw-r--r--pages/subgroups/edit.php46
-rw-r--r--pages/subgroups/owner.php38
-rw-r--r--start.php211
-rw-r--r--views/default/forms/groups/edit.php142
-rw-r--r--views/default/forms/subgroups/add.php37
-rw-r--r--views/default/group/default.php39
-rw-r--r--views/default/group/elements/summary.php67
-rw-r--r--views/default/groups/css/elements/components.php6
-rw-r--r--views/default/groups/group_sort_menu.php46
-rw-r--r--views/default/groups/profile/fields.php41
-rw-r--r--views/default/groups/sidebar/subgroups.php44
-rw-r--r--views/default/icon/default.php58
-rw-r--r--views/default/input/autocomplete.php57
-rw-r--r--views/default/navigation/breadcrumbs.php83
-rw-r--r--views/default/subgroups/group_module.php51
-rw-r--r--views/default/subgroups/groups_i_can_edit.php71
-rw-r--r--views/default/subgroups/subgroups_icons.php11
29 files changed, 1908 insertions, 0 deletions
diff --git a/actions/subgroups/add.php b/actions/subgroups/add.php
new file mode 100644
index 000000000..92416ea05
--- /dev/null
+++ b/actions/subgroups/add.php
@@ -0,0 +1,33 @@
+<?php
+
+elgg_load_library('elgg:subgroups');
+
+$group_guid = get_input('group');
+$othergroup_guid = get_input('othergroup');
+$othergroup_url = get_input('othergroup_url'); // maybe it isn't used
+$group = get_entity($group_guid);
+$othergroup = get_entity($othergroup_guid);
+
+if(!$othergroup && $othergroup = subgroups_get_group_from_url($othergroup_url)){
+ $othergroup_guid = $othergroup->guid;
+}
+
+if ($group instanceof ElggGroup && $group->canEdit() && $othergroup instanceof ElggGroup) {
+ if ($othergroup->canEdit() && $group_guid != $othergroup_guid) {
+ // Check if other group isn't currently a supergroup
+ $tree_group = $group;
+ while ($tree_group->container_guid > 0 && $tree_group->guid != $othergroup_guid) {
+ $tree_group = get_entity($tree_group->container_guid);
+ }
+ // Only save if there isn't circles in the tree.
+ if ($tree_group->guid != $othergroup_guid) {
+ $othergroup->container_guid = $group_guid;
+ $othergroup->save();
+ forward(REFERER);
+ }
+ }
+}
+
+register_error(elgg_echo('subgroups:add:error'));
+forward(REFERER);
+
diff --git a/actions/subgroups/remove.php b/actions/subgroups/remove.php
new file mode 100644
index 000000000..206673de3
--- /dev/null
+++ b/actions/subgroups/remove.php
@@ -0,0 +1,13 @@
+<?php
+
+$group_guid = get_input('group');
+$othergroup_guid = get_input('othergroup');
+$group = get_entity($group_guid);
+$othergroup = get_entity($othergroup_guid);
+if ($group instanceof ElggGroup && $group->canEdit()) {
+ if ($othergroup instanceof ElggGroup && $othergroup->canEdit() && $othergroup->container_guid == $group_guid) {
+ $othergroup->container_guid = $other_group->owner_guid;
+ $othergroup->save();
+ }
+}
+forward(REFERER);
diff --git a/activate.php b/activate.php
new file mode 100644
index 000000000..1e173fdd5
--- /dev/null
+++ b/activate.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Unsets container guids from all groups that aren't subgroups
+ */
+
+$groups = elgg_get_entities(array(
+ 'type' => 'group',
+ 'limit' => 0,
+));
+
+foreach($groups as $group) {
+ if (!elgg_instanceof($group->getContainerEntity(), 'group')) {
+ $group->container_guid = 0;
+ $group->save();
+ }
+}
diff --git a/deactivate.php b/deactivate.php
new file mode 100644
index 000000000..9b0cd1189
--- /dev/null
+++ b/deactivate.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ * Resets container guids from all groups that aren't subgroups to owner guid
+ */
+
+$groups = elgg_get_entities(array(
+ 'type' => 'group',
+ 'limit' => 0,
+));
+
+foreach($groups as $group) {
+ global $CONFIG;
+ if (!elgg_instanceof($group->getContainerEntity(), 'group')) {
+ $query = "UPDATE {$CONFIG->dbprefix}entities set"
+ . " container_guid=0 where guid={$group->owner_guid}";
+ update_data($query);
+ }
+}
diff --git a/languages/ca.php b/languages/ca.php
new file mode 100644
index 000000000..948b2ee95
--- /dev/null
+++ b/languages/ca.php
@@ -0,0 +1,22 @@
+<?php
+$language = array (
+ 'subgroups:new' => 'Nou subgrup',
+ 'subgroups:new:of' => 'Nou subgrup de «%s»',
+ 'subgroups:add:error' => 'Hi ha hagut un error. Has escrit bé el nom del grup?',
+ 'subgroups' => 'Subgrups',
+ 'subgroups:more' => 'Veure tots els subgrups',
+ 'subgroups:owner' => 'Subgrups de %s',
+ 'subgroups:owner:single' => 'Subgrup de %s',
+ 'subgroups:none' => 'Aquest grup no té subgrups.',
+ 'subgroups:group' => 'Subgrups del grup',
+ 'subgroups:in_frontpage' => 'Mostra els subgrups a la pàgina del grup',
+ 'subgroups:add' => 'Edita subgrups',
+ 'subgroups:add:label' => 'Escriu el nom del grup',
+ 'subgroups:addurl:label' => 'Copia l\'URL del grup aquí',
+ 'subgroups:add:button' => 'Afegeix com a subgrup',
+ 'subgroups:dontwork' => 'No funciona?',
+ 'subgroups:unlink' => 'Desvincula els grups',
+ 'add' => 'Afegeix',
+ 'subgroups:nopermissons' => 'No tens permissos per modificar el grup',
+);
+add_translation("ca", $language); \ No newline at end of file
diff --git a/languages/en.php b/languages/en.php
new file mode 100755
index 000000000..e08e22e34
--- /dev/null
+++ b/languages/en.php
@@ -0,0 +1,30 @@
+<?php
+/**
+ * Elgg subgroups plugin language pack
+ *
+ * @package ElggSubgroups
+ */
+
+$english = array(
+ "subgroups" => 'Subgroups',
+ "subgroups:more" => 'View all subgroups',
+ "subgroups:owner" => 'Subgroups of %s',
+ "subgroups:owner:single" => 'Subgroup of %s',
+ "subgroups:none" => 'This group has no subgroups.',
+ "subgroups:group" => 'Group subgroups',
+ "subgroups:in_frontpage" => 'Show subgroups on group page',
+ "subgroups:add" => 'Manage subgroups',
+ "subgroups:new" => 'New subgroup',
+ "subgroups:add_existing" => 'Add existing one',
+ "subgroups:new:of" => 'New subgroup of &laquo;%s&raquo;',
+ "subgroups:add:label" => "Write the group's name",
+ "subgroups:addurl:label" => "Copy the group URL here",
+ "subgroups:add:button" => 'Add as subgroup',
+ "subgroups:dontwork" => "Doesn't it work?",
+ "subgroups:unlink" => 'Unlink groups',
+ "add" => "Add",
+ "subgroups:nopermissons" => 'You have no permissons to modify that subgroups',
+ "subgroups:add:error" => 'There are an error. Did you write correctly the group\'s name?',
+);
+
+add_translation("en", $english);
diff --git a/languages/es.php b/languages/es.php
new file mode 100644
index 000000000..b86a97423
--- /dev/null
+++ b/languages/es.php
@@ -0,0 +1,22 @@
+<?php
+$es = array (
+ 'subgroups' => 'Subgrupos',
+ 'subgroups:more' => 'Ver todos los subgrupos',
+ 'subgroups:owner' => 'Subgrupos de %s',
+ 'subgroups:owner:single' => 'Subgrupo de %s',
+ 'subgroups:none' => 'Este grupo no tiene subgrupos.',
+ 'subgroups:group' => 'Subgrupos del grupo',
+ 'subgroups:in_frontpage' => 'Muestra los subgrupos en la página del grupo',
+ 'subgroups:add' => 'Subgrupos',
+ 'subgroups:add:label' => 'Escribe el nombre del grupo',
+ 'subgroups:addurl:label' => 'Copia la URL del grupo aquí',
+ 'subgroups:add:button' => 'Añade como subgrupo',
+ 'subgroups:dontwork' => 'No funciona?',
+ 'subgroups:unlink' => 'Desvincula grupos',
+ 'add' => 'Añade',
+ 'subgroups:nopermissons' => 'No tienes permisos para modificar el grupo',
+ 'subgroups:add:error' => 'Ha habido un error. Has escrito bien el nombre del grupo?',
+);
+
+add_translation("es", $es);
+
diff --git a/languages/gl.php b/languages/gl.php
new file mode 100644
index 000000000..3a91d9fc4
--- /dev/null
+++ b/languages/gl.php
@@ -0,0 +1,27 @@
+<?php
+/**
+* Elgg subgroups plugin language pack
+*
+* @package ElggSubgroups
+*/
+
+$galician = array(
+ "subgroups" => 'Subgrupos',
+ "subgroups:more" => 'Ver tódolos subgrupos',
+ "subgroups:owner" => 'Subgrupos de %s',
+ "subgroups:owner:single" => 'Subgrupo de %s',
+ "subgroups:none" => 'Iste grupo non ten subgrupos.',
+ "subgroups:group" => 'Subgrupos do grupo',
+ "subgroups:in_frontpage" => 'Mostra os subgrupos na páxina do grupo',
+ "subgroups:add" => 'Edita os subgrupos',
+ "subgroups:add:label" => "Escribe o nome do grupo",
+ "subgroups:addurl:label" => "Copia a URL do grupo eiquí",
+ "subgroups:add:button" => 'Añade como subgrupo',
+ "subgroups:dontwork" => "Non funciona?",
+ "subgroups:unlink" => 'Desvincula grupos',
+ "add" => "Engade",
+ "subgroups:nopermissons" => 'Non tes permisos para modificar o grupo',
+ "subgroups:add:error" => 'Houbo un erro. Escribiches ben o nome do grupo?',
+);
+
+add_translation("gl", $galician);
diff --git a/languages/pt.php b/languages/pt.php
new file mode 100644
index 000000000..f116ed9de
--- /dev/null
+++ b/languages/pt.php
@@ -0,0 +1,7 @@
+<?php
+$pt = array (
+ 'add' => 'Adicionar',
+);
+
+add_translation("pt", $pt);
+
diff --git a/lib/groups.php b/lib/groups.php
new file mode 100644
index 000000000..82bd6226d
--- /dev/null
+++ b/lib/groups.php
@@ -0,0 +1,564 @@
+<?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',
+ 'container_guid' => 0,
+ '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',
+ 'container_guid' => 0,
+ '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");
+ $title = elgg_echo('groups:search:title', array($tag));
+
+ // groups plugin saves tags as "interests" - see groups_fields_setup() in start.php
+ $params = array(
+ 'metadata_name' => 'interests',
+ 'metadata_value' => $tag,
+ 'types' => '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);
+
+ 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);
+
+ elgg_register_title_button();
+
+ $content = elgg_list_entities_from_relationship_count(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');
+ }
+
+ $filter = elgg_view('groups/group_sort_menu', array('selected' => $selected_tab));
+
+ $params = array(
+ 'content' => $content,
+ 'title' => $title,
+ 'filter' => $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 (!$group) {
+ forward('groups/all');
+ }
+ elgg_push_breadcrumb($group->name);
+
+ groups_register_profile_buttons($group);
+
+ $content = elgg_view('groups/profile/layout', array('entity' => $group));
+ if (group_gatekeeper(false)) {
+ $sidebar = '';
+ if (elgg_is_active_plugin('search')) {
+ $sidebar .= elgg_view('groups/sidebar/search', array('entity' => $group));
+ }
+ $sidebar .= elgg_view('groups/sidebar/members', array('entity' => $group));
+ } else {
+ $sidebar = '';
+ }
+
+ $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'));
+
+ $content = elgg_list_entities_from_relationship(array(
+ 'relationship' => 'member',
+ 'relationship_guid' => $group->guid,
+ 'inverse_relationship' => true,
+ 'types' => 'user',
+ 'limit' => 20,
+ ));
+
+ $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;
+ }
+
+ $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/lib/subgroups.php b/lib/subgroups.php
new file mode 100644
index 000000000..ffa531e16
--- /dev/null
+++ b/lib/subgroups.php
@@ -0,0 +1,84 @@
+<?php
+/**
+ * Subgroups helper functions
+ *
+ * @package ElggSubgroups
+ */
+
+
+/**
+ * Gives the list of the group subgroups
+ *
+ * @param ElggGroup $group
+ * @return array
+ */
+function get_subgroups($group, $options = array()){
+ if($group instanceof ElggGroup){
+
+ $options['type'] = 'group';
+ $options['container_guid'] = $group->guid;
+ return elgg_get_entities($options);
+
+ } else {
+ return false;
+ }
+}
+
+function list_subgroups($group, $options = array()){
+
+ if($group instanceof ElggGroup){
+
+ $defaults = array(
+ 'full_view' => false,
+ 'pagination' => true,
+ );
+ $options = array_merge($defaults, $options);
+
+ $options['type'] = 'group';
+ $options['container_guid'] = $group->guid;
+
+ elgg_push_context('subgroups');
+ $list = elgg_list_entities($options);
+ elgg_pop_context();
+
+ return $list;
+
+ } else {
+ return "";
+ }
+}
+
+function subgroups_group_url_matches($url){
+ $url = parse_url($url);
+ $pattern1 = "/groups\/profile\/(?P<group_guid>\d+)/";
+ $pattern2 = "/g\/(?P<group_alias>[^\/]+)/";
+
+ $matches1 = array();
+ $matches2 = array();
+
+ preg_match($pattern1, $url['path'], $matches1);
+ preg_match($pattern2, $url['path'], $matches2);
+
+ if(!empty($matches1) || !empty($matches2)) {
+ return array_merge($matches1, $matches2);
+ } else {
+ return false;
+ }
+}
+
+function subgroups_get_group_from_url($group_url){
+ $matches = subgroups_group_url_matches($group_url);
+ $group_guid = $matches['group_guid'];
+ $group_alias = $matches['group_alias'];
+
+ $group = get_entity($group_guid);
+ if(!$group && elgg_is_active_plugin('group_alias')) {
+ $group = get_group_from_group_alias($group_alias);
+ }
+
+ if($group && $group->getURL() == $group_url){
+ return $group;
+ } else {
+ return false;
+ }
+}
diff --git a/manifest.xml b/manifest.xml
new file mode 100644
index 000000000..f4f249133
--- /dev/null
+++ b/manifest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<plugin_manifest xmlns="http://www.elgg.org/plugin_manifest/1.8">
+ <name>Subgroups</name>
+ <author>Lorea</author>
+ <version>1.1-beta2</version>
+ <description>Group admins can create subgroups.</description>
+ <website>https://lorea.cc/</website>
+ <copyright>(C) Lorea 2011</copyright>
+ <license>GNU Public License version 2</license>
+
+ <category>enhancement</category>
+
+ <requires>
+ <type>elgg_release</type>
+ <version>1.8</version>
+ </requires>
+
+ <requires>
+ <type>priority</type>
+ <priority>after</priority>
+ <plugin>groups</plugin>
+ </requires>
+
+</plugin_manifest>
diff --git a/pages/subgroups/edit.php b/pages/subgroups/edit.php
new file mode 100644
index 000000000..f8b0921ef
--- /dev/null
+++ b/pages/subgroups/edit.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ * Manage subgroups page
+ *
+ * @package ElggSubroups
+ */
+
+elgg_load_library('elgg:subgroups');
+
+$page_owner = elgg_get_page_owner_entity();
+elgg_set_context('groups');
+
+if(!($page_owner instanceof ElggGroup) || !$page_owner->canEdit()){
+ forward($page_owner->getURL());
+}
+
+elgg_push_breadcrumb(elgg_echo('group'),'groups/all');
+elgg_push_breadcrumb($page_owner->name, $page_owner->getURL());
+
+$title = elgg_echo('subgroups:add');
+elgg_push_breadcrumb($title);
+
+elgg_register_title_button('subgroups', 'new');
+
+elgg_register_menu_item('title', array(
+ 'name' => 'add_existing',
+ 'href' => "#subgroups-add",
+ 'text' => elgg_echo("subgroups:add_existing"),
+ 'rel' => 'toggle',
+ 'link_class' => 'elgg-button elgg-button-action',
+ 'priority' => 200,
+));
+
+$form_vars = array('class' => 'hidden', 'id' => 'subgroups-add');
+$body_vars = array('group' => $page_owner);
+
+$content = elgg_view_form('subgroups/add', $form_vars, $body_vars);
+$content .= list_subgroups($page_owner);
+
+$body = elgg_view_layout('content', array(
+ 'content' => $content,
+ 'title' => $title,
+ 'filter' => ''
+));
+
+echo elgg_view_page($title, $body);
diff --git a/pages/subgroups/owner.php b/pages/subgroups/owner.php
new file mode 100644
index 000000000..ae06d968d
--- /dev/null
+++ b/pages/subgroups/owner.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ * List of group's subgroups
+ *
+ * @package ElggSubgroups
+ */
+
+elgg_load_library('elgg:subgroups');
+
+// access check for closed groups
+group_gatekeeper();
+
+$owner = elgg_get_page_owner_entity();
+if (!$owner) {
+ forward('groups/all');
+}
+
+elgg_register_title_button();
+
+$title = elgg_echo("subgroups:owner", array($owner->name));
+
+elgg_push_breadcrumb(elgg_echo('groups'), "groups/all");
+elgg_push_breadcrumb($owner->name, $owner->getURL());
+elgg_push_breadcrumb(elgg_echo('relatedgroups'));
+
+// List
+$content = list_subgroups($owner);
+if (!$content) {
+ $content = elgg_echo("subgroups:none");
+}
+
+$body = elgg_view_layout('content', array(
+ 'title' => $title,
+ 'content' => $content,
+ 'filter' => '',
+));
+
+echo elgg_view_page($title, $body);
diff --git a/start.php b/start.php
new file mode 100644
index 000000000..803567f18
--- /dev/null
+++ b/start.php
@@ -0,0 +1,211 @@
+<?php
+/**
+ * Elgg subgroups plugin
+ *
+ * @package ElggSubgroups
+ *
+ * TODO:
+ * * ElggSubgroup class with getMetaContainerGUID() ?
+ * * Subgroup graphs
+ *
+ */
+
+elgg_register_event_handler('init', 'system', 'subgroups_init');
+
+/**
+ * Subgroups plugin initialization functions.
+ */
+function subgroups_init() {
+ // register a library of helper functions
+ elgg_register_library('elgg:subgroups', elgg_get_plugins_path() . 'subgroups/lib/subgroups.php');
+ // override groups library
+ elgg_register_library('elgg:groups', elgg_get_plugins_path() . 'subgroups/lib/groups.php');
+
+ // Register actions
+ $actions_path = elgg_get_plugins_path() . 'subgroups/actions/subgroups';
+ elgg_register_action("subgroups/add", $actions_path."/add.php");
+ elgg_register_action("subgroups/remove", $actions_path."/remove.php");
+
+ // Register page handler
+ elgg_register_page_handler('subgroups', 'subgroups_page_handler');
+
+ // Register pagesetup event handler
+ elgg_register_event_handler('pagesetup', 'system', 'subgroups_setup_sidebar_menus');
+
+ // Register unsetter container_guid handler
+ elgg_register_event_handler('update', 'group', 'subgroups_unset_group_container');
+
+ // Register an unrelate link to entity menu (max priority to run the last)
+ elgg_register_plugin_hook_handler('register', 'menu:entity', 'subgroups_menu_setup', 9999);
+
+ // Extend group fields
+ elgg_register_plugin_hook_handler('profile:fields', 'group', 'subgroups_add_container_field');
+
+ // Access permissions
+ elgg_register_plugin_hook_handler('access:collections:write', 'all', 'subgroups_read_acl_plugin_hook');
+
+ // Extending views
+ elgg_extend_view('groups/sidebar/members', 'groups/sidebar/subgroups', 300);
+ //TODO elgg_extend_view('groups/forum_latest', 'subgroups/frontpage');
+
+ // Extending CSS
+ elgg_extend_view('css/elements/components', 'groups/css/elements/components');
+
+ elgg_register_ajax_view('subgroups/groups_i_can_edit');
+
+ // Add group tool
+ add_group_tool_option('subgroups', elgg_echo('subgroups:in_frontpage'), false);
+ elgg_extend_view('groups/tool_latest', 'subgroups/group_module');
+}
+
+/**
+ * Configure the groups sidebar menu. Triggered on page setup
+ *
+ */
+function subgroups_setup_sidebar_menus() {
+
+ elgg_unregister_menu_item('page', 'groups:member');
+
+ // Get the page owner entity
+ $page_owner = elgg_get_page_owner_entity();
+
+ if (elgg_get_context() == 'group_profile' || elgg_get_context() == 'groups') {
+ if ($page_owner instanceof ElggGroup) {
+ if (elgg_is_logged_in() && $page_owner->canEdit() || elgg_is_admin_logged_in()) {
+ $url = elgg_get_site_url() . "subgroups/edit/{$page_owner->getGUID()}";
+ elgg_register_menu_item('page', array(
+ 'name' => 'subgroups',
+ 'text' => elgg_echo('subgroups:add'),
+ 'href' => $url,
+ ));
+ }
+ }
+ }
+}
+
+/**
+ * Dispatches subgroups pages.
+ * URLs take the form of
+ *
+ * Group view subgroups: subgroups/owner/<group_guid>
+ * Group manage subgroups: subgroups/manage/<group_guid>
+ *
+ * @param array $page
+ * @return NULL
+ */
+function subgroups_page_handler($page){
+ $pages_path = elgg_get_plugins_path() . "subgroups/pages";
+
+ switch($page[0]) {
+ case 'add':
+ case 'edit':
+ elgg_set_page_owner_guid($page[1]);
+ include($pages_path."/subgroups/edit.php");
+ break;
+ case 'owner':
+ elgg_set_page_owner_guid($page[1]);
+ include($pages_path."/subgroups/owner.php");
+ break;
+ case 'new':
+ $group = new ElggGroup((int)$page[1]);
+
+ if (!$group->guid) {
+ register_error(elgg_echo('error:default'));
+ return false;
+ }
+
+ elgg_load_library('elgg:groups');
+ $title = elgg_echo('subgroups:new:of', array($group->name));
+
+ elgg_push_breadcrumb(elgg_echo('groups'), "groups/all");
+ elgg_push_breadcrumb($group->name, $group->getURL());
+ elgg_push_breadcrumb(elgg_echo('subgroups:new'));
+
+ set_input('container_guid', $group->guid);
+
+ $body = elgg_view_layout('content', array(
+ 'content' => elgg_view('groups/edit'),
+ 'title' => $title,
+ 'filter' => '',
+ ));
+ echo elgg_view_page($title, $body);
+
+ break;
+ default:
+ return false;
+ }
+ return true;
+}
+
+function subgroups_menu_setup($hook, $type, $return, $params){
+
+ $group = elgg_get_page_owner_entity();
+ $othergroup = $params['entity'];
+
+ if($group instanceof ElggGroup && $group->canEdit() &&
+ $othergroup instanceof ElggGroup &&
+ elgg_in_context('subgroups')){
+
+ // Delete all previous links
+ $return = array();
+
+ $url = elgg_http_add_url_query_elements('action/subgroups/remove', array(
+ 'group' => $group->guid,
+ 'othergroup' => $othergroup->guid,
+ ));
+
+ $options = array(
+ 'name' => 'delete',
+ 'href' => $url,
+ 'text' => "<span class=\"elgg-icon elgg-icon-delete\"></span>",
+ 'confirm' => elgg_echo('deleteconfirm'),
+ 'text_encode' => false,
+ );
+ $return[] = ElggMenuItem::factory($options);
+ }
+ return $return;
+}
+
+/**
+ * Unset container guid when a group is created. Triggered on group save.
+ * Using SQL since event is triggered on save() function and we can't do
+ * call the function again.
+ *
+ */
+function subgroups_unset_group_container($event, $object_type, $entity) {
+ global $CONFIG;
+ if (!elgg_instanceof($entity->getContainerEntity(), 'group')) {
+ $query = "UPDATE {$CONFIG->dbprefix}entities set"
+ . " container_guid=0 where guid={$entity->guid}";
+ return !!(update_data($query));
+ }
+ return true;
+}
+
+function subgroups_add_container_field($hook, $type, $return, $params) {
+ $return['container_guid'] = 'hidden';
+ return $return;
+}
+
+/**
+ * Hook to listen to read access control requests and return parent groups.
+ */
+function subgroups_read_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) {
+ $parent_group = $page_owner->getContainerEntity();
+ while ($parent_group) {
+ $returnvalue[$parent_group->group_acl] = elgg_echo('groups:group') . ': ' . $parent_group->name;
+ $parent_group = $parent_group->getContainerEntity();
+ }
+ }
+
+ return $returnvalue;
+}
diff --git a/views/default/forms/groups/edit.php b/views/default/forms/groups/edit.php
new file mode 100644
index 000000000..e2f9fb394
--- /dev/null
+++ b/views/default/forms/groups/edit.php
@@ -0,0 +1,142 @@
+<?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');
+unset($group_profile_fields['container_guid']);
+
+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
+}
+
+$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 (isset($entity)) {
+ echo elgg_view('input/hidden', array(
+ 'name' => 'group_guid',
+ 'value' => $entity->getGUID(),
+ ));
+}
+
+echo elgg_view('input/hidden', array(
+ 'name' => 'container_guid',
+ 'value' => isset($vars['entity']) ?
+ $entity->getContainerGUID() :
+ get_input('container_guid'),
+));
+
+echo elgg_view('input/submit', array('value' => elgg_echo('save')));
+
+if (isset($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/views/default/forms/subgroups/add.php b/views/default/forms/subgroups/add.php
new file mode 100644
index 000000000..f0349a728
--- /dev/null
+++ b/views/default/forms/subgroups/add.php
@@ -0,0 +1,37 @@
+<label class="subgroups-add-autocomplete" style="display:none">
+<?php
+ echo elgg_echo('subgroups:add:label'); echo '<br />';
+ echo elgg_view('input/autocomplete', array(
+ 'name' => 'othergroup',
+ 'livesearch_url' => elgg_get_site_url().'ajax/view/subgroups/groups_i_can_edit',
+ 'class' => 'mvm',
+ ));
+?>
+</label>
+<label class="subgroups-add-url">
+<?php
+ echo elgg_echo('subgroups:addurl:label'); echo '<br />';
+ echo elgg_view('input/url', array('name' => 'othergroup_url', 'class' => 'mvm'));
+?>
+</label>
+<?php
+ echo elgg_view('input/hidden', array(
+ 'name' => 'group',
+ 'value' => $vars['group']->guid));
+ echo elgg_view('input/submit', array(
+ 'value' => elgg_echo('subgroups:add:button')));
+?>
+<a href="" class="subgroups-dontwork-link mlm" style="display:none">(<?php echo elgg_echo('subgroups:dontwork'); ?>)</a>
+
+<script type="text/javascript">
+$(function(){
+ $('.subgroups-add-autocomplete').show();
+ $('.subgroups-add-url').hide();
+ $('.subgroups-dontwork-link').show().click(function(){
+ $('.subgroups-add-autocomplete').hide();
+ $('.subgroups-add-url').show();
+ $(this).hide();
+ return false;
+ });
+});
+</script>
diff --git a/views/default/group/default.php b/views/default/group/default.php
new file mode 100644
index 000000000..9c0356550
--- /dev/null
+++ b/views/default/group/default.php
@@ -0,0 +1,39 @@
+<?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 (elgg_get_context() == 'gallery') {
+ echo $icon;
+} elseif ($vars['full_view']) {
+ echo elgg_view("groups/profile/profile_block", $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/views/default/group/elements/summary.php b/views/default/group/elements/summary.php
new file mode 100644
index 000000000..a95d1e296
--- /dev/null
+++ b/views/default/group/elements/summary.php
@@ -0,0 +1,67 @@
+<?php
+/**
+ * Group summary
+ *
+ * @uses $vars['entity'] ElggEntity
+ * @uses $vars['title'] Title link (optional) false = no title, '' = default
+ * @uses $vars['metadata'] HTML for entity menu and metadata (optional)
+ * @uses $vars['subtitle'] HTML for the subtitle (optional)
+ * @uses $vars['tags'] HTML for the tags (optional)
+ * @uses $vars['content'] HTML for the entity content (optional)
+ */
+
+$entity = $vars['entity'];
+
+$title_link = elgg_extract('title', $vars, '');
+if ($title_link === '') {
+ if (isset($entity->title)) {
+ $text = $entity->title;
+ } else {
+ $text = $entity->name;
+ }
+ $params = array(
+ 'text' => $text,
+ 'href' => $entity->getURL(),
+ 'is_trusted' => true,
+ );
+ $title_link = elgg_view('output/url', $params);
+}
+
+$metadata = elgg_extract('metadata', $vars, '');
+$subtitle = elgg_extract('subtitle', $vars, '');
+$content = elgg_extract('content', $vars, '');
+
+$container = get_entity($entity->container_guid);
+
+$tags = elgg_extract('tags', $vars, '');
+if ($tags !== false) {
+ $tags = elgg_view('output/tags', array('tags' => $entity->tags));
+}
+
+if ($metadata) {
+ echo $metadata;
+}
+if ($title_link) {
+ echo "<h3>$title_link</h3>";
+}
+if(elgg_instanceof($container, 'group')) {
+ $container_link = elgg_view('output/url', array(
+ 'text' => $container->name,
+ 'href' => $container->getURL(),
+ 'is_trusted' => true,
+ ));
+ $container_link = elgg_echo('subgroups:owner:single', array($container_link));
+ echo "<div class=\"elgg-subtext\">$container_link</div>";
+}
+echo "<div class=\"elgg-subtext\">$subtitle</div>";
+
+$subgroups = elgg_view('subgroups/subgroups_icons', array('entity' => $entity));
+echo "<div class=\"subgroups-icons\">$subgroups</div>";
+
+echo $tags;
+
+echo elgg_view('object/summary/extend', $vars);
+
+if ($content) {
+ echo "<div class=\"elgg-content\">$content</div>";
+}
diff --git a/views/default/groups/css/elements/components.php b/views/default/groups/css/elements/components.php
new file mode 100644
index 000000000..0198fa309
--- /dev/null
+++ b/views/default/groups/css/elements/components.php
@@ -0,0 +1,6 @@
+/* ***************************************
+ Gallery
+*************************************** */
+.elgg-gallery-groups > li {
+ margin: 0 2px;
+}
diff --git a/views/default/groups/group_sort_menu.php b/views/default/groups/group_sort_menu.php
new file mode 100644
index 000000000..7e4d1bca6
--- /dev/null
+++ b/views/default/groups/group_sort_menu.php
@@ -0,0 +1,46 @@
+<?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' => 400,
+ ),
+
+ 'discussion' => array(
+ 'text' => elgg_echo('groups:latestdiscussion'),
+ 'href' => 'groups/all?filter=discussion',
+ 'priority' => 500,
+ ),
+);
+
+if ($user = elgg_get_logged_in_user_entity()) {
+ $tabs['member'] = array(
+ 'text' => elgg_echo('groups:yours'),
+ 'href' => "groups/member/$user->username",
+ 'priority' => 300,
+ );
+}
+
+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/views/default/groups/profile/fields.php b/views/default/groups/profile/fields.php
new file mode 100644
index 000000000..41b0de9a0
--- /dev/null
+++ b/views/default/groups/profile/fields.php
@@ -0,0 +1,41 @@
+<?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 or hidden values
+ if ($key == 'name' || $valtype == 'hidden') {
+ continue;
+ }
+
+ $value = $group->$key;
+ if (empty($value)) {
+ continue;
+ }
+
+ $options = array('value' => $group->$key);
+ if ($valtype == 'tags') {
+ $options['tag_names'] = $key;
+ }
+
+ if ($output = elgg_view("output/$valtype", $options)) {
+
+ echo "<div class=\"{$even_odd}\">";
+ echo "<b>";
+ echo elgg_echo("groups:$key");
+ echo ": </b>";
+ echo $output;
+ echo "</div>";
+
+ $even_odd = ($even_odd == 'even') ? 'odd' : 'even';
+ }
+ }
+}
diff --git a/views/default/groups/sidebar/subgroups.php b/views/default/groups/sidebar/subgroups.php
new file mode 100644
index 000000000..35ffbaef9
--- /dev/null
+++ b/views/default/groups/sidebar/subgroups.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ * Subgroups sidebar
+ *
+ * @package ElggSubgroups
+ *
+ * @uses $vars['entity'] Group entity
+ * @uses $vars['limit'] The number of subgroups to display
+ */
+
+$owner = elgg_get_page_owner_entity();
+
+if(!elgg_instanceof($owner, 'group')) {
+ return false;
+}
+
+$limit = elgg_extract('limit', $vars, 10);
+
+$all_link = elgg_view('output/url', array(
+ 'href' => 'subgroups/owner/' . $owner->guid,
+ 'text' => elgg_echo('subgroups:more'),
+ 'is_trusted' => true,
+));
+
+$params = array(
+ 'type' => 'group',
+ 'container_guid' => $owner->guid,
+ 'limit' => $limit,
+ 'types' => 'group',
+ 'list_type' => 'gallery',
+ 'gallery_class' => 'elgg-gallery-groups',
+ 'full_view' => false
+);
+
+$params['count'] = true;
+if(elgg_get_entities($params) == 0) {
+ return true;
+}
+$params['count'] = false;
+
+$body = elgg_list_entities($params);
+$body .= "<div class='center mts'>$all_link</div>";
+
+echo elgg_view_module('aside', elgg_echo('subgroups'), $body);
diff --git a/views/default/icon/default.php b/views/default/icon/default.php
new file mode 100644
index 000000000..3ef1a05a1
--- /dev/null
+++ b/views/default/icon/default.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ * Generic icon view.
+ *
+ * @package Elgg
+ * @subpackage Core
+ *
+ * @uses $vars['entity'] The entity the icon represents - uses getIconURL() method
+ * @uses $vars['size'] topbar, tiny, small, medium (default), large, master
+ * @uses $vars['href'] Optional override for link
+ * @uses $vars['img_class'] Optional CSS class added to img
+ * @uses $vars['link_class'] Optional CSS class for the link
+ */
+
+$entity = $vars['entity'];
+
+$sizes = array('small', 'medium', 'large', 'tiny', 'master', 'topbar');
+// Get size
+if (!in_array($vars['size'], $sizes)) {
+ $vars['size'] = "medium";
+}
+
+$class = elgg_extract('img_class', $vars, '');
+
+if (isset($entity->name)) {
+ $title = $entity->name;
+} else {
+ $title = $entity->title;
+}
+$title = htmlspecialchars($title, ENT_QUOTES, 'UTF-8', false);
+
+$url = $entity->getURL();
+if (isset($vars['href'])) {
+ $url = $vars['href'];
+}
+
+$img = elgg_view('output/img', array(
+ 'src' => $entity->getIconURL($vars['size']),
+ 'alt' => $title,
+ 'class' => $class,
+));
+
+if ($url) {
+ $params = array(
+ 'href' => $url,
+ 'text' => $img,
+ 'title' => $title,
+ 'is_trusted' => true,
+ );
+ $class = elgg_extract('link_class', $vars, '');
+ if ($class) {
+ $params['class'] = $class;
+ }
+
+ echo elgg_view('output/url', $params);
+} else {
+ echo $img;
+}
diff --git a/views/default/input/autocomplete.php b/views/default/input/autocomplete.php
new file mode 100644
index 000000000..4eedac22a
--- /dev/null
+++ b/views/default/input/autocomplete.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ * Displays an autocomplete text input.
+ *
+ * @package Elgg
+ * @subpackage Core
+ *
+ * @todo This currently only works for ONE AUTOCOMPLETE TEXT FIELD on a page.
+ *
+ * @uses $vars['value'] Current value for the text input
+ * @uses $vars['match_on'] Array | str What to match on. all|array(groups|users|friends)
+ * @uses $vars['match_owner'] Bool. Match only entities that are owned by logged in user.
+ * @uses $vars['livesearsh_url'] Alternative livesearch URL
+ * @uses $vars['class'] Additional CSS class
+ */
+
+if (isset($vars['class'])) {
+ $vars['class'] = "elgg-input-autocomplete {$vars['class']}";
+} else {
+ $vars['class'] = "elgg-input-autocomplete";
+}
+
+if (isset($vars['livesearch_url'])) {
+ $livesearch_url = $vars['livesearch_url'];
+ unset($vars['livesearch_url']);
+} else {
+ $livesearch_url = elgg_get_site_url() . 'livesearch';
+}
+
+$defaults = array(
+ 'value' => '',
+ 'disabled' => false,
+);
+
+$vars = array_merge($defaults, $vars);
+
+$params = array();
+if (isset($vars['match_on'])) {
+ $params['match_on'] = $vars['match_on'];
+ unset($vars['match_on']);
+}
+if (isset($vars['match_owner'])) {
+ $params['match_owner'] = $vars['match_owner'];
+ unset($vars['match_owner']);
+}
+$ac_url_params = http_build_query($params);
+
+elgg_load_js('elgg.autocomplete');
+elgg_load_js('jquery.ui.autocomplete.html');
+
+?>
+
+<script type="text/javascript">
+elgg.provide('elgg.autocomplete');
+elgg.autocomplete.url = "<?php echo $livesearch_url . '?' . $ac_url_params; ?>";
+</script>
+<input type="text" <?php echo elgg_format_attributes($vars); ?> />
diff --git a/views/default/navigation/breadcrumbs.php b/views/default/navigation/breadcrumbs.php
new file mode 100644
index 000000000..6ceb5eacc
--- /dev/null
+++ b/views/default/navigation/breadcrumbs.php
@@ -0,0 +1,83 @@
+<?php
+/**
+ * Displays breadcrumbs.
+ *
+ * @package Elgg
+ * @subpackage Core
+ *
+ * @uses $vars['breadcrumbs'] (Optional) Array of arrays with keys 'title' and 'link'
+ * @uses $vars['class']
+ *
+ * @see elgg_push_breadcrumb
+ */
+
+if (isset($vars['breadcrumbs'])) {
+ $breadcrumbs = $vars['breadcrumbs'];
+} else {
+ $breadcrumbs = elgg_get_breadcrumbs();
+}
+
+
+$page_owner = elgg_get_page_owner_entity();
+
+if(elgg_instanceof($page_owner, 'group')) {
+
+ // $breadcrumbs[1] should corresponds to group's breadcrumb
+ // we'll look for it in crumbs link
+
+ $link = $breadcrumbs[1]['link'];
+ $guid = (string) $page_owner->guid;
+ $alias = $page_owner->alias;
+
+ $title = $breadcrumbs[1]['title'];
+ $name = $page_owner->name;
+
+ if(strpos($link, $guid) || $alias && strpos($link, $alias) || !$link && $title == $name) {
+ $first_crumb = array_shift($breadcrumbs);
+ $container = get_entity($page_owner->container_guid);
+ while(elgg_instanceof($container, 'group')) {
+
+ // TODO: I should find a better solution for this.
+ if(strpos($first_crumb['link'], 'groups') !== false) {
+ $container_link = str_replace('all', "profile/$container->guid", $first_crumb['link']);
+ } elseif(strpos($first_crumb['link'], 'discussion') !== false) {
+ $container_link = str_replace('all', "owner/$container->guid", $first_crumb['link']);
+ } else {
+ $container_link = str_replace('all', "group/$container->guid", $first_crumb['link']);
+ }
+
+ $container_link = elgg_trigger_plugin_hook('container_crumb_link', 'breadcrumbs', array('container' => $container, 'first_crumb' => $first_crumb), $container_link);
+
+ array_unshift($breadcrumbs, array(
+ 'title' => $container->name,
+ 'link' => $container_link,
+ ));
+ $container = get_entity($container->container_guid);
+ }
+ array_unshift($breadcrumbs, $first_crumb);
+ }
+}
+
+
+$class = 'elgg-menu elgg-breadcrumbs';
+$additional_class = elgg_extract('class', $vars, '');
+if ($additional_class) {
+ $class = "$class $additional_class";
+}
+
+if (is_array($breadcrumbs) && count($breadcrumbs) > 0) {
+ echo "<ul class=\"$class\">";
+ foreach ($breadcrumbs as $breadcrumb) {
+ if (!empty($breadcrumb['link'])) {
+ $crumb = elgg_view('output/url', array(
+ 'href' => $breadcrumb['link'],
+ 'text' => $breadcrumb['title'],
+ 'is_trusted' => true,
+ ));
+ } else {
+ $crumb = $breadcrumb['title'];
+ }
+ echo "<li>$crumb</li>";
+ }
+ echo '</ul>';
+}
diff --git a/views/default/subgroups/group_module.php b/views/default/subgroups/group_module.php
new file mode 100644
index 000000000..083e50b16
--- /dev/null
+++ b/views/default/subgroups/group_module.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ * List subgroups on group profile page
+ *
+ * @package ElggSubgroups
+ */
+
+$group = elgg_get_page_owner_entity();
+
+if ($group->subgroups_enable != "yes") {
+ return true;
+}
+
+$all_link = elgg_view('output/url', array(
+ 'href' => "subgroups/owner/$group->guid/all",
+ 'text' => elgg_echo('link:view:all'),
+ 'is_trusted' => true,
+));
+
+$options = array(
+ 'type' => 'group',
+ 'container_guid' => $group->guid,
+ 'type' => 'group',
+ 'limit' => 6,
+ 'full_view' => false,
+ 'pagination' => false,
+);
+
+elgg_push_context('widgets');
+$content = elgg_list_entities($options);
+elgg_pop_context();
+
+if (!$content) {
+ $content = '<p>' . elgg_echo('subgroups:none') . '</p>';
+}
+if($group->canEdit()) {
+ $new_link = elgg_view('output/url', array(
+ 'href' => "subgroups/add/$group->guid",
+ 'text' => elgg_echo('subgroups:add'),
+ 'is_trusted' => true,
+ ));
+} else {
+ $new_link = false;
+}
+
+echo elgg_view('groups/profile/module', array(
+ 'title' => elgg_echo('subgroups:group'),
+ 'content' => $content,
+ 'all_link' => $all_link,
+ 'add_link' => $new_link,
+));
diff --git a/views/default/subgroups/groups_i_can_edit.php b/views/default/subgroups/groups_i_can_edit.php
new file mode 100644
index 000000000..45b0c9e6e
--- /dev/null
+++ b/views/default/subgroups/groups_i_can_edit.php
@@ -0,0 +1,71 @@
+<?php
+
+if (!elgg_is_logged_in()) {
+ exit();
+}
+
+$q = sanitise_string(get_input('term'));
+
+// replace mysql vars with escaped strings
+$q = str_replace(array('_', '%'), array('\_', '\%'), $q);
+
+$user_guid = elgg_get_logged_in_user_guid();
+$entities = elgg_get_entities(array(
+ 'type' => 'group',
+ 'owner_guid' => $user_guid,
+ 'limit' => 0,
+));
+$entities = array_merge(
+ $entities,
+ elgg_get_entities_from_relationship(array(
+ 'type' => 'group',
+ 'relationship' => 'operator',
+ 'relationship_guid' => $user_guid,
+ 'limit' => 0,
+ ))
+);
+
+$all_entities = array();
+while (!empty($entities)) {
+ $entity = array_pop($entities);
+ $childs = elgg_get_entities(array(
+ 'type' => 'group',
+ 'container_guid' => $entity->guid,
+ ));
+ foreach ($childs as $child) {
+ array_push($entities, $child);
+ }
+ $all_entities[] = $entity;
+}
+
+$results = array();
+foreach ($all_entities as $entity) {
+
+ if (!preg_match("/^{$q}/i", $entity->name)) {
+ continue;
+ }
+
+ $output = elgg_view_list_item($entity, array(
+ 'use_hover' => false,
+ 'class' => 'elgg-autocomplete-item',
+ ));
+
+ $icon = elgg_view_entity_icon($entity, 'tiny', array(
+ 'use_hover' => false,
+ ));
+ $results[$entity->name . $entity->guid] = array(
+ 'type' => 'group',
+ 'name' => $entity->name,
+ 'desc' => strip_tags($entity->description),
+ 'guid' => $entity->guid,
+ 'label' => $output,
+ 'value' => $entity->guid,
+ 'icon' => $icon,
+ 'url' => $entity->getURL(),
+ );
+}
+
+ksort($results);
+header("Content-Type: application/json");
+echo json_encode(array_values($results));
+exit;
diff --git a/views/default/subgroups/subgroups_icons.php b/views/default/subgroups/subgroups_icons.php
new file mode 100644
index 000000000..dfd5b29fa
--- /dev/null
+++ b/views/default/subgroups/subgroups_icons.php
@@ -0,0 +1,11 @@
+<?php
+elgg_load_library('elgg:subgroups');
+
+$subgroups = get_subgroups($vars['entity']);
+foreach ($subgroups as $subgroup) {
+ echo elgg_view('icon/default', array(
+ 'entity' => $subgroup,
+ 'size' => 'tiny'
+ ));
+ echo " ";
+}