l(t('theme configuration page'), 'admin/theme')));
}
}
function og_menu($may_cache) {
global $user;
if ($may_cache) {
// anon users should be able to get to the subscribe page
$items[] = array('path' => 'og/subscribe', 'type' => MENU_CALLBACK, 'callback' => 'og_subscribe', 'access' => TRUE, 'title' => t('subscribe to group'));
$items[] = array('path' => 'og/image', 'callback' => 'og_image', 'title' => t('group image (large)'), 'weight' => 4, 'access' => user_access('access content'), 'type' => MENU_CALLBACK);
$items[] = array('path' => 'node/add/og', 'title' => t('group'), 'access' => user_access('create groups'));
$items[] = array('path' => 'og', 'callback' => 'og_list_groups_page', 'title' => t('groups'), 'weight' => 3, 'access' => user_access('access content'));
$access = $user->uid; // login is required
$items[] = array('path' => 'og/unsubscribe', 'type' => MENU_CALLBACK, 'callback' => 'og_unsubscribe', 'access' => $access, 'title' => t('unsubscribe from group'));
$items[] = array('path' => 'og/approve', 'type' => MENU_CALLBACK, 'callback' => 'og_approve', 'access' => $access, 'title' => t('approve subscription request'));
$items[] = array('path' => 'og/deny', 'type' => MENU_CALLBACK, 'callback' => 'og_deny', 'access' => $access, 'title' => t('deny subscription request'));
$items[] = array('path' => 'og/create_admin', 'type' => MENU_CALLBACK, 'callback' => 'og_create_admin', 'access' => $access, 'title' => t('create group administrator'));
$items[] = array('path' => 'og/delete_admin', 'type' => MENU_CALLBACK, 'callback' => 'og_delete_admin', 'access' => $access, 'title' => t('delete group administrator'));
$items[] = array('path' => 'og/remove_node', 'type' => MENU_CALLBACK, 'callback' => 'og_remove_node', 'access' => $access, 'title' => t('remove post from group'));
$items[] = array('path' => 'og/feed', 'callback' => 'og_feed', 'title' => t('group feed'), 'type' => MENU_CALLBACK, 'access' => user_access('access content'));
$items[] = array('path' => 'og/albums', 'callback' => 'og_albums_page', 'title' => t('albums'), 'type' => MENU_CALLBACK, 'access' => user_access('access content'));
$items[] = array('path' => 'og/albums/form', 'callback' => 'og_albums_form', 'title' => t('album'), 'type' => MENU_CALLBACK, 'access' => user_access('create images'));
$items[] = array('path' => 'og/albums/validate', 'callback' => 'og_albums_validate', 'title' => t('album'), 'type' => MENU_CALLBACK, 'access' => user_access('create images'));
}
else {
// we have to perform a load in order to assure that the $user->og_groups bits are present.
$user = user_load(array('uid' => $user->uid));
foreach ($user->og_groups as $key => $sub) {
$items[] = array('path' => "og/view/$key", 'callback' => 'og_nodeview', 'title' => $sub['title'], 'callback arguments' => array($key), 'access' => TRUE, 'type' => MENU_CALLBACK);
$items[] = array('path' => "og/users/$key", 'callback' => 'og_list_users_page', 'title' => t('subscriber management'), 'callback arguments' => array($key), 'type' => MENU_CALLBACK, 'access' => TRUE);
$items[] = array('path' => "og/users/$key/list", 'callback' => 'og_list_users_page', 'title' => t('list'), 'callback arguments' => array($key), 'type' => MENU_DEFAULT_LOCAL_TASK, 'access' => TRUE);
$items[] = array('path' => "og/users/$key/add", 'callback' => 'og_add_users_page', 'title' => t('add subscribers'), 'callback arguments' => array($key), 'type' => MENU_LOCAL_TASK, 'access' => TRUE, 'weight' => 5);
$items[] = array('path' => "og/manage/$key", 'callback' => 'og_manage', 'title' => t('manage subscription'), 'callback arguments' => array($key), 'type' => MENU_CALLBACK, 'access' => user_access('access content'));
$items[] = array('path' => "og/invite/$key", 'callback' => 'og_invite', 'title' => t('send invitation'), 'callback arguments' => array($key), 'type' => MENU_CALLBACK, 'access' => user_access('access content'));
}
if (arg(0) == 'node' && is_numeric(arg(1))) {
$node = node_load(array('nid' => arg(1)));
if ($node->type == 'og') {
$items[] = array('path' => 'node/'. arg(1). '/email', 'title' => t('email'), 'callback' => 'og_email', 'callback arguments' => array(arg(1)), 'access' => node_access('update', $node), 'type' => MENU_LOCAL_TASK, 'weight' => 7);
}
}
og_theme();
}
return $items;
}
function og_perm() {
return array('create groups', 'administer organic groups');
}
/**
* override theme based on what group is being displayed (if any).
* be smart about selecting the 'active' group for ambigous urls like node/$nid
*
*
* @param
* none
* @return
* none
*/
function og_theme() {
global $custom_theme;
$group_node = NULL; // a node object containing the 'active' group for this request
$pages = array('users', 'albums', 'feed', 'invite', 'remove_node', 'manage', 'all');
if (arg(0) == 'og' && arg(1) == 'albums' && arg(2) == 'form' && $gid = $_REQUEST['edit']['og_groups'][0]) {
$group_node = node_load(array('nid' => $gid));
$custom_theme = $group_node->og_theme;
}
elseif (arg(0) == 'og' && in_array(arg(1), $pages)) {
$group_node = og_set_theme(arg(2));
}
elseif (arg(0) == 'node' && is_numeric(arg(1))) {
$group_node = og_set_theme(arg(1));
}
elseif (arg(0) == 'node' && arg(1) == 'add' && $gid = $_REQUEST['edit']['og_groups'][0]) {
$group_node = node_load(array('nid' => $gid));
$custom_theme = $group_node->og_theme;
}
elseif (arg(0) == 'comment' && is_numeric(arg(2))) {
$og_node = og_set_theme(arg(2));
}
$_SESSION['og_last'] = $group_node;
}
function og_set_theme($nid) {
global $custom_theme;
$node = node_load(array('nid' => $nid));
if ($node->type == 'og') {
$custom_theme = $node->og_theme;
return $node;
}
else {
switch (count($node->og_groups)) {
case 0:
return NULL;
case 1:
$group_node = node_load(array('nid' => $node->og_groups[0]));
$custom_theme = $group_node->og_theme;
default:
// node is in multiple groups. preference goes to the group we showed on the prior page view (if any)
if (in_array($_SESSION['og_last']->nid, $node->og_groups)) {
$group_node = node_load(array('nid' => $_SESSION['og_last']->nid));
$custom_theme = $group_node->og_theme;
}
else {
$group_node = node_load(array('nid' => $node->og_groups[0]));
$custom_theme = $group_node->og_theme;
}
}
// we know everything we need to know here to determine the node breadcrumb
// instead of reproducing this logic elsewhere, save in a GLOBAL and set_breadcrumb() in og_nodeapi('view')
$GLOBALS['og_node_bc'][] = l(t('home'), '');
$GLOBALS['og_node_bc'][] = l(t('groups'), 'og');
$GLOBALS['og_node_bc'][] = l($group_node->title, "node/$group_node->nid");
return $group_node;
}
}
function og_nodeview($gid) {
drupal_goto("node/$gid");
}
/**
* Admins may broadcast email to all their subscribers
*
* @param $gid
* the nid of a group.
*/
function og_email($gid) {
$node = node_load(array('nid' => $gid));
drupal_set_title(t('Send email to %group', array('%group' => $node->title)));
if ($edit = $_POST['edit']) {
if (!$edit['body']) {
form_set_error('body', t("Your email body may not be blank"));
$err = TRUE;
}
if (!$edit['subject']) {
form_set_error('subject', t('Your email subject may not be blank'));
$err = TRUE;
}
if (!$err) {
$msg = $edit['body']. t("\n\n--------------------------------\nThis message was sent by an administrator in the '%group' group at %site. To visit this group, browse to %url1. To unsubscribe from this group, visit %url2", array('%group' => $node->title, '%site' => variable_get('site_name', drupal), '%url1' => url("node/$node->nid", NULL, NULL, TRUE), '%url2' => url("og/unsubscribe/$node->nid", NULL, NULL, TRUE)));
global $user;
$from = $user->mail;
$headers = "From: $from\nReply-to: $from\nX-Mailer: Drupal\nReturn-path: $from";
$sql = og_list_users_sql(1);
$result = db_query($sql, $gid);
while ($row = db_fetch_object($result)) {
$emails[] = $row->mail;
}
foreach ($emails as $mail) {
user_mail(trim($mail), $edit['subject'], $msg, $headers);
}
drupal_set_message(t('%count emails sent.', array('%count' => count($emails))));
drupal_goto("node/$gid");
}
else {
print theme('page', og_email_form($gid));
}
}
else {
print theme('page', og_email_form($gid));
}
}
function og_email_form($gid) {
$edit = $_POST['edit'];
$result = db_query(og_list_users_sql(1), $gid);
$txt = format_plural(db_num_rows($result), '1 subscriber', 'all %count subscribers');
drupal_set_message(t('Your email will be sent to %count in this group. Please use this feature sparingly.', array('%count' => l($txt, "og/users/$gid"))));
$form .= form_textfield(t('Subject'), 'subject', $edit['subject'], 70, 250, t("Enter a subject for your email."), NULL, TRUE);
$form .= form_textarea(t('Body'), 'body', $edit['body'], 90, 5, t('Enter a body for your email.'), NULL, TRUE);
$form .= form_button(t('Send email'));
return form($form);
}
function og_manage($gid) {
global $user;
if ($edit = $_POST['edit']) {
$sql = "DELETE FROM {og_uid} WHERE nid=%d AND uid=%d";
db_query($sql, $gid, $user->uid);
$sql = "INSERT INTO {og_uid} (mail_type, nid, uid) VALUES (%d, %d, %d)";
db_query($sql, $edit['mail_type'], $gid, $user->uid);
drupal_set_message(t('Subscription saved.'));
}
$group = node_load(array('nid' => $gid));
// group owner can't unsubscribe
if ($group->uid != $user->uid) {
$output .= form_item(t('Goodbye'), l(t('Unsubscribe from this group'), "og/unsubscribe/$gid"), NULL, 'destination=og');
}
$output .= form_radios('Email notification', "mail_type", $edit["mail_type"] ? $edit["mail_type"] : $user->og_groups[$gid]['mail_type'], array(t('disabled'), t('enabled')), t('Do you want to receive an email each time a message is posted to this group?'));
$output .= form_button(t('Submit'));
$output = form($output);
$bc = array(l(t('home'), ''), l(t('groups'), 'og'), l($group->title, "node/$gid"));
drupal_set_breadcrumb($bc);
print theme('page', $output);
}
function og_approve($gid, $uid) {
if (node_access('update', array('nid' => $gid, 'status' => 1))) {
$sql = "REPLACE INTO {node_access} (nid, gid, realm, grant_view) VALUES (%d, %d, 'og_uid', 1)";
db_query($sql, $gid, $uid);
drupal_set_message(t('Subscription request approved.'));
$node = node_load(array('nid' => $gid));
$subj = t("Subscription request approved for '%title'", array('%title' => $node->title));
$body = t('You may now post messages in this group located at %url', array('%url' => url("node/$node->nid", NULL, NULL, TRUE)));
$from = variable_get('site_mail', ini_get('sendmail_from'));
$headers = "From: $from\nReply-to: $from\nX-Mailer: Drupal\nReturn-path: $from\nErrors-to: $from";
$account = user_load(array('uid' => $uid));
user_mail($account->mail, $subj, $body, $headers);
drupal_goto("node/$gid");
}
else {
drupal_access_denied();
}
}
function og_deny($gid, $uid) {
if (node_access('update', array('nid' => $gid, 'status' => 1))) {
$sql = "DELETE FROM {node_access} WHERE nid=%d AND gid=%d AND realm='og_uid'";
db_query($sql, $gid, $uid);
drupal_set_message(t('Subscription request denied.'));
$subj = t('Subscription request denied for %title', array('title' => $node->title));
$body = t('Sorry, your subscription request was denied.');
$from = variable_get('site_mail', ini_get('sendmail_from'));
$headers = "From: $from\nReply-to: $from\nX-Mailer: Drupal\nReturn-path: $from\nErrors-to: $from";
$account = user_load(array('uid' => $uid));
user_mail($account->mail, $subj, $body, $headers);
drupal_goto("node/$gid");
}
else {
drupal_access_denied();
}
}
function og_create_admin($gid, $uid) {
if (node_access('update', array('nid' => $gid, 'status' => 1))) {
$sql = "REPLACE INTO {node_access} (nid, gid, realm, grant_view, grant_update) VALUES (%d, %d, 'og_uid', 1, 1)";
db_query($sql, $gid, $uid);
drupal_set_message(t('User was promoted to group administrator'));
drupal_goto("node/$gid");
}
else {
drupal_access_denied();
}
}
function og_delete_admin($gid, $uid) {
if (node_access('update', array('nid' => $gid, 'status' => 1))) {
$sql = "REPLACE INTO {node_access} (nid, gid, realm, grant_view, grant_update) VALUES (%d, %d, 'og_uid', 1, 0)";
db_query($sql, $gid, $uid);
drupal_set_message(t('User is no longer a group administrator'));
drupal_goto("node/$gid");
}
else {
drupal_access_denied();
}
}
function og_remove_node($gid, $nid) {
if (node_access('update', array('nid' => $gid, 'status' => 1))) {
$node = node_load(array('nid' => $nid));
if ($_POST['op']['og_confirm']) {
og_delete_folksonomy($node);
$sql = "DELETE FROM {node_access} WHERE nid=%d AND gid=%d AND realm='og_group'";
db_query($sql, $nid, $gid);
drupal_set_message(t('Post removed from group.'));
drupal_goto("node/$gid");
}
else {
$output = form_item(t('Confirmation'), t('Remove %title from this group.', array('%title' => ''. $node->title. '')));
$output .= form_hidden('og_confirm', 1);
$output .= form_button(t('Remove'));
print theme('page', form($output));
}
}
else {
drupal_access_denied();
}
}
function og_delete_folksonomy($node) {
if ($node->og_groups) {
foreach ($node->og_groups as $gid) {
$realm = "og_group_$gid";
module_invoke('folksonomy', 'delete', array('realm' => $realm, 'id' => $node->nid));
}
}
}
function og_invite($gid) {
$node = node_load(array('nid' => $gid));
if ($node->og_selective < OG_INVITE_ONLY || node_access('update', $node)) {
$max = variable_get('og_email_max', 10);
if ($edit = $_POST['edit']) {
$emails = explode(',', $edit['mails']);
if (count($emails) > $max) {
form_set_error('mails', t("You may not specify more than %max email addresses.", array('%max' => $max)));
$err = TRUE;
}
else {
foreach ($emails as $email) {
if (!valid_email_address(trim($email))) {
$bad[] = $email;
}
}
if ($bad) {
form_set_error('mails', t('invalid email address: '). implode(' ', $bad));
$err = TRUE;
}
}
if (!$err) {
$node = node_load(array('nid' => $gid));
$subj = t('Invitation to join the group "%group" at %site', array('%group' => $node->title, '%site' => variable_get('site_name', 'drupal')));
$body = t("Hi. I'm a member of '%group' and I welcome you to join this group as well. Please see the link and message below.\n\n", array('%group' => $node->title));
$body .= $node->title. "\n";
$body .= $node->og_description. "\n";
$body .= t('Subscribe: %url', array('%url' => url("og/subscribe/$gid", NULL, NULL, TRUE)));
$body .= $edit['pmessage'] ? "\n\n ----------------------------\n". $edit['pmessage']. "\n--------------------------------" : '';
global $user;
$from = $user->mail;
global $user;
$headers = "From: $from\nReply-to: $from\nX-Mailer: Drupal\nReturn-path: $from";
foreach ($emails as $mail) {
user_mail(trim($mail), $subj, $body, $headers);
}
drupal_set_message(t('%count invitations sent.', array('%count' => count($emails))));
print theme('page', og_invite_form($gid));
}
else {
print theme('page', og_invite_form($gid));
}
}
else {
print theme('page', og_invite_form($gid));
}
}
else {
drupal_access_denied();
}
}
function og_invite_form($gid) {
$edit = $_POST['edit'];
$max = variable_get('og_email_max', 10);
$form .= form_textfield(t('Email addresses'), 'mails', $edit['mails'], 90, 250, t("Enter up to %max email addresses. Separate multiple addresses by commas. Each will receive an invitation message from you.", array('%max' => $max)), NULL, TRUE);
$form .= form_textarea(t('Personal message'), 'pmessage', $edit['pmessage'], 90, 5, t('Optional. Enter a message which will become part of the invitation email'));
$form .= form_button(t('Send invitation'));
return form($form);
}
function og_subscribe($gid, $uid = NULL) {
global $user;
if (is_null($uid)) {
if ($user->uid) {
$account = $user;
}
else {
drupal_set_message(t('In order to subscribe to this group, you must login or register a new account. After you have successfully done so, you will need to follow the subscribe link again.'));
drupal_goto('user');
}
}
else {
$account = user_load(array('uid' => $uid));
}
if ($account->uid != $user->uid && !node_access('update', array('nid' => $gid, 'status' => 1))) {
// only admins can subscribe another person
drupal_access_denied();
}
$return = og_subscribe_user($gid, $account);
if ($return == 'approved') {
drupal_set_message(t('Subscription request awaits approval by an administrator.'));
}
else if ($return == 'subscribed') {
drupal_set_message(t('User subscribed to group,'));
}
drupal_goto("node/$gid");
}
/**
* subscribe given user to given group. no access control since this is an API function
*
* @return string 'approval' or 'subscribed' depending on the group's configuration.
**/
function og_subscribe_user($gid, $account) {
$names = array('nid', 'realm', 'gid', 'grant_view', 'grant_update');
$values = array($gid, "'og_uid'", $account->uid);
// moderated groups must approve all members (selective=1)
// if you can't view/edit/delete, you are *requesting* membership in the group
// if you can view, you are a member
// if you can edit, you are an admin
$node = node_load(array('nid' => $gid));
if ($node->og_selective) {
$values[] = 0;
$values[] = 0;
$sql = og_list_users_sql(1, 1);
$res = db_query($sql, $node->nid);
while ($row = db_fetch_object($res)) {
$admins[] = $row->mail ? $row->mail : NULL;
}
$subj = t("Subscription request for '%group' from '%name'", array('%group' => $node->title, '%name' => $account->name));
$body = t('You may approve or deny this request at %url', array('%url' => url("og/approve/$node->nid/$account->uid", NULL, NULL, TRUE)));
$from = variable_get('site_mail', ini_get('sendmail_from'));
$headers = "From: $from\nX-Mailer: Drupal\nReturn-path: $from\nErrors-to: $from";
user_mail(implode(', ', $admins), $subj, $body, $headers);
$return_value = 'approval';
}
else {
$values[] = 1;
$values[] = 0;
$return_value = 'subscribed';
}
$sql = 'REPLACE INTO {node_access} ('. implode(',', $names). ') VALUES ('. implode(',', $values). ')';
db_query($sql);
return $return_value;
}
function og_unsubscribe($gid, $uid = NULL) {
global $user;
if (is_null($uid)) {
$uid = $user->uid;
}
if ($uid != $user->uid && !node_access('update', array('nid' => $gid, 'status' => 1))) {
// only admins can unsubscribe another person
drupal_access_denied();
}
$sql = "DELETE FROM {node_access} WHERE gid = %d AND nid = %d AND realm = 'og_uid'";
db_query($sql, $uid, $gid);
$sql = "DELETE FROM {og_uid} WHERE nid=%d AND uid=%d";
db_query($sql, $gid, $uid);
drupal_set_message(t('User unsubscribed from group.'));
drupal_goto("node/$gid");
}
// since a user's subscriptions are loaded into $user object, this function is only occassionally useful to get group subs for users other than the current user
// even then, it often makes sense to call user_load() instead of this function.
// load all subscriptions for a given user
function og_get_subscriptions($uid) {
static $subscriptions = array();
if (!isset($subscriptions[$uid])) {
$sql = "SELECT na.*, n.title, ou.mail_type FROM {node_access} na INNER JOIN {node} n ON na.nid = n.nid LEFT JOIN {og_uid} ou ON n.nid=ou.nid WHERE gid = %d AND realm = 'og_uid' AND grant_view = 1";
$result = db_query($sql, $uid);
while ($row = db_fetch_object($result)) {
$subscriptions[$uid][$row->nid]['title'] = $row->title;
$subscriptions[$uid][$row->nid]['mail_type'] = $row->mail_type;
$subscriptions[$uid][$row->nid]['grant_view'] = $row->grant_view;
$subscriptions[$uid][$row->nid]['grant_update'] = $row->grant_update;
$subscriptions[$uid][$row->nid]['grant_delete'] = $row->grant_delete;
}
if (!$subscriptions[$uid]) {
$subscriptions[$uid] = array();
}
}
return $subscriptions[$uid];
}
/**
* Implementation of hook_access().
*/
function og_access($op, $node) {
global $user;
if ($op == 'create') {
return user_access('create groups') && $user->uid;
}
}
function og_list_users_sql($min_grant_view = 1, $min_grant_update = 0) {
return "SELECT u.uid, u.name, u.mail, u.picture, na.* FROM {node_access} na INNER JOIN {users} u ON na.gid = u.uid AND na.nid = %d WHERE u.status > 0 AND realm = 'og_uid' AND grant_view >= $min_grant_view AND grant_update >= $min_grant_update ORDER BY u.name ASC";
}
function og_add_users_page($gid) {
if (node_access('update', array('nid' => $gid, 'status' => 1))) {
if ($edit = $_POST['edit']) {
$names = explode(',', $edit['og_names']);
foreach ($names as $name) {
$account = user_load(array('name' => trim($name)));
if ($account->uid) {
$accounts[] = $account;
$uids[] = $account->uid;
}
else {
$bad[] = $name;
$err = TRUE;
}
}
if (!$err && $accounts) {
// safest option is to do a select, filter existing subscribers, then insert
foreach ($accounts as $account) {
$sql = "INSERT INTO {node_access} (nid, gid, realm, grant_view) VALUES (%d, %d, 'og_uid', 1)";
db_query($sql, $gid, $account->uid);
}
drupal_set_message(t('%count added to the group', array('%count' => format_plural(count($accounts), '1 user', '%count users'))));
}
else {
form_set_error('og_names', t('Unrecognized %names: ', array('%names' => format_plural(count($bad), 'name', 'names'))). implode(', ', $bad));
}
}
$output = form_textarea(t('List of users'), 'og_names', $edit['og_names'], 70, 5, t('Add one or more usernames in order to associate users with this group. Multiple usernames should be separated by a comma.'));
$output .= form_submit(t('Submit'));
$output = form($output);
print theme('page', $output);
}
else {
drupal_access_denied();
}
}
function og_list_users_page($gid) {
$sql = og_list_users_sql(0);
$result = pager_query($sql, 500, 0, NULL, $gid);
$header[] = t("Name");
$access = node_access('update', array('nid' => $gid, 'status' => 1));
if ($access) {
$header[] = array('data' => t('Operations'), 'colspan' => 2);
}
// prepend the group owner
$node = node_load(array('nid' => $gid));
$i=0;
$rows[$i][] = format_name($node). ' '. t('manager'). '';
if ($access) {
$rows[$i][] = l(t('edit group'), "node/$gid/edit");
$rows[$i][] = ' ';
}
$i++;
while ($account = db_fetch_object($result)) {
if ($account->uid != $node->uid) {
$rows[$i][] = format_name($account);
if ($access) {
if ($account->grant_view) {
$rows[$i][] = l(t('unsubscribe'), "og/unsubscribe/$gid/$account->uid", array(), "destination=og/users/$gid");
if ($account->grant_update) {
$rows[$i][] = l(t('admin: remove'), "og/delete_admin/$gid/$account->uid", array(), 'destination='. $_GET['q']);
}
else {
$rows[$i][] = l(t('admin: create'), "og/create_admin/$gid/$account->uid", array(), 'destination='. $_GET['q']);
}
}
else {
$rows[$i][] = l(t('approve'), "og/approve/$gid/$account->uid", array(), "destination=og/users/$gid");
$rows[$i][] = l(t('deny'), "og/deny/$gid/$account->uid", array(), "destination=og/users/$gid");
}
}
$i++;
}
}
if ($pager = theme('pager', NULL, 500)) {
$rows[$i][] = array('data' => $pager, 'colspan' => 2);
}
$output = theme('table', $header, $rows);
$bc = array(l(t('Home'), ''), l(t('groups'), 'og'), l($node->title, "node/$node->nid"));
drupal_set_breadcrumb($bc);
drupal_set_title(t('Subscribers'));
print theme('page', $output);
}
function og_list_groups_page() {
global $user;
$result = pager_query(db_rewrite_sql("SELECT n.nid, n.title, n.body, n.uid, u.name, og.description FROM {og} og INNER JOIN {node} n ON og.nid = n.nid INNER JOIN {users} u ON n.uid = u.uid WHERE og.directory=1 AND n.status=1 ORDER BY n.nid DESC"), 50);
$header = array(t("Title"), t('Subscribers'), t("Owner"), t('Description'));
while ($node = db_fetch_object($result)) {
$cnt = db_num_rows(db_query(og_list_users_sql(), $node->nid));
$rows[] = array(
array("data" => l($node->title, "node/$node->nid")),
array("data" => in_array($node->nid, array_keys($user->og_groups)) ? l($cnt, "og/users/$node->nid") : $cnt),
array("data" => format_name($node)),
array("data" => check_plain($node->description)),
);
}
if (!$rows) {
$rows[] = array(array('data' => t('No groups'), 'colspan' => 4));
}
$output = theme('table', $header, $rows). theme('pager', NULL, 50);
print theme('page', $output);
}
// str_types is a list of types which should be selected. if not provided, we return all but a couple
function og_get_home_nodes_sql($str_types = NULL) {
if ($str_types) {
$str_types = db_escape_string($str_types);
$where = " n.type IN ('$str_types')";
}
else {
$where = "n.type NOT IN ('og', 'image')";
}
return "SELECT DISTINCT(n.nid), n.title, n.uid, u.name, n.created, l.comment_count, l.last_comment_timestamp FROM {node} n INNER JOIN {node_access} og_na ON n.nid = og_na.nid INNER JOIN {node_comment_statistics} l ON n.nid = l.nid INNER JOIN {users} u ON n.uid = u.uid WHERE og_na.gid = %d AND og_na.realm = 'og_group' AND n.status=1 AND $where ORDER BY n.sticky DESC, l.last_comment_timestamp DESC";
}
// when you view a group, you really see some facts about the group in a block and then lists of nodes affiliated with that group.
// each of these lists is presented by default in a table, although that can be changed by the theme
function og_view(&$node, $teaser = FALSE, $page = FALSE) {
$node = theme('og_view', $node, $teaser, $page);
return $node;
}
// if you want a totally different group home page, you may redefine this function in your theme
// if you just want to change the presentation of a group home page section, redefine theme_og_list_generic()
function theme_og_view(&$node, $teaser = FALSE, $page = FALSE) {
if ($teaser || !$page) {
$node->teaser = $node->og_description;
$node = node_prepare($node, $teaser);
}
else {
$bc = array(l(t('Home'), ''), l(t('groups'), 'og'));
drupal_set_breadcrumb($bc);
$output ='';
$mode = 'all';
if (!$types[] = $_GET['ntype']) {
$types = node_list();
$mode = 'brief';
}
foreach ($types as $type) {
// image is filtered out here because we expect images to be added from within albums
$exempt = array_merge(array('og', 'image'), variable_get('og_omitted', array()));
if (!in_array($type, $exempt)) {
if ($table = og_list_og($node->nid, $type, $mode)) {
$output .= $table;
}
}
}
if (!$output) {
drupal_set_message(t('No posts in this group.'));
}
$url = url("og/feed/$node->nid");
$icon = theme('xml_icon', $url);
drupal_set_html_head("title RSS feed\" type=\"application/rss+xml\" />");
// metzlerd - tag on the node body
$node = node_prepare($node,$teaser);
$node->body = $node->body . $output. $icon;
}
return $node;
}
function og_form(&$node, &$param) {
$edit = $_POST['edit'];
if (function_exists('taxonomy_node_form')) {
$output .= implode('', taxonomy_node_form('og', $node));
}
$output .= form_textfield(t('Description'), 'og_description', $node->og_description, 70, 150, '', NULL, TRUE);
// $output .= filter_form('format', $node->format);
if (isset($edit['og_selective'])) {
$selective = $edit['og_selective'];
}
elseif ($node->nid) {
$selective = $node->og_selective;
}
else {
$selective = OG_OPEN;
}
if (isset($edit['og_register'])) {
$register = $edit['og_register'];
}
elseif ($node->nid) {
$register = $node->og_register;
}
else {
$register = 0;
}
if (isset($edit['og_directory'])) {
$directory = $edit['og_directory'];
}
elseif ($node->nid) {
$directory = $node->og_directory;
}
else {
$directory = 1;
}
$output .= form_radios(t('Subscription requests'), 'og_selective', $selective, array(t('open - subscription requests are accepted immediately'), t('moderated - subscription requests must be approved.'), t('invite only - subscriptions must be created by an administrator.')), t('How should subscription requests be handled in this group?'));
$output .= form_checkbox(t('registration form'), 'og_register', 1, $register, t('Should this group be available for subscription during registration?. If checked, a corresponding checkbox will be added to the registration form.'));
$output .= form_checkbox(t('list in groups directory'), 'og_directory', 1, $directory, t('Should this group appear on the %page', array('%page' => l(t('list of groups page'),'og'))));
//metzlerd - Add the ability to specify body to the form.
$output .= form_textarea(t('Body'), 'body', $node->body, 60, 20, '', NULL, TRUE);
$output .= filter_form('format', $node->format);
// group image
if (module_exist('image')) {
if (is_array($node->images)) {
foreach ($node->images as $label => $image) {
$output .= form_hidden('images]['.$label, $image);
}
}
if ($node->images['thumbnail']) {
$output.= form_item(t('Thumbnail'), image_display($node, 'thumbnail'));
}
$output .= form_file(t('Image'), 'image', 50, t('Click "Browse..." to select an image to upload.'));
$param['options'] = array("enctype" => "multipart/form-data", "name" => "image_forms");
}
$allthemes = list_themes();
// list only active themes
foreach ($allthemes as $key => $theme) {
if ($theme->status) {
$themes[$key] = $theme;
}
}
if (count($themes) > 1) {
$rows = array();
foreach ($themes as $key => $value) {
$row = array();
// Screenshot column.
$screenshot = dirname($value->filename) .'/screenshot.png';
$row[] = file_exists($screenshot) ? theme('image', $screenshot, t('Screenshot for %theme theme', array('%theme' => $value->name)), '', 'class="screenshot"', false) : t('no screenshot');
// Information field.
$field = ''. $value->name .'';
$row[] = $field;
// Reset to follow site default theme if user selects the site default
if ($key == variable_get('theme_default', 'bluemarine')) {
$key = '';
if ($node->og_theme == variable_get('theme_default', 'bluemarine')) {
$node->og_theme = '';
}
}
// Selected column.
$row[] = array('data' => form_radio('', 'og_theme', $key, ($node->og_theme == $key) ? 1 : 0), 'align' => 'center');
$rows[] = $row;
}
$header = array(t('Screenshot'), t('Name'), t('Selected'));
$output .= form_item(t('Group theme'), theme('table', $header, $rows), t('Select a theme for your group.'));
}
return $output;
}
// set og_public property for given node
function og_node_load_public($node) {
$sql = "SELECT grant_view FROM {node_access} WHERE nid = %d AND gid=0 AND realm='og_group'";
$gv = db_result(db_query($sql, $node->nid));
$node->og_public = $gv;
return $node;
}
// returns all the group affiliations for a given node.
function og_get_node_groups($node) {
if ($node->type != 'og') {
$sql = "SELECT na.gid, n.title FROM {node_access} na INNER JOIN {node} n ON na.gid = n.nid WHERE na.nid = %d AND na.realm='og_group' AND na.gid != 0";
$result = db_query($sql, $node->nid);
while ($row = db_fetch_object($result)) {
$groups[$row->gid] = $row->title;
}
return $groups ? $groups : array();
}
}
function og_image($gid) {
$node = node_load(array('nid' => $gid));
$request = ($_GET['size']) ? $_GET['size'] : 'preview';
$output = image_display($node, $request);
print theme('page', $output);
}
/**
* Implementation of hook_validate
*/
function og_validate(&$node) {
// comments are not allowed on group nodes, since we don't have any nice way to present them
$node->comment = 0;
// Reset to follow site default theme if user selects the site default
if ($node->og_theme == variable_get('theme_default', 'bluemarine')) {
$node->og_theme = NULL;
}
if (module_exist('image')) {
image_validate($node, 'image');
}
}
function og_node_name($node) {
return t('group');
}
function og_load(&$node) {
$sql = 'SELECT selective AS og_selective, description AS og_description, theme AS og_theme, register AS og_register, directory AS og_directory FROM {og} WHERE nid = %d';
$result = db_query($sql, $node->nid);
$node = (object) array_merge((array)$node, db_fetch_array($result));
// module_invoke does not pass references and image_load() requires this
if ($node->og_image && function_exists('image_load')) {
image_load($node);
}
}
function og_insert($node) {
$sql = "INSERT INTO {og} (nid, theme, selective, description, register, directory) VALUES (%d, '%s', %d, '%s', %d, %d)";
db_query($sql, $node->nid, $node->og_theme, $node->og_selective, $node->og_description, $node->og_register, $node->og_directory);
}
function og_update($node) {
if ($node->images) {
foreach ($node->images as $label => $image) {
$old_path = db_result(db_query("SELECT filepath FROM {files} WHERE filename='%s' AND nid=%d", $label, $node->nid));
// This is a new image.
if ($old_path != $image) {
file_delete(file_create_path($old_path));
db_query("DELETE FROM {files} WHERE filename='%s' AND nid=%d", $label, $node->nid);
_image_insert($node->nid, $label, file_create_path($image));
}
}
}
$sql = "UPDATE {og} SET theme = '%s', selective = %d, register = %d, description = '%s', directory = %d WHERE nid = %d";
db_query($sql, $node->og_theme, $node->og_selective, $node->og_register, $node->og_description, $node->og_directory, $node->nid);
}
/**
* Implementation of hook_nodeapi().
*
*/
function og_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) {
switch ($op) {
case 'view':
if ($bc = $GLOBALS['og_node_bc']) {
drupal_set_breadcrumb($bc);
}
break;
case 'load':
if ($node->type != 'og') {
$node = og_node_load_public($node);
}
if ($grps = og_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 'validate':
global $user;
if ($node->type != 'og') {
// 'og/album/validate' is a special case. We want the audience validation even if 'image' node type is omitted
// Used for album module galleries
if (!in_array($node->type, variable_get('og_omitted', array())) || substr_count($_GET['q'], 'og/album/validate')) {
if (variable_get('og_audience_required', 0) && empty($node->og_groups) && $_POST) {
form_set_error('og_groups', t('You must select an audience in order to post.'));
}
else {
if (is_array($node->og_groups)) {
foreach($node->og_groups as $gid) {
if (!in_array($gid, array_keys($user->og_groups))) {
form_set_error('og_groups', t('%name must be a subscriber in order to post into %group', array('%name' => $node->name, '%group' => $$user->og_groups[$gid]['title'])));
}
}
}
}
if (!user_access('administer organic groups')) {
$vis = variable_get('og_visibility', 0);
switch ($vis) {
case OG_VISIBLE_BOTH:
$node->og_public = 1;
break;
case OG_VISIBLE_GROUPONLY:
$node->og_public = 0;
break;
}
}
}
// if a post isn't in any groups. it must be public
if (empty($node->og_groups)) {
$node->og_public = 1;
}
}
break;
case 'delete':
og_delete_folksonomy($node);
og_delete_permissions($node);
break;
case 'insert':
og_save_permissions($node);
og_mail($node);
break;
case 'update':
og_save_permissions($node);
break;
case 'form post':
return og_nodeapi_form($node);
}
}
function og_nodeapi_form($node) {
$edit = $_REQUEST['edit'];
// 'og/albums/form' is a special case. We want the audience selection and 'public' checkbox even if 'image' node type is omitted
// Used for album module galleries
if ( substr_count($_GET['q'], 'og/albums/form') == 0 && ( $node->type == 'og' || ( in_array($node->type, variable_get('og_omitted', array()))))) {
return form_hidden('og_public', 1);
}
else {
$required = variable_get('og_audience_required', 0);
$subs = og_get_subscriptions($node->uid);
foreach ($subs as $key => $val) {
$options[$key] = $val['title'];
}
if (!$options && $required && $_POST) {
drupal_set_message(t('You must subscribe to a group before posting.'), 'error');
}
if (user_access('administer organic groups')) {
$vis = OG_VISIBLE_CHOOSE;
drupal_set_message(t('Admins: If you want to assign this post to a group whose checkbox does not appear below, you must first change the %author. The author\'s subscriptions are always shown.', array('%author' => theme('placeholder', t('Author')))));
}
else {
$vis = variable_get('og_visibility', 0);
}
switch ($vis) {
case OG_VISIBLE_CHOOSE: //user decides how public the post is
if (isset($edit['og_public'])) {
$public = $edit['og_public'];
}
elseif ($node->nid) {
$public = $node->og_public;
}
else {
$public = 1;
}
$output .= form_checkbox(t('Public'), 'og_public', 1, $public, t('Show this post to everyone or only to members of the checked selected below.'));
break;
}
if (isset($edit['og_groups'])) {
$groups = $edit['og_groups'];
}
elseif ($node->nid) {
$groups = $node->og_groups;
}
else {
$groups = array();
}
$output .= form_checkboxes(t('Audience'), 'og_groups', $groups, $options, t('Show this post in these groups.'), NULL, $required);
return $output;
}
}
/**
* Send this node via email to all email subscribers. Called from og_nodeapi()
*
* @param $node
* the node which was just added or updated
* @return
* none
*/
function og_mail($node) {
if ($node->og_groups) {
$url = url("node/$node->nid", NULL, NULL, TRUE);
$author = user_load(array('uid' => $node->uid));
$sitemail = variable_get("site_mail", ini_get("sendmail_from"));
$headers = "From: $sitemail\nReply-to: $sitemail\nX-Mailer: Drupal\nReturn-path: $sitemail\nErrors-to: $sitemail";
//get email subscribers
$groups = implode(', ', $node->og_groups);
$sql = "SELECT DISTINCT(u.mail) as mail, ou.nid AS gid, n.title AS group_name FROM {og_uid} ou INNER JOIN {users} u ON ou.uid=u.uid INNER JOIN {node} n ON ou.nid=n.nid WHERE ou.nid IN ($groups) AND ou.mail_type=1";
$result = db_query($sql);
while ($row = db_fetch_object($result)) {
$subj = "[$row->group_name] ". t('%author added \'%title\' at %site', array('%author' => $author->name, '%title' => $node->title, '%site' => variable_get('site_name', drupal)));
$txt = "'$node->title' by $author->name\n$url\n\n";
$txt .= $node->read_more ? t('EXCERPT') : t('FULL POST');
$txt .= "\n". og_mail_output($node->teaser, 1, $node->format);
$txt .= "\n\n-----------------------\n";
$txt .= t("You are subscribed to the group '%group_name' at '%site'. To manage your subscription, visit %group_url", array('%group_name' => $row->group_name, '%site' => variable_get('site_name', drupal), '%group_url' => url("og/manage/$row->gid", NULL, NULL, TRUE)));
$subject = "[]";
user_mail($row->mail, $subj, $txt, $headers);
}
}
}
// 2 functions blatantly ripped from mail.inc in project.module package
function og_mail_urls($url = 0) {
static $urls = array();
if ($url) {
$urls[] = strpos($url, '://') ? $url : url($url, NULL, NULL, 1);
return count($urls);
}
return $urls;
}
function og_mail_output(&$body, $html = 1, $format = FILTER_FORMAT_DEFAULT) {
static $i = 0;
if ($html) {
$pattern = '@((.+?))@ei';
$body = preg_replace($pattern, "'\\3 ['. og_mail_urls('\\2') .']'", $body);
$urls = og_mail_urls();
if (count($urls)) {
$body .= "\n";
for ($max = count($urls); $i < $max; $i++) {
$body .= '['. ($i + 1) .'] '. $urls[$i] ."\n";
}
}
$body = check_output($body, $format);
$body = preg_replace('!?blockquote>!i', '"', $body);
$body = preg_replace('!?(em|i)>!i', '/', $body);
$body = preg_replace('!?(b|strong)>!i', '*', $body);
$body = preg_replace("@
(?!\n)@i", "\n", $body);
$body = preg_replace("@