og_subgroups.module in Subgroups for Organic groups 5.3
Same filename and directory in other branches
Maintains a hierarchy of group/subgroup relationships.
File
og_subgroups.moduleView source
<?php
/**
* @file
* Maintains a hierarchy of group/subgroup relationships.
*/
function og_subgroups_menu($may_cache) {
$items = array();
if (!$may_cache) {
$arg0 = arg(0);
$arg1 = arg(1);
if ($arg0 == 'node' && is_numeric($arg1)) {
$node = node_load($arg1);
if (og_is_group_type($node->type)) {
//Begin tabs displayed on node view.
if (user_access('access og_subgroups node view tabs')) {
$items[] = array(
'path' => 'node/' . $arg1 . '/view/nodes',
'title' => t('Overview'),
'access' => node_access('view', $node),
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => 0,
);
$items[] = array(
'path' => 'node/' . $arg1 . '/view/tree',
'title' => t('Tree'),
'callback' => 'og_subgroups_page',
'callback arguments' => $arg1,
'access' => node_access('view', $node),
'type' => MENU_LOCAL_TASK,
'weight' => 5,
);
if (_og_subgroups_can_view_members($arg1)) {
$items[] = array(
'path' => 'node/' . $arg1 . '/view/members',
'title' => t('Members'),
'callback' => 'og_subgroups_members_page',
'callback arguments' => $arg1,
'access' => node_access('view', $node),
'type' => MENU_LOCAL_TASK,
'weight' => 7,
);
}
}
//End of tabs displayed on node view.
$items[] = array(
'path' => 'node/' . $arg1 . '/edit/group',
'title' => t('Group'),
'access' => node_access('update', $node),
'type' => MENU_DEFAULT_LOCAL_TASK,
);
$items[] = array(
'path' => 'node/' . $arg1 . '/edit/children',
'title' => t('SubGroups'),
'callback' => 'drupal_get_form',
'callback arguments' => array(
'og_subgroups_edit_children_page',
$arg1,
),
'access' => user_access('edit subgroups hierarchy'),
'type' => MENU_LOCAL_TASK,
'weight' => 3,
);
$items[] = array(
'path' => 'node/' . $arg1 . '/edit/members',
'title' => t('Members'),
'callback' => 'drupal_get_form',
'callback arguments' => array(
'og_subgroups_edit_members_page',
$arg1,
),
'access' => user_access('edit subgroups members'),
'type' => MENU_LOCAL_TASK,
'weight' => 5,
);
}
}
}
else {
$items[] = array(
'path' => 'admin/og/subgroups',
'title' => t('OG Subgroups Settings'),
'callback' => 'drupal_get_form',
'callback arguments' => array(
'og_subgroups_settings',
),
'access' => user_access('administer og_subgroups'),
'weight' => 1,
);
}
return $items;
}
/**
* Implementation of hook_perm().
*/
function og_subgroups_perm() {
return array(
'edit subgroups hierarchy',
'edit subgroups members',
'administer og_subgroups',
'access og_subgroups node view tabs',
);
}
function og_subgroups_set_breadcrumb($addchild = false) {
$gnode = og_get_group_context();
$parent = _og_subgroups_get_parent($gnode->nid);
if ($parent) {
$pnode = node_load($parent);
$bc[] = l(t('Home'), NULL);
$bc[] = l(t('Groups'), 'og');
$bc[] = l($pnode->title, "node/{$pnode->nid}");
if ($addchild) {
$bc[] = l($gnode->title, "node/{$gnode->nid}");
}
drupal_set_breadcrumb($bc);
}
}
function og_subgroups_settings() {
$form['og_subgroups_settings']['og_subgroups_parent_children_types'] = array(
'#type' => 'fieldset',
'#title' => t('Parent-Child Group Relationships'),
'#collapsible' => TRUE,
'#collapsed' => FALSE,
);
$form['og_subgroups_settings']['og_subgroups_prop_type'] = array(
'#type' => 'radios',
'#title' => t('Post Propagation Direction'),
'#default_value' => variable_get('og_subgroups_prop_type', 'none'),
'#options' => array(
'parents' => t('Up the tree'),
'children' => t('Down the tree'),
'none' => t('No propagation'),
),
'#multiple' => FALSE,
'#description' => t("When a post is created inside an OG, should it propagate to that group's parents, children, or not at all?"),
);
$og_types = variable_get('og_node_types', array());
foreach ($og_types as $child_type) {
$form['og_subgroups_settings']['og_subgroups_parent_children_types']['og_subgroups_child_' . $child_type] = array(
'#type' => 'fieldset',
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#title' => ucfirst($child_type),
);
$form['og_subgroups_settings']['og_subgroups_parent_children_types']['og_subgroups_child_' . $child_type]['og_subgroups_form_settings_' . $child_type] = array(
'#type' => 'fieldset',
'#collapsible' => TRUE,
'#collapsed' => FALSE,
'#title' => t('Form Settings'),
);
$form['og_subgroups_settings']['og_subgroups_parent_children_types']['og_subgroups_child_' . $child_type]['og_subgroups_form_settings_' . $child_type]['og_subgroups_' . $child_type . '_set_parents'] = array(
'#type' => 'checkbox',
'#title' => t("Provide a 'set parents' form element"),
'#default_value' => variable_get('og_subgroups_' . $child_type . '_set_parents', 1),
);
$form['og_subgroups_settings']['og_subgroups_parent_children_types']['og_subgroups_child_' . $child_type]['og_subgroups_form_settings_' . $child_type]['og_subgroups_' . $child_type . '_set_members'] = array(
'#type' => 'checkbox',
'#title' => t("Provide a 'set members' form element"),
'#default_value' => variable_get('og_subgroups_' . $child_type . '_set_members', 1),
);
$other_og_types = $og_types;
$form['og_subgroups_settings']['og_subgroups_parent_children_types']['og_subgroups_child_' . $child_type]['og_subgroups_' . $child_type . '_parents'] = array(
'#type' => 'select',
'#multiple' => TRUE,
'#options' => $other_og_types,
'#validate' => array(
'og_subgroups_parent_types_validate' => array(),
),
'#title' => t('Parent Types'),
'#default_value' => variable_get('og_subgroups_' . $child_type . '_parents', $og_other_types),
);
}
return system_settings_form($form);
}
function og_subgroups_parent_types_validate($element) {
$value = $element['#value'];
if (array_key_exists('none', $value)) {
unset($value['none']);
if (count($value) > 0) {
form_error($element, t("Please choose either 'none' or one or more node types."));
}
}
}
function og_subgroups_nodeapi($node, $op, $teaser = NULL, $page = NULL) {
switch ($op) {
case 'load':
if ($grps = og_subgroups_get_node_groups($node)) {
// TODO: Refactor so we don't need 2 arrays.
$node->og_groups = array_keys($grps);
$node->og_groups_names = array_values($grps);
}
break;
case 'view':
og_subgroups_set_breadcrumb(!og_is_group_type($node->type));
break;
case 'insert':
if (og_is_group_type($node->type) && is_array($node->members)) {
og_subgroups_save_members($node->nid, $node->members);
}
og_subgroups_save_family($node, variable_get('og_subgroups_prop_type', 'none'));
break;
case 'update':
if (og_is_group_type($node->type) && is_array($node->members)) {
og_subgroups_save_members($node->nid, $node->members);
}
og_subgroups_save_family($node, variable_get('og_subgroups_prop_type', 'none'));
break;
}
}
// returns all the group affiliations for a given subgroup.
function og_subgroups_get_node_groups($node) {
$groups = array();
$parent_types = variable_get('og_subgroups_' . $node->type . '_parents', array());
if (og_is_group_type($node->type && !in_array('none', $parent_types))) {
$result = og_get_node_groups_result($node->nid);
while ($row = db_fetch_object($result)) {
$groups[$row->group_nid] = $row->title;
}
return $groups;
}
}
/**
* Implementation of hook_form_alter().
*/
function og_subgroups_form_alter($form_id, &$form) {
if (strpos($form_id, 'node_form')) {
$node = $form['#node'];
if (og_is_group_type($node->type)) {
if (user_access('edit subgroups hierarchy') && variable_get('og_subgroups_' . $node->type . '_set_parents', 1)) {
$selected = array();
if (isset($node->nid)) {
$selected = og_subgroups_get_parents($node->nid);
}
og_subgroups_form_add_audience($form_id, $form);
}
if (user_access('edit subgroups members') && variable_get('og_subgroups_' . $node->type . '_set_members', 1)) {
$selected = array();
if (isset($node->nid)) {
$selected = og_subgroups_get_users('names', $node->nid, 0);
}
$form['members'] = og_subgroups_members_select($selected);
}
}
}
}
function og_subgroups_get_sql_args($type) {
if (empty($type)) {
$types = variable_get('og_node_types', array(
'og',
));
}
else {
$types = variable_get('og_subgroups_' . $type . '_parents', array());
}
$in = implode(', ', array_fill(0, count($types), "'%s'"));
return array(
$types,
$in,
);
}
function og_subgroups_selective_groups_options($type) {
//Note that these two things are possible:
//1) Type is not set, in which case we return a non-selective list of node types.
//2) Type is set but this type has no parent types available
if (empty($type) && !in_array($type, variable_get('og_node_types', array(
'og',
)))) {
//type is not set or node is not an og_type
return og_all_groups_options();
}
else {
$types = variable_get('og_subgroups_' . $type . '_parents', array());
}
if (!empty($types) && count($types) > 0) {
//Does $types have any contents?
list($types, $in) = og_subgroups_get_sql_args($type);
$sql = "SELECT n.title, n.nid FROM {node} n WHERE n.type IN ({$in}) AND n.status = 1 ORDER BY n.title ASC";
$result = db_query($sql, $types);
while ($row = db_fetch_object($result)) {
$options[$row->nid] = $row->title;
}
return $options ? $options : array();
}
else {
return array();
//If not, return an empty array.
}
}
/**
* A modified version of og_form_add_og_audience that takes into account appropriate parent types of OG homepage nodes.
*/
function og_subgroups_form_add_audience($form_id, &$form) {
global $user;
$node = $form['#node'];
$prop_type = variable_get('og_subgroups_prop_type', 'none');
$filtered_options = og_subgroups_selective_groups_options($node->type);
$og_node_types = variable_get('og_node_types', array(
'og',
));
$parent_node_types = variable_get('og_subgroups_' . $node->type . '_parents', array(
$og_node_types,
));
//Avoided nesting another variable_get here.
// determine the selected groups if fapi doesn't tell us.
if ($_SERVER["REQUEST_METHOD"] == 'GET') {
$gids = $_GET['gids'];
}
elseif ($_POST['og_groups_hidden']) {
$gids = unserialize($_POST['og_groups_hidden']);
}
$required = variable_get('og_audience_required', 0) && !user_access('administer nodes');
// Determine the list of groups that are shown.
// Start by collecting all groups that the user is a member of.
$subs = og_get_subscriptions($user->uid);
$options = array();
foreach ($subs as $key => $val) {
if (isset($parent_node_types[$val['type']])) {
$options[$key] = $val['title'];
}
}
if (user_access('administer nodes')) {
// Node admins see all of groups.
$other = array_diff_assoc($filtered_options, $options);
// Use an optgroup if admin is not a member of all groups.
if ($other) {
$options = array(
t('My subscribed groups') => $options,
t('Other groups') => $other,
);
$is_optgroup = TRUE;
}
else {
$options = $all;
}
}
else {
// Classify those groups which the node already has but the author does not.
if (function_exists('og_node_groups_distinguish')) {
$current_groups = og_node_groups_distinguish($node->og_groups, $node->og_groups_names);
}
// Put inaccessible groups in the $form so that they can persist. See og_submit_group()
$form['og_invisible']['og_groups_inaccessible'] = array(
'#type' => 'value',
'#value' => $current_groups['inaccessible'],
);
// Add the accessible groups that they node already belongs to.
if ($current_groups['accessible']) {
// Use an optgroup to distinguish between my subscriptions and additional groups in the Audience select.
// There is code below which assumes that $options does not have optgroups but that code is within a $simple check
// So we are OK as long as $simple does not apply to node edits.
// NOTE: If you form_alter the audience element, beware that it can sometimes be an optgroup.
foreach ($current_groups['accessible'] as $key => $val) {
$other[$key] = $val['title'];
}
$options = array(
t('My subscribed groups') => $options,
t('Other groups') => $other,
);
$is_optgroup = TRUE;
}
else {
$is_optgroup = FALSE;
}
}
// show read only item if we are non-admin, and in simple mode (i.e. non-checkboxes) and at least one group is in querystring
$simple = !user_access('administer organic groups') && !variable_get('og_audience_checkboxes', TRUE) && count($gids);
// determine value of audience multi-select
if (count($options) == 1 && $required) {
$gids = array_keys($options);
$gid = $gids[0];
$groups = array(
$gid,
);
// also show read only mode if user has 1 option and we are in required mode
$simple = TRUE;
}
elseif ($gids) {
// populate field from the querystring if sent
$groups = $gids;
if (!user_access('administer nodes') && $simple) {
// filter out any groups where author is not a member. we cannot rely on fapi to do this when in simple mode.
$groups = array_intersect($gids, array_keys($options));
}
}
elseif ($node->nid || $node->og_groups) {
$groups = $node->og_groups;
}
else {
$groups = array();
}
// don't bother with visibility if access control is disabled. all is public.
if (variable_get('og_enabled', FALSE)) {
// get the visibility for normal users
$vis = variable_get('og_visibility', 0);
// override visibility for og admins and when author only has 1 group
if (user_access('administer organic groups') && $vis < 2) {
$vis = $vis == OG_VISIBLE_GROUPONLY ? OG_VISIBLE_CHOOSE_PRIVATE : OG_VISIBLE_CHOOSE_PUBLIC;
}
elseif (!count($options)) {
// don't show checkbox if no subscriptions. must be public.
$vis = OG_VISIBLE_BOTH;
}
// If the post is to a private group, visibility must default to one of the private options.
// Try not to show checkbox if admin likes to reduce decisions for node authors.
$selected_groups = isset($form['#post']['og_groups']) ? array_filter($form['#post']['og_groups']) : $groups;
if (count($selected_groups)) {
foreach ($selected_groups as $gid) {
$group_node = new stdClass();
$group_node->nid = $gid;
og_load_group($group_node);
if ($group_node->og_private) {
$vis = variable_get('og_visibility', 0) == OG_VISIBLE_BOTH ? OG_VISIBLE_GROUPONLY : OG_VISIBLE_CHOOSE_PRIVATE;
break;
}
}
}
switch ($vis) {
case OG_VISIBLE_BOTH:
$form['og_nodeapi']['og_public'] = array(
'#type' => 'value',
'#value' => 1,
);
break;
case OG_VISIBLE_GROUPONLY:
$form['og_nodeapi']['og_public'] = array(
'#type' => 'value',
'#value' => 0,
);
break;
//user decides how public the post is.
case OG_VISIBLE_CHOOSE_PUBLIC:
$form['og_nodeapi']['visible']['og_public'] = array(
'#type' => 'checkbox',
'#title' => t('Public'),
'#default_value' => $node->nid ? $node->og_public : 1,
'#description' => t('Show this post to everyone, or only to subscribers of the groups checked above. Posts without any groups are always <em>Public</em>.'),
'#weight' => 2,
);
break;
case OG_VISIBLE_CHOOSE_PRIVATE:
$form['og_nodeapi']['visible']['og_public'] = array(
'#type' => 'checkbox',
'#title' => t('Public'),
'#default_value' => $node->nid ? $node->og_public : 0,
'#description' => t('Show this post to everyone, or only to subscribers of the groups checked above. Posts without any groups are always <em>Public</em>.'),
'#weight' => 2,
);
break;
}
}
// Emit the audience form element.
if ($simple) {
// 'simple' mode. read only.
if (count($groups)) {
foreach ($groups as $gid) {
$titles[] = $options[$gid];
$item_value = implode(', ', $titles);
}
$form['og_nodeapi']['visible']['og_groups_visible'] = array(
'#type' => 'item',
'#title' => t('Audience'),
'#value' => $item_value,
);
$assoc_groups = drupal_map_assoc($groups);
// this hidden element persists audience values during a Preview cycle. avoids errors on Preview.
$form['og_nodeapi']['invisible']['og_groups_hidden'] = array(
'#type' => 'hidden',
'#value' => serialize($assoc_groups),
);
// this 'value' element persists the audience value during submit process
$form['og_nodeapi']['invisible']['og_groups'] = array(
'#type' => 'value',
'#value' => $assoc_groups,
);
}
}
elseif ($cnt = count($options, COUNT_RECURSIVE)) {
drupal_add_js(drupal_get_path('module', 'og') . '/og.js');
// show multi-select. if less than 20 choices, use checkboxes.
$type = $cnt >= 20 || $is_optgroup ? 'select' : 'checkboxes';
$form['og_nodeapi']['visible']['og_groups'] = array(
'#type' => $type,
'#title' => t('Audience'),
'#attributes' => array(
'class' => 'og-audience',
),
'#options' => $options,
'#required' => $required,
'#description' => format_plural(count($options), 'Show this post in this group.', 'Show this post in these groups.'),
'#default_value' => $groups,
'#required' => $required,
'#multiple' => TRUE,
);
}
else {
if ($required) {
form_set_error('title', t('You must !join before posting a %type.', array(
'!join' => l(t('join a group'), 'og'),
'%type' => node_get_types('name', $node->type),
)));
}
}
if (count($form['og_nodeapi']['visible']) > 1) {
$form['og_nodeapi']['#type'] = 'fieldset';
$form['og_nodeapi']['#title'] = t('Groups');
$form['og_nodeapi']['#collapsible'] = TRUE;
$form['og_nodeapi']['#collapsed'] = $gids ? TRUE : FALSE;
}
}
/**
* Lists users of a site so members can be specified
*/
//function og_subgroups_members_select($selected = array()) {
function og_subgroups_members_select($selected = array()) {
$options = og_subgroups_get_users('names');
$selected = array_keys($selected);
unset($options[0]);
$type = count($options) >= 20 ? 'select' : 'checkboxes';
return array(
'#type' => $type,
'#title' => t('Members'),
'#default_value' => $selected,
'#options' => $options,
'#description' => t('Anyone who is an immediate member of the group. Members of subgroups need not be checked.'),
'#multiple' => 1,
'#size' => $multiple ? min(9, count($options)) : 0,
'#weight' => 0,
);
}
function og_subgroups_parents_select($title, $name, $selected, $gid, $type, $exclude = array()) {
$child_types = variable_get('og_subgroups_' . $type . '_parents', array());
if (count($child_types) == 0) {
return "";
}
$options = array();
$query = "SELECT og.nid, n.title FROM {og} og INNER JOIN {node} n where og.nid=n.nid AND og.nid <> %d";
$add = " and (";
foreach ($child_types as $type) {
$query .= $add . "n.type = '" . $type . "'";
$add = " or ";
}
$query .= ")";
$result = db_query($query, $gid);
while ($row = db_fetch_object($result)) {
if (!in_array($row->nid, $exclude)) {
$options[$row->nid] = $row->title;
}
}
$selected = array_keys($selected);
if (count($options)) {
$type = count($options) >= 20 ? 'select' : 'checkboxes';
return array(
'#type' => $type,
'#title' => $title,
'#default_value' => $selected,
'#options' => $options,
'#description' => '',
'#multiple' => 1,
'#size' => min(9, count($options)),
'#weight' => -1,
);
}
else {
return "";
}
}
/**
* Returns the parent for a given groupnode id
*/
function _og_subgroups_get_parent($gid) {
$sql = "SELECT oga.group_nid FROM {og_ancestry} oga where oga.nid = %d";
return db_result(db_query($sql, $gid));
}
function _og_subgroups_can_view_members($gid) {
global $user;
if ($user->uid == 1) {
return true;
}
return in_array($gid, array_keys($user->og_groups));
}
/**
* Output a viewable page of group members
*/
function og_subgroups_members_page($gid) {
global $user;
// get the user object
// Need to make sure a user can only see members if he is a member of the group
if (!_og_subgroups_can_view_members($gid)) {
drupal_access_denied();
return;
}
$node = node_load($gid);
drupal_set_title(check_plain($node->title));
og_subgroups_set_breadcrumb(true);
// Grab users and theme display
$users = og_subgroups_get_users('links', $gid, 1);
if (!count($users)) {
$users = array(
"(no members)",
);
}
$output = theme('og_subgroups_members_list', array_unique($users));
return $output;
}
function theme_og_subgroups_members_list($members = array()) {
$output = implode($members, ', ');
return $output;
}
/**
* Retrieve an array of all users that are members of the group
* If the recursive flag is true, then users of children are returned as well
*/
function og_subgroups_get_users($return_type = 'users', $gid = 0, $recursive = 0) {
if ($gid > 0) {
$result = db_query(og_list_users_sql(), $gid);
}
else {
$result = db_query("SELECT u.uid, u.name, u.mail, u.picture FROM {users} u");
}
$users = array();
while ($user = db_fetch_object($result)) {
if ($return_type == 'links') {
$users[$user->uid] = theme('username', $user);
}
if ($return_type == 'users') {
$users[$user->uid] = $user;
}
if ($return_type == 'names') {
$users[$user->uid] = $user->name;
}
}
if ($recursive) {
$children = og_subgroups_get_children($gid);
foreach ($children as $cid => $cname) {
// We'll have to merge ourselves due to desire to have unique keys
// Original code just used array_merge but this leaves us with reindexed numeric keys
// which will not work. The uid keys MUST be preserved uniquely.
$susers = og_subgroups_get_users($return_type, $cid, 1);
foreach ($susers as $sid => $cname) {
if (empty($users[$sid])) {
$users[$sid] = $cname;
}
}
}
}
return $users;
}
/**
* Return an array of children groups of the group
*/
function og_subgroups_get_children($gid) {
$result = db_query('SELECT oga.nid, n.title, n.type FROM {og_ancestry} oga INNER JOIN {node} n WHERE oga.group_nid=%d AND oga.nid=n.nid', $gid);
$children = array();
while ($row = db_fetch_object($result)) {
if (og_is_group_type($row->type)) {
$children[$row->nid] = $row->title;
}
}
return $children;
}
function og_subgroups_page($gid) {
$node = node_load($gid);
drupal_set_title(check_plain($node->title));
og_subgroups_set_breadcrumb(true);
return og_subgroups_tree(array(
$node->nid => $node->title,
));
}
function og_subgroups_tree($children, $depth = 0) {
global $user;
if ($depth == 0) {
drupal_add_js(drupal_get_path('module', 'og_subgroups') . '/og_subgroups.js');
$togo = "<ul class=collapsible>";
}
else {
$togo = "<ul>";
}
foreach ($children as $cid => $cname) {
$show_members = _og_subgroups_can_view_members($cid);
if ($depth == 0) {
$link = '<span><a href="#">' . $cname . '</a></span>';
if ($show_members) {
$link .= ' ' . l('[' . t('list all members') . ']', 'node/' . $cid . '/view/members');
}
$togo .= '<li>' . $link;
$togo .= og_subgroups_tree(og_subgroups_get_children($cid), $depth + 1);
if ($show_members) {
$togo .= og_subgroups_make_list(og_subgroups_get_users('links', $cid, 0));
}
$togo .= '</li>';
}
else {
$link = '<span><a href="#">' . $cname . '</a></span>';
$link .= ' ' . l('[' . t('view this group') . ']', 'node/' . $cid);
$togo .= '<li>' . $link;
$togo .= og_subgroups_tree(og_subgroups_get_children($cid), $depth + 1);
if ($show_members) {
$togo .= og_subgroups_make_list(og_subgroups_get_users('links', $cid, 0), $depth);
}
$togo .= '</li>';
}
}
$togo .= "</ul>";
return $togo;
}
function og_subgroups_make_list($array, $depth = 0) {
if ($depth == 0) {
$togo = "<ul>";
}
else {
$togo = "<ul style='display:none'>";
}
foreach ($array as $i) {
$togo .= "<li class=leaf>{$i}</li>";
}
$togo .= "</ul>";
return $togo;
}
function og_subgroups_save_family($this_node, $family_type) {
$tree = og_subgroups_get_family($this_node, $family_type);
if ($tree) {
$sql = "DELETE FROM {og_ancestry} WHERE nid = %d";
db_query($sql, $this_node->nid);
foreach ($tree as $this_tree) {
$this_tree_node = node_load($this_tree['nid']);
if (!og_is_omitted_type($this_tree_node->type)) {
$sql = "INSERT INTO {og_ancestry} (nid, group_nid, is_public) VALUES (%d, %d, %d)";
$gid = $this_tree['nid'];
db_query($sql, $this_node->nid, $gid, $this_node->og_public);
}
if (!empty($this_tree[$family_type])) {
foreach ($this_tree[$family_type] as $this_key => $this_value) {
$my_member = node_load($this_key);
if (!og_is_omitted_type($my_member->type)) {
$gid = $this_key;
$sql = "INSERT INTO {og_ancestry} (nid, group_nid, is_public) VALUES (%d, %d, %d)";
db_query($sql, $this_node->nid, $gid, $this_node->og_public);
}
}
}
}
}
}
function og_subgroups_get_family($node, $relationship_type) {
$func = og_subgroups_get_ . $relationship_type;
$tree = array();
if (is_array($node->parents)) {
$parents = $node->parents;
}
else {
$parents = $node->og_groups;
}
if ($parents) {
foreach ($parents as $key => $value) {
//Build the first level of the tree
$tree[$value]['nid'] = $value;
unset($tree[$value]['title']);
$tree[$value]['title'] = $node->og_groups_names[$key];
//when the node is not already in node og_groups this results in a blank title
//build parents or children (or nothing)
if ($relationship_type != 'none') {
$tree[$value][$relationship_type] = $func($value);
//og_subgroups_get_parents or og_subgroups_get_children
}
if (!empty($tree[$value][$relationship_type])) {
foreach ($tree[$value][$relationship_type] as $this_member) {
//unset the parents from the first level of the tree
if ($this_member['nid'] != $tree[$value]['nid']) {
//Don't unset the parent from the first level -- BUT DO UNSET IT FROM ITS OWN PARENT
unset($tree[$this_member['nid']]);
}
}
}
}
}
return $tree;
}
function og_subgroups_edit_children_page($gid) {
$node = node_load($gid);
drupal_set_title(check_plain($node->title));
$header = array(
'',
array(
'data' => t('Group name'),
'field' => 'name',
),
);
$result = db_query('SELECT og.nid, n.title FROM {og} og INNER JOIN {node} n where og.nid=n.nid AND og.nid <> %d', $gid);
$options = array();
while ($row = db_fetch_object($result)) {
$options[$row->nid] = $row->title;
}
$selected = array();
$selected = og_subgroups_get_children($gid);
$form['subgroups'] = array(
'#type' => 'checkboxes',
'#default_value' => array_keys($selected),
'#options' => $options,
'#description' => t('Check all subgroups.'),
);
$form['op'] = array(
'#type' => 'submit',
'#value' => t('Submit'),
);
$form['gid'] = array(
'#type' => 'hidden',
'#value' => $gid,
);
return $form;
}
function theme_og_subgroups_edit_children_page($form) {
foreach ($form['subgroups'] as $gid => $val) {
if (is_numeric($gid)) {
$title = $form['subgroups'][$gid]['#title'];
$form['subgroups'][$gid]['#title'] = "";
$rows[] = array(
drupal_render($form['subgroups'][$gid]),
l($title, 'node/' . $gid),
);
}
}
$header = array(
'',
array(
'data' => t('Group name'),
'field' => 'name',
),
);
$output2 = drupal_render($form['subgroups']);
$output = theme('table', $header, $rows);
$output .= '<br>' . drupal_render($form) . '</br>';
return $output2 . $output;
}
function og_subgroups_edit_children_page_submit($form_id, $values) {
og_subgroups_save_children($values['gid'], $values['subgroups']);
return 'node/' . $values['gid'];
}
function og_subgroups_save_children($gid, $subgroups) {
// First delete group children from hierarchy
$children = og_subgroups_get_children($gid);
foreach ($children as $cid => $cname) {
db_query('DELETE FROM {og_ancestry} WHERE nid=%d and group_nid=%d', $cid, $gid);
}
// Now add back each new child
if (is_array($subgroups)) {
foreach ($subgroups as $subgroup) {
if ($subgroup != 0) {
db_query('INSERT INTO {og_ancestry} (nid,group_nid,is_public) VALUES (%d,%d,0)', $subgroup, $gid);
}
}
}
}
function og_subgroups_edit_members_page($gid) {
$node = node_load($gid);
drupal_set_title(check_plain($node->title));
$header = array(
'',
array(
'data' => t('Username'),
'field' => 'name',
),
);
$result = db_query("SELECT u.uid, u.name, u.mail, u.picture FROM {users} u WHERE uid>0" . tablesort_sql($header));
while ($user = db_fetch_object($result)) {
$options[$user->uid] = $user;
}
$selected = og_subgroups_get_users('names', $node->nid);
$form['members'] = array(
'#type' => 'checkboxes',
'#title' => NULL,
'#default_value' => array_keys($selected),
'#options' => $options,
'#description' => t('Check anyone who is an immediate member of the group. Members of subgroups need not be checked.'),
);
$form['op'] = array(
'#type' => 'submit',
'#value' => t('Submit'),
);
$form['gid'] = array(
'#type' => 'hidden',
'#value' => $gid,
);
return $form;
}
function theme_og_subgroups_edit_members_page($form) {
$header = array(
'',
array(
'data' => t('Username'),
'field' => 'name',
),
);
foreach ($form['members'] as $key => $val) {
if (is_numeric($key)) {
$username = theme('username', $val['#title']);
$form['members'][$key]['#title'] = "";
$rows[] = array(
drupal_render($form['members'][$key]),
$username,
$email,
);
}
}
$output = theme('table', $header, $rows);
$output2 = drupal_render($form['members']);
$output .= '<br>' . drupal_render($form) . '</br>';
return $output2 . $output;
}
function og_subgroups_edit_members_page_submit($form_id, $values) {
og_subgroups_save_members($values['gid'], $values['members']);
return 'node/' . $values['gid'];
}
function og_subgroups_save_members($gid, $members) {
$new_group = array();
if (is_array($members)) {
foreach ($members as $uid => $active) {
if ($active > 0) {
og_save_subscription($gid, $uid, array(
'is_active' => 1,
));
$new_group[] = $uid;
}
}
}
$whole_group = og_subgroups_get_users('users', $gid);
foreach ($whole_group as $uid => $val) {
if (!in_array($uid, $new_group)) {
og_delete_subscription($gid, $uid);
}
}
}
function og_subgroups_get_effective_groups($nodes = array(), $skip = array()) {
$togo = array();
if (!is_array($nodes)) {
return array();
}
foreach ($nodes as $node) {
if (!in_array(array_keys($nodes), array_keys($skip))) {
$togo[$node['nid']] = $node;
$togo2 = og_subgroups_get_effective_groups(og_subgroups_get_parents($node['nid']), $togo);
if (is_array($togo2)) {
foreach ($togo2 as $key => $val) {
$togo[$key] = $val;
}
}
}
}
return $togo;
}
function og_subgroups_get_parents($gid) {
$result = db_query('SELECT n.title, n.type, n.status, oga.group_nid as nid, 1 as is_active FROM {og_ancestry} oga INNER JOIN {node} n WHERE oga.nid=%d AND oga.group_nid=n.nid', $gid);
$parents = array();
while ($row = db_fetch_array($result)) {
if (og_is_group_type($row['type'])) {
$parents[$row['nid']] = $row;
}
}
return $parents;
}