'forum',
'title' => t('Forums'),
'callback' => 'og_forum_page',
'type' => MENU_SUGGESTED_ITEM,
'access' => user_access('access content'),
);
$items[] = array(
'path' => 'admin/og/og_forum',
'title' => t('Organic groups forums'),
'description' => t('Configure forums for organic groups'),
'callback' => 'drupal_get_form',
'callback arguments' => array('og_forum_admin_settings'),
'access' => user_access('administer site configuration'),
);
}
else {
// we expect the group nid as 1st argument
if (is_numeric(arg(2))) {
// load forum's group
$group = node_load(arg(2));
if ($group) {
$items[] = array(
'title' => t('Manage group\'s forum'),
'path' => 'og_forum/manage',
'callback' => 'og_forum_manage',
'callback arguments' => array($group),
'type' => MENU_CALLBACK,
'access' => (og_forum_is_admin($group) && user_access('admin own group forums')) || user_access('administer forums'),
);
}
}
elseif (is_numeric(arg(3)) && is_numeric(arg(4))) {
if (arg(2) == 'add') {
$group = node_load(arg(3));
$items[] = array(
'path' => 'og_forum/manage/add',
'title' => t('Add forum'),
'callback' => 'og_forum_form_main',
'callback arguments' => array('add', array('group_id' => arg(3), 'parent' => arg(4))),
'access' => ((og_forum_is_admin($group) && user_access('admin own group forums')) && !og_forum_forum_limit_reached(arg(3))) || user_access('administer forums'),
'type' => MENU_CALLBACK
);
}
elseif (arg(2) == 'edit') {
$group = node_load(arg(3));
$term = taxonomy_get_term(arg(4));
$parents = taxonomy_get_parents($term->tid);
$parent = array_pop($parents);
$term->parent = $parent->tid;
$term->group_id = arg(3);
$items[] = array(
'path' => 'og_forum/manage/edit',
'title' => t('Edit forum'),
'callback' => 'og_forum_form_main',
'callback arguments' => array('edit', (array)$term),
'access' => ((og_forum_is_admin($group) && user_access('admin own group forums')) || user_access('administer forums')),
'type' => MENU_CALLBACK
);
}
elseif (arg(2) == 'public') {
$group = node_load(arg(3));
$allow_public = variable_get('forum_allow_public', 0);
$items[] = array(
'path' => 'og_forum/manage/public',
'title' => t('Make forum public'),
'callback' => 'og_forum_public',
'callback arguments' => array('group_id' => arg(3), 'tid' => arg(4)),
'access' => ((og_forum_is_admin($group) && user_access('admin own group forums') && $allow_public) || user_access('make forums public')),
'type' => MENU_CALLBACK
);
}
elseif (arg(2) == 'private') {
$group = node_load(arg(3));
$allow_public = variable_get('forum_allow_public', 0);
$items[] = array(
'path' => 'og_forum/manage/private',
'title' => t('Make forum private'),
'callback' => 'og_forum_private',
'callback arguments' => array('group_id' => arg(3), 'tid' => arg(4)),
'access' => ((og_forum_is_admin($group) && user_access('admin own group forums') && $allow_public) || user_access('make forums public')),
'type' => MENU_CALLBACK
);
}
elseif (arg(2) == 'reset') {
$group = node_load(arg(3));
$allow_public = variable_get('forum_allow_public', 0);
$items[] = array(
'path' => 'og_forum/manage/reset',
'title' => t('Reset forum publicity'),
'callback' => 'og_forum_reset',
'callback arguments' => array('group_id' => arg(3), 'tid' => arg(4)),
'access' => ((og_forum_is_admin($group) && user_access('admin own group forums') && $allow_public) || user_access('make forums public')),
'type' => MENU_CALLBACK
);
}
}
}
return $items;
} // function og_forum_menu()
/**
* Implimentation of hook_block()
*
* Creates a block to display forum information for a group.
*/
function og_forum_block($op = 'list', $delta = 0, $edit = array()) {
if($group_node = og_get_group_context()){
$nid = $group_node->nid;
}
switch ($op) {
case 'list':
$blocks[0]['info'] = t('Active forum topics in group');
$blocks[1]['info'] = t('New forum topics in group');
return $blocks;
case 'configure':
$form['og_forum_block_num_'. $delta] = array('#type' => 'select', '#title' => t('Number of topics'), '#default_value' => variable_get('og_forum_block_num_'. $delta, '5'), '#options' => drupal_map_assoc(array(2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20)));
return $form;
case 'save':
variable_set('og_forum_block_num_'. $delta, $edit['og_forum_block_num_'. $delta]);
break;
case 'view':
if (user_access('access content') && $nid) {
switch ($delta) {
case 0:
$title = t('Active group forum topics');
$sql = db_rewrite_sql("SELECT n.nid, n.title, l.comment_count, l.last_comment_timestamp FROM {node} n INNER JOIN {node_comment_statistics} l INNER JOIN {og_term} ot INNER JOIN {term_node} tn WHERE ot.nid = $nid AND ot.tid = tn.tid AND tn.nid = n.nid AND n.nid = l.nid AND n.status = 1 AND n.type = 'forum' ORDER BY l.last_comment_timestamp DESC");
$result = db_query_range($sql, 0, variable_get('og_forum_block_num_0', '5'));
if (db_num_rows($result)) {
$content = node_title_list($result);
}
break;
case 1:
$title = t('New group forum topics');
$sql = db_rewrite_sql("SELECT n.nid, n.title FROM {node} n, {og_term} ot, {term_node} tn WHERE (ot.nid = %d) AND (ot.tid = tn.tid) AND (tn.nid = n.nid)", $nid);
$sql = db_rewrite_sql("SELECT n.nid, n.title, l.comment_count FROM {node} n INNER JOIN {node_comment_statistics} l INNER JOIN {og_term} ot INNER JOIN {term_node} tn WHERE ot.nid = $nid AND ot.tid = tn.tid AND tn.nid = n.nid AND n.nid = l.nid AND n.type = 'forum' AND n.status = 1 ORDER BY n.nid DESC");
$result = db_query_range($sql, 0, variable_get('og_forum_block_num_1', '5'));
if (db_num_rows($result)) {
$content = node_title_list($result);
}
break;
}
if ($content) {
$forum = og_forum_get_forum_container($nid);
$content .= '
'. l(t('more'), "forum/$forum") .'
';
}
$block['subject'] = $title;
$block['content'] = $content;
return $block;
}
}
} //og_forum_block
/**
* Menu callback; allows us to set group context prior to loading a forum
*/
function og_forum_page($tid = 0) {
global $user;
if ($tid != 0) {
og_forum_set_og_group_context_from_tid($tid);
$gid = og_forum_gid_from_tid($tid);
if ($gid) {
if (!array_key_exists($gid, $user->og_groups) && ($user->uid != 1) && !(user_access('administer forums')) && !og_forum_is_public($tid)) {
return drupal_access_denied();
}
}
}
elseif (is_numeric(og_get_group_context())) {
$tid = og_get_group_context();
}
//The rest is copied from forum_page with a modified theme call
if (module_exists('taxonomy') && module_exists('comment')) {
$forum_per_page = variable_get('forum_per_page', 25);
$sortby = variable_get('forum_order', 1);
if (og_forum_is_public($tid)) {
$forums = og_forum_get_forums($tid);
}
else {
$forums = forum_get_forums($tid);
}
$parents = taxonomy_get_parents_all($tid);
if ($tid && !in_array($tid, variable_get('forum_containers', array()))) {
if (og_forum_is_public($tid)) {
$topics = og_forum_get_topics($tid, $sortby, $forum_per_page);
}
else {
$topics = forum_get_topics($tid, $sortby, $forum_per_page);
}
}
return theme('og_forum_display', $forums, $topics, $parents, $tid, $sortby, $forum_per_page);
}
else {
drupal_set_message(t('The forum module requires both the taxonomy module and the comment module to be enabled and configured.'), 'error');
return ' ';
}
} // function og_forum_page()
/**
* Returns a list of all forums for a given taxonomy id.
* Copied forum_get_forums from the forum module in order to bypass node_access removing topics from listings when set to publicly viewable.
* This is only called when private posts should be viewable and on a per-forum basis - i.e. called only when the forum's publicity is set
* to PRIVATE_DEFAULT; if a group owner sets a forum to PRIVATE_SET_BY_OWNER, topics won't show in the list.
*
* Forum objects contain the following fields
* -num_topics Number of topics in the forum
* -num_posts Total number of posts in all topics
* -last_post Most recent post for the forum
*
* @param $tid
* Taxonomy ID of the vocabulary that holds the forum list.
* @return
* Array of object containing the forum information.
*/
function og_forum_get_forums($tid = 0) {
$forums = array();
$_forums = taxonomy_get_tree(variable_get('forum_nav_vocabulary', ''), $tid);
if (count($_forums)) {
$counts = array();
$sql = "SELECT r.tid, COUNT(n.nid) AS topic_count, SUM(l.comment_count) AS comment_count FROM {node} n INNER JOIN {node_comment_statistics} l ON n.nid = l.nid INNER JOIN {term_node} r ON n.nid = r.nid WHERE n.status = 1 AND n.type = 'forum' GROUP BY r.tid";
//$sql = db_rewrite_sql($sql);
$_counts = db_query($sql, $forum->tid);
while ($count = db_fetch_object($_counts)) {
$counts[$count->tid] = $count;
}
}
foreach ($_forums as $forum) {
if (in_array($forum->tid, variable_get('forum_containers', array()))) {
$forum->container = 1;
}
if ($counts[$forum->tid]) {
$forum->num_topics = $counts[$forum->tid]->topic_count;
$forum->num_posts = $counts[$forum->tid]->topic_count + $counts[$forum->tid]->comment_count;
}
else {
$forum->num_topics = 0;
$forum->num_posts = 0;
}
// This query does not use full ANSI syntax since MySQL 3.x does not support
// table1 INNER JOIN table2 INNER JOIN table3 ON table2_criteria ON table3_criteria
// used to join node_comment_statistics to users.
$sql = "SELECT ncs.last_comment_timestamp, IF (ncs.last_comment_uid != 0, u2.name, ncs.last_comment_name) AS last_comment_name, ncs.last_comment_uid FROM {node} n INNER JOIN {users} u1 ON n.uid = u1.uid INNER JOIN {term_node} tn ON n.nid = tn.nid INNER JOIN {node_comment_statistics} ncs ON n.nid = ncs.nid INNER JOIN {users} u2 ON ncs.last_comment_uid=u2.uid WHERE n.status = 1 AND n.type='forum' AND tn.tid = %d ORDER BY ncs.last_comment_timestamp DESC";
//$sql = db_rewrite_sql($sql);
$topic = db_fetch_object(db_query_range($sql, $forum->tid, 0, 1));
$last_post = new stdClass();
$last_post->timestamp = $topic->last_comment_timestamp;
$last_post->name = $topic->last_comment_name;
$last_post->uid = $topic->last_comment_uid;
$forum->last_post = $last_post;
$forums[$forum->tid] = $forum;
}
return $forums;
} // function og_forum_get_forums()
/**
* Copied forum_get_topics from the forum module in order to bypass node_access removing topics from listings when set to publicly viewable.
* This is only called when private posts should be viewable and on a per-forum basis - i.e. called only when the forum's publicity is set
* to PRIVATE_DEFAULT; if a group owner sets a forum to PRIVATE_SET_BY_OWNER, topics won't show in the list.
*
* @param integer $tid
* @param string $sortby
* @param integer $forum_per_page
* @return array
*/
function og_forum_get_topics($tid, $sortby, $forum_per_page) {
global $user, $forum_topic_list_header;
$forum_topic_list_header = array(
array('data' => ' ', 'field' => NULL),
array('data' => t('Topic'), 'field' => 'n.title'),
array('data' => t('Replies'), 'field' => 'l.comment_count'),
array('data' => t('Created'), 'field' => 'n.created'),
array('data' => t('Last reply'), 'field' => 'l.last_comment_timestamp'),
);
$order = _forum_get_topic_order($sortby);
for ($i = 0; $i < count($forum_topic_list_header); $i++) {
if ($forum_topic_list_header[$i]['field'] == $order['field']) {
$forum_topic_list_header[$i]['sort'] = $order['sort'];
}
}
$term = taxonomy_get_term($tid);
//can I just use some regexes to remove restirctions after I get the $sql var back from db_rewrite_sql? or do I not really need to worry about that? for now, just unwrapping db_rewrite_sql from next line
$sql = "SELECT n.nid, f.tid, n.title, n.sticky, u.name, u.uid, n.created AS timestamp, n.comment AS comment_mode, l.last_comment_timestamp, IF(l.last_comment_uid != 0, cu.name, l.last_comment_name) AS last_comment_name, l.last_comment_uid, l.comment_count AS num_comments FROM {node_comment_statistics} l, {users} cu, {term_node} r, {users} u, {forum} f, {node} n WHERE n.status = 1 AND l.last_comment_uid = cu.uid AND n.nid = l.nid AND n.nid = r.nid AND r.tid = %d AND n.uid = u.uid AND n.vid = f.vid";
$sql .= tablesort_sql($forum_topic_list_header, 'n.sticky DESC,');
$sql .= ', n.created DESC'; // Always add a secondary sort order so that the news forum topics are on top.
$sql_count = "SELECT COUNT(n.nid) FROM {node} n INNER JOIN {term_node} r ON n.nid = r.nid AND r.tid = %d WHERE n.status = 1 AND n.type = 'forum'";
$result = pager_query($sql, $forum_per_page, 0, $sql_count, $tid);
$topics = array();
while ($topic = db_fetch_object($result)) {
if ($user->uid) {
// folder is new if topic is new or there are new comments since last visit
if ($topic->tid != $tid) {
$topic->new = 0;
}
else {
$history = _forum_user_last_visit($topic->nid);
$topic->new_replies = comment_num_new($topic->nid, $history);
$topic->new = $topic->new_replies || ($topic->timestamp > $history);
}
}
else {
// Do not track "new replies" status for topics if the user is anonymous.
$topic->new_replies = 0;
$topic->new = 0;
}
if ($topic->num_comments > 0) {
$last_reply = new stdClass();
$last_reply->timestamp = $topic->last_comment_timestamp;
$last_reply->name = $topic->last_comment_name;
$last_reply->uid = $topic->last_comment_uid;
$topic->last_reply = $last_reply;
}
$topics[] = $topic;
}
return $topics;
} // function og_forum_get_topics()
/**
* Format the forum body.
*
* Copied from forum module. Slightly modified to produce correct links and eliminate 'add new topic' links in containers.
*
* @ingroup themeable
*/
function theme_og_forum_display($forums, $topics, $parents, $tid, $sortby, $forum_per_page) {
global $user;
// forum list, topics list, topic browser and 'add new topic' link
$vocabulary = taxonomy_get_vocabulary(variable_get('forum_nav_vocabulary', ''));
$title = $vocabulary->name;
// Breadcrumb navigation:
$breadcrumb = array();
if ($gid !== NULL) {
$breadcrumb[] = array('path' => "og", 'title' => t('Groups'));
$breadcrumb[] = array('path' => "node/". $node->og_groups[0], 'title' => $node->og_groups_names[0]);
}
if ($tid) {
$breadcrumb[] = array('path' => 'forum', 'title' => $title);
}
if ($parents) {
$parents = array_reverse($parents);
foreach ($parents as $p) {
if ($p->tid == $tid) {
$title = $p->name;
}
else {
$breadcrumb[] = array('path' => 'forum/' .$p->tid, 'title' => $p->name);
}
}
}
drupal_set_title(check_plain($title));
$breadcrumb[] = array('path' => $_GET['q']);
menu_set_location($breadcrumb);
if (count($forums) || count($parents)) {
$output = '';
$output .= '
';
if (user_access('create forum topics') && !in_array($tid, variable_get('forum_containers', array())) && ($tid != 0)) {
og_forum_set_og_group_context_from_tid($tid);
$gid = og_forum_gid_from_tid($tid);
//group forum link with group selected
if (!empty($gid) && array_key_exists($gid, $user->og_groups)) {//make sure only group members are shown this link
$output .= '- ' .l(t('Post new forum topic.'), "node/add/forum/$tid", array() , "gids[]=$gid"). '
';
}
elseif (empty($gid)) {//normal forum, not in group
$output .= '- ' .l(t('Post new forum topic.'), "node/add/forum/$tid"). '
';
}
}
elseif (user_access('create forum topics')) {
$output .= '- ' .t('Select a forum below.'). '
';
}
elseif ($user->uid) {
$output .= '- ' .t('You are not allowed to post a new forum topic.'). '
';
}
else {
$output .= '- ' .t('Login to post a new forum topic.', array('@login' => url('user/login', drupal_get_destination()))). '
';
}
$output .= '
';
$output .= theme('og_forum_list', $forums, $parents, $tid);
if ($tid && !in_array($tid, variable_get('forum_containers', array()))) {
$output .= theme('og_forum_topic_list', $tid, $topics, $sortby, $forum_per_page, $gid);
if (og_forum_is_public($tid)) {
drupal_add_feed(url('taxonomy/term/' .$tid. '/0/feed'), 'RSS - ' .$title);
}
}
$output .= '
';
}
else {
drupal_set_title(t('No forums defined or you don\'t have permission to view them.'));
$output = '';
}
return $output;
} // function theme_og_forum_display()
/**
* Format the forum listing.
*
* Copied from forum module. Slightly modified to produce correct links.
*
* @ingroup themeable
*/
function theme_og_forum_list($forums, $parents, $tid) {
global $user;
if ($forums) {
$header = array(t('Forum'), t('Topics'), t('Posts'), t('Last post'));
foreach ($forums as $forum) {
if ($forum->container) {
$description = '\n";
$description .= '
' .l($forum->name, "forum/$forum->tid"). "
\n";
if ($forum->description) {
$description .= '
' .filter_xss_admin($forum->description). "
\n";
}
$description .= "
\n";
$rows[] = array(array('data' => $description, 'class' => 'container', 'colspan' => '4'));
}
else {
$new_topics = _forum_topics_unread($forum->tid, $user->uid);
$forum->old_topics = $forum->num_topics - $new_topics;
if (!$user->uid) {
$new_topics = 0;
}
$description = '\n";
$description .= '
' .l($forum->name, "forum/$forum->tid"). "
\n";
if ($forum->description) {
$description .= '
' .filter_xss_admin($forum->description). "
\n";
}
$description .= "
\n";
$rows[] = array(
array('data' => $description, 'class' => 'forum'),
array('data' => $forum->num_topics .($new_topics ? '
' .l(format_plural($new_topics, '1 new', '@count new'), "forum/$forum->tid", NULL, NULL, 'new') : ''), 'class' => 'topics'),
array('data' => $forum->num_posts, 'class' => 'posts'),
array('data' => _forum_format($forum->last_post), 'class' => 'last-reply'));
}
}
return theme('table', $header, $rows);
}
} // function theme_og_forum_list()
/**
* Format the topic listing.
*
* Copied from forum module. Slightly modified to produce correct links.
*
* @ingroup themeable
*/
function theme_og_forum_topic_list($tid, $topics, $sortby, $forum_per_page, $gid) {
global $forum_topic_list_header, $user;
if ($topics) {
foreach ($topics as $topic) {
// folder is new if topic is new or there are new comments since last visit
if ($topic->tid != $tid) {
$rows[] = array(
array('data' => theme('forum_icon', $topic->new, $topic->num_comments, $topic->comment_mode, $topic->sticky), 'class' => 'icon'),
array('data' => check_plain($topic->title), 'class' => 'title'),
array('data' => l(t('This topic has been moved'), "forum/$topic->tid"), 'colspan' => '3')
);
}
else {
$sql = "SELECT oa.nid, COALESCE(oa.is_public, 1) AS is_public FROM {node} n LEFT JOIN {og_ancestry} oa ON oa.nid = n.nid WHERE n.nid = %d";
$public_post = db_fetch_object(db_query($sql, $topic->nid));
if (isset($public_post) && $public_post->is_public == 1 && !array_key_exists($gid, $user->og_groups)) {
$rows[] = array(
array('data' => theme('forum_icon', $topic->new, $topic->num_comments, $topic->comment_mode, $topic->sticky) .' public', 'class' => 'icon public'),
array('data' => l($topic->title, "node/$topic->nid"), 'class' => 'topic'),
array('data' => $topic->num_comments. ($topic->new_replies ? '
' .l(format_plural($topic->new_replies, '1 new', '@count new'), "node/$topic->nid", NULL, NULL, 'new') : ''), 'class' => 'replies'),
array('data' => _forum_format($topic), 'class' => 'created'),
array('data' => _forum_format(isset($topic->last_reply) ? $topic->last_reply : NULL), 'class' => 'last-reply')
);
}
elseif (isset($public_post) && $public_post->is_public == 0 && !array_key_exists($gid, $user->og_groups)) {
$rows[] = array(
array('data' => theme('forum_icon', $topic->new, $topic->num_comments, $topic->comment_mode, $topic->sticky) .' private', 'class' => 'icon private'),
array('data' => l($topic->title, "node/$topic->nid"), 'class' => 'topic'),
array('data' => $topic->num_comments. ($topic->new_replies ? '
' .l(format_plural($topic->new_replies, '1 new', '@count new'), "node/$topic->nid", NULL, NULL, 'new') : ''), 'class' => 'replies'),
array('data' => _forum_format($topic), 'class' => 'created'),
array('data' => _forum_format(isset($topic->last_reply) ? $topic->last_reply : NULL), 'class' => 'last-reply')
);
}
elseif (isset($public_post)) {//if the user is a group member, hide the public/private indicators
$rows[] = array(
array('data' => theme('forum_icon', $topic->new, $topic->num_comments, $topic->comment_mode, $topic->sticky), 'class' => 'icon'),
array('data' => l($topic->title, "node/$topic->nid"), 'class' => 'topic'),
array('data' => $topic->num_comments. ($topic->new_replies ? '
' .l(format_plural($topic->new_replies, '1 new', '@count new'), "node/$topic->nid", NULL, NULL, 'new') : ''), 'class' => 'replies'),
array('data' => _forum_format($topic), 'class' => 'created'),
array('data' => _forum_format(isset($topic->last_reply) ? $topic->last_reply : NULL), 'class' => 'last-reply')
);
}
else {//non-group forum topics
$rows[] = array(
array('data' => theme('forum_icon', $topic->new, $topic->num_comments, $topic->comment_mode, $topic->sticky) .' public', 'class' => 'icon public'),
array('data' => l($topic->title, "node/$topic->nid"), 'class' => 'topic'),
array('data' => $topic->num_comments. ($topic->new_replies ? '
' .l(format_plural($topic->new_replies, '1 new', '@count new'), "node/$topic->nid", NULL, NULL, 'new') : ''), 'class' => 'replies'),
array('data' => _forum_format($topic), 'class' => 'created'),
array('data' => _forum_format(isset($topic->last_reply) ? $topic->last_reply : NULL), 'class' => 'last-reply')
);
}
}
}
}
$output = theme('table', $forum_topic_list_header, $rows);
$output .= theme('pager', NULL, $forum_per_page, 0);
return $output;
} // function theme_og_forum_topic_list()
/**
* Implementation of hook_settings().
*/
function og_forum_admin_settings() {
$form['#submit']['og_forum_settings_submit'] = array(); // custom submit handler
$form['#submit']['system_settings_form_submit'] = array(); // we just overrode the standard submit, but still want it to fire too
$form['update'] = array(
'#type' => 'fieldset',
'#title' => t('Retroactively update old groups'),
'#description' => t('Pressing this button will create forums for any groups that do not already have them.'),
'#collapsible' => TRUE,
);
$form['update']['button'] = array(
'#type' => 'submit',
'#value' => t('Update old groups'),
);
$current_default_name = variable_get('forum_default_name', 'General discussion');
$form['default_forum_name'] = array(
'#type' => 'textfield',
'#title' => t('Default forum name'),
'#description' => t('When this module creates a container and default forum for a new group, this will be the name given to that group.'),
'#default_value' => $current_default_name,
);
$form['container'] = array(
'#type' => 'fieldset',
'#title' => t('Group forum container'),
'#collapsible' => TRUE,
);
$default_container_yn = variable_get('forum_default_container_yn', FALSE);
$form['container']['default_container_yn'] = array(
'#type' => 'checkbox',
'#title' => t('Would you like all group forums to be placed in the same container?'),
'#description' => t('If you would like your forums to all be under one container, check this box and select a container in the drop down box.'),
'#default_value' => $default_container_yn,
);
$default_container = variable_get('forum_default_container', 0);
$all_container_tids = variable_get('forum_containers', array());
$sql = "SELECT name FROM {term_data} WHERE tid = %d";
$containers = array();
$containers[-1] = t('none');
foreach ($all_container_tids as $key => $tid) {
$result = db_fetch_object(db_query($sql, $tid));
$containers[$tid] = $result->name;
}
$form['container']['default_container'] = array(
'#type' => 'select',
'#title' => t('Select container'),
'#description' => t('You need to have setup the container before hand.'),
'#default_value' => $default_container,
'#options' => $containers,
);
$form['public_forums'] = array(
'#type' => 'fieldset',
'#title' => t('Forum publicity administration'),
'#description' => t('Using these features is probably expensive in terms of SQL queries.'),
'#collapsible' => TRUE,
);
$auto_public = variable_get('forum_auto_public', 0);
$form['public_forums']['auto_public'] = array(
'#type' => 'checkbox',
'#title' => t('Automatic forum publicity'),
'#description' => t('If you would like to make the publicity, or public-ness, of forums automatic based on whether there are any public posts inside
of them, then check this box.'),
'#default_value' => $auto_public,
);
$allow_public = variable_get('forum_allow_public', 0);
$form['public_forums']['allow_public'] = array(
'#type' => 'checkbox',
'#title' => t('Allow public choice'),
'#description' => t('If you would like to allow group owners the ability to decide which, if any, of their forums are publicly viewable, check the box.
Those with the make forums public permission can always make forums and containers public. If auto mode is checked, above, then this will
allow group owners to override auto settings on a case by case basis. The auto mode respects group owner-set values.'),
'#default_value' => $allow_public,
);
$all_public = variable_get('forum_all_public', 0);
$form['public_forums']['all_public'] = array(
'#type' => 'checkbox',
'#title' => t('Make all forums public'),
'#description' => t('This is only a display option and will not affect database entries. If you have both boxes unchecked above and no users assigned
to the make forums public permission, no database entries will be made as to the publicity of forums, but all will be visible and traversable.
User 1 can still affect the database through the normal "make public" and "make private" functionality, but such changes won\'t affect the forums\'
display until such time as this feature is disabled. Individual posts will be public or private based on their own settings, just like if the above
features are used. This is an easy way to get all forums visible to all users so they can see what posts they are missing out on (in the case where posts
are private themselves). With this setting, no forums can be private. You could use this feature during a promotion period to temporarily open the whole
site to guests.'),
'#default_value' => $all_public,
);
$form['public_forums']['pb'] = array(
'#type' => 'fieldset',
'#title' => t('Manage publicity of old groups'),
'#description' => t('If you check the "Automatic forum publicity" box, this will go through all existing forums and set them accordingly.
Otherwise, a public forum topic will need to be created or resaved in each forum. You don\'t need to click this if you haven\'t checked that box.
You should use this only once - usually the first time you upgrade to a version with this feature as it will not respect settings made by
group owners.'),
);
$form['public_forums']['pb']['public_button'] = array(
'#type' => 'submit',
'#value' => t('Publicize old groups'),
);
$form['public_forums']['rp'] = array(
'#type' => 'fieldset',
'#title' => t('Switch to automatic publicity'),
'#description' => t('This will switch all group admin-set publicity values to automatic values. PUBLIC_BY_GROUP_OWNER -> PUBLIC_AUTO, PRIVATE_BY_GROUP_OWNER -> PRIVATE_DEFAULT. This will allow you to switch a site from
group admin-controlled publicity to automatic publicity of forums.'),
);
$form['public_forums']['rp']['switch_auto'] = array(
'#type' => 'submit',
'#value' => t('Switch to auto mode'),
);
$forum_limit = variable_get('forum_limit', 0);
$form['limit_forums'] = array(
'#type' => 'textfield',
'#title' => t('Limit number of forums per group'),
'#size' => 3,
'#maxlength' => 3,
'#description' => t('Set the number of forums a container can have. 0 means no limit. 1 means groups can only have the default "General Discussion" forum.'),
'#default_value' => $forum_limit,
);
return system_settings_form($form);
} // function og_forum_admin_settings()
/**
* Custom submit handler for group update
*/
function og_forum_settings_submit($form_id, $form_values) {
if ($form_values['op'] == t('Update old groups')) {
og_forum_retroactively_apply();
}
elseif ($form_values['op'] == t('Publicize old groups')) {
$auto_public = variable_get('forum_auto_public', 0);
if ($auto_public) {
//go through all existing forums and where a node has been made public, set the forum's publicity to PUBLIC_AUTO
$sql = "SELECT DISTINCT tn.tid, oa.group_nid FROM {node} n INNER JOIN {og_ancestry} oa ON oa.nid = n.nid INNER JOIN {term_node} tn ON tn.nid = oa.nid WHERE n.type = 'forum' AND oa.is_public = 1";
$results = db_query($sql);
while ($result = db_fetch_object($results)) {
$gid = $result->group_nid;
$container = og_forum_get_forum_container($gid);
$sql2 = "UPDATE {og_term} SET public = %d WHERE tid = %d and nid = %d";
db_query($sql2, PUBLIC_AUTO, $result->tid, $gid);
db_query($sql2, PUBLIC_AUTO, $container, $gid);
}
}
else {
drupal_set_message(t('You need to select "Automatic forum publicity" for this to work.'), 'error');
}
}
elseif ($form_values['op'] == t('Switch to auto mode')) {
$sql = "UPDATE {og_term} SET public = %d WHERE public = %d";
db_query($sql, PUBLIC_AUTO, PUBLIC_BY_GROUP_OWNER);
db_query($sql, PRIVATE_DEFAULT, PRIVATE_BY_GROUP_OWNER);
}
if ($form_values['op'] == t('Save configuration')) {
variable_set('forum_default_name', $form_values['default_forum_name']);
variable_set('forum_default_container_yn', $form_values['default_container_yn']);
variable_set('forum_default_container', $form_values['default_container']);
variable_set('forum_allow_public', $form_values['allow_public']);
variable_set('forum_auto_public', $form_values['auto_public']);
variable_set('forum_all_public', $form_values['all_public']);
variable_set('forum_limit', $form_values['limit_forums']);
}
} // function og_forum_settings_submit()
/**
* using the tid, set the group context
*/
function og_forum_set_og_group_context_from_tid($tid=0) {
$sql = "SELECT nid FROM {og_term} WHERE tid = %d";
if ($gid = db_result(db_query($sql, $tid))) {
$group_node = node_load($gid);
og_set_group_context($group_node);
}
} // function og_forum_set_og_group_context_from_tid()
/**
* using the tid, get the group id
*/
function og_forum_gid_from_tid($tid=0) {
$sql = "SELECT nid FROM {og_term} WHERE tid = %d";
if ($gid = db_result(db_query($sql, $tid))) {
return $gid;
}
else {
return 0;
}
} // function og_forum_gid_from_tid()
/**
* Implementation of hook_db_rewrite_sql().
*
* Restricts forum viewing by organic group.
*
* How this works:
* First, each small part-
* The forums in groups OTHER users belong to: SELECT DISTINCT ogt.tid FROM og_term ogt INNER JOIN og_uid ogu ON ogt.nid = ogu.nid AND ogu.uid != $user->uid;
* The forums in groups USER belongs to: SELECT DISTINCT ogt.tid FROM og_term ogt INNER JOIN og_uid ogu ON ogt.nid = ogu.nid AND ogu.uid = $user->uid;
* The forums in groups user belongs to, but is INACTIVE: SELECT DISTINCT ogt.tid FROM og_term ogt INNER JOIN og_uid ogu ON ogt.nid = ogu.nid AND ogu.uid = $user->uid WHERE ogu.is_active = 0;
*
* Put the first two together-
* The forums in groups the user DOES NOT belong to.
* SELECT x.tid FROM (SELECT DISTINCT ogt.tid FROM og_term ogt INNER JOIN og_uid ogu ON ogt.nid = ogu.nid AND ogu.uid != $user->uid) x
* WHERE x.tid NOT IN (SELECT DISTINCT ogt.tid FROM og_term ogt INNER JOIN og_uid ogu ON ogt.nid = ogu.nid AND ogu.uid = $user->uid));
*
* Put it all together and you can read it like this: WHERE t.tid NOT IN (The forums in groups the user DOES NOT belong to)
* AND t.tid NOT IN (The forums in groups user belongs to, but is INACTIVE)
*
* This should show all forums for which the user is a group member as well as those forums in the site-wide forums.
*/
function og_forum_db_rewrite_sql($query, $primary_table = 'n', $primary_field = 'nid') {
global $user;
$restrict = FALSE;
$restrict2 = FALSE;
if (module_exists('og_user_roles')) {
$gidx = $_GET['gids'];
$typex = $_GET['type'];
$tidx = $_GET['tid'];
}
else {
$gidx = NULL;
$typex = NULL;
$tidx = NULL;
}
if ($primary_field == 'tid') {
// Only do this on forum nodes
if (((arg(0) == 'forum') || (arg(0) == 'og_forum') || (db_result(db_query('SELECT type FROM {node} WHERE nid = %d', arg(1))) == 'forum')) && ($user->uid != 1) && !(user_access('administer forums'))) {
$restrict = TRUE;
}
elseif ((arg(0) == 'node' && arg(1) == 'add' && arg(2) == 'forum' && arg(3)) && ($user->uid != 1) && !(user_access('administer forums'))) {
$restrict = TRUE;
$restrict2 = TRUE;
}
elseif ((arg(0) == 'node' && arg(1) == 'add' && arg(2) == 'forum') && ($user->uid != 1) && !(user_access('administer forums'))) {
$restrict = TRUE;
}
elseif ((arg(0) == 'node' && arg(1) == 'ognodeadd' && $typex == 'forum' && $tidx != NULL) && ($user->uid != 1) && !(user_access('administer forums'))) {//for og_user_roles compatibility
$restrict = TRUE;
$restrict2 = TRUE;
}
elseif ((arg(0) == 'node' && arg(1) == 'ognodeadd' && $typex == 'forum') && ($user->uid != 1) && !(user_access('administer forums'))) {//for og_user_roles compatibility
$restrict = TRUE;
}
// If on a forum node, prevent display of all forums; only the ones for this organic group
// The forum vocab should have a lower weight than any other vocabulary assigned to forum nodes.
static $og_vocab = FALSE;
$all_public = variable_get('forum_all_public', 0);
if ($restrict && $user->uid != 0 && !$all_public) {
//This query and the one below are what makes regular forums work side by side with og forums.
//Esentially, instead of sequentially restricting our selection based on whether the forum is in an organic group,
//we find which organic group forums we don't want to show and remove them from the site-wide forum list.
//What remains are all regular forums, plus those the user is subscribed to in each group and which is_active is set to 1.
$return['where'] = 't.tid NOT IN (SELECT x.tid FROM (SELECT DISTINCT(ogt.tid) FROM {og_term} ogt INNER JOIN {og_uid} ogu ON ogt.nid = ogu.nid AND ogu.uid != ' .$user->uid. ' AND ogt.public < 2) x
WHERE x.tid NOT IN (SELECT DISTINCT(ogt.tid) FROM {og_term} ogt INNER JOIN {og_uid} ogu ON ogt.nid = ogu.nid AND (ogt.public > 1 OR ogu.uid = ' .$user->uid. ')))
AND t.tid NOT IN (SELECT DISTINCT(ogt.tid) FROM {og_term} ogt INNER JOIN {og_uid} ogu ON ogt.nid = ogu.nid AND ogu.uid = ' .$user->uid. ' WHERE ogu.is_active = 0)';
if ($restrict2) {
$og_nid = og_forum_gid_from_tid(arg(3));
if ($og_nid && !$og_vocab) {
$og_vocab = TRUE;
//Same as above, except without removing is_active == 0 forums since we are looking for a particular node.
//Need to put the join in here since we need to match ogt.nid
//TODO do I need to add the ogt.public checks here or not?
$return['join'] = "LEFT JOIN {og_term} ogt ON " .$primary_table. ".tid = ogt.tid";
$return['where'] = "t.tid NOT IN (SELECT x.tid FROM
(SELECT DISTINCT(ogt.tid) FROM {og_term} ogt INNER JOIN {og_uid} ogu ON ogt.nid = ogu.nid AND ogu.uid != ' .$user->uid. ') x
WHERE x.tid NOT IN (SELECT DISTINCT(ogt.tid) FROM {og_term} ogt INNER JOIN {og_uid} ogu ON ogt.nid = ogu.nid AND ogu.uid = ' .$user->uid. '))
AND ogt.nid = $og_nid";
}
}
$return['distinct'] = TRUE;
return $return;
}
elseif ($restrict && !$all_public){
//anonymous users should be able to at least see the site-wide and other public forums
$return['where'] = 't.tid NOT IN (SELECT DISTINCT ogt.tid FROM {og_term} ogt WHERE public < 2)';
//we shouldn't need to modify anything further if they request a specific node from a forum that is in
//a group forum as the above 'where' should weed it out; i.e. don't need 'join' in a $restrict2 'if'
$return['distinct'] = TRUE;
return $return;
}
else {
$og_vocab = FALSE;
return;
}
}
} // function og_forum_db_rewrite_sql()
/**
* Implementation of hook_nodeapi().
*
* Automatically creates a forum container and forum each time an organic group is added.
*/
function og_forum_nodeapi($node, $op, $teaser = NULL, $page = NULL) {
switch ($op) {
case 'load':
if ($node->type == 'forum' && $og_forum_nid = db_result(db_query('SELECT nid FROM {og_term} WHERE tid = %d', $node->tid))) {
$node->og_forum_nid = $og_forum_nid;
}
break;
case 'prepare':
if (module_exists('og_user_roles')) {
$gidx = $_GET['gids'];
$typex = $_GET['type'];
$tidx = $_GET['tid'];
}
else {
$gidx = NULL;
$typex = NULL;
$tidx = NULL;
}
if (arg(0) == 'node' && arg(1) == 'add' && arg(2) == 'forum' && arg(3)) {
if (!og_get_group_context()) {
og_forum_set_og_group_context_from_tid(arg(3));
//return FALSE;
}
}
elseif (arg(0) == 'node' && arg(1) == 'ognodeadd' && $typex == 'forum' && $tidx != NULL) {//for og_user_roles compatibility
if (!og_get_group_context()) {
og_forum_set_og_group_context_from_tid($tidx);
//return FALSE;
}
}
break;
case 'insert':
if (og_is_group_type($node->type)) {
$default_container_yn = variable_get('forum_default_container_yn', FALSE);
if ($default_container_yn) {
$edit = array('name' => $node->title, 'vid' => _forum_get_vid());
$default_container = variable_get('forum_default_container', 0);
$edit['parent'] = array($default_container);
unset($edit['tid']);
$status = taxonomy_save_term($edit);
db_query('INSERT INTO {og_term} (tid, nid) VALUES (%d, %d)', $edit['tid'], $node->nid);
}
else {
//Added Functionality to allow for the creation of multiple forums/containers
//when a new group is created. To use, change the default forum name
//in OG_Forum administation to a semicolon seperated list
//e.g. Forum1;Forum2;Forum
//Use C for new container, P for the previous container, R to return to the root container
//e.g. Forum1;C;Container2;Forum2;C;Container3;Forum3;R;Forum4 would give the structure
// Group Container
// Forum1
// Container2
// ..Forum2
// ..Container3
// ....Forum3
// Forum4
// NOTE: Weights are used to keep the ordering correct
// 2-19-2008 Josh Cohen
// Updated 3-13-2008 - Added ability to use descriptions. Follow the container or
// forum number by a comma, then decription. e.g. Forum3, This is a description;Forum4
//
//Setup Main Container
$edit = array('name' => $node->title, 'vid' => _forum_get_vid());
$status = taxonomy_save_term($edit);
$containers = variable_get('forum_containers', array());
$containers[] = $edit['tid'];
variable_set('forum_containers', $containers);
db_query('INSERT INTO {og_term} (tid, nid) VALUES (%d, %d)', $edit['tid'], $node->nid);
///Start Multiple Forum Code Change
// 2-19-2008 Josh Cohen
$curr_container = $edit['tid'];
$root_container = $curr_container;
unset($edit['tid']); //taxonomy_save_term will give us new tids
$default_forum_names = variable_get('forum_default_name', 'General discussion');
$forum_names = explode(";",$default_forum_names); //return default forum names as an array
$is_container = 0;
$c_order = array($root_container); //To keep track of the container sequence
$weight_indx = -10;
foreach ($forum_names as $fvalue){
switch(strtoupper($fvalue)){
case('C'): //Create New Container
$is_container = 1;
break;
case('P'): //Go to previous container
//Delete current container
if (end($c_order) != $root_container){
array_pop($c_order);
}
//Set current container
$curr_container = end($c_order);
$is_container = 0;
break;
case('R'): //Go to the root container
unset($c_order);
$c_order = array($root_container);
$curr_container = $root_container;
$is_container = 0;
break;
default:
if ($is_container == '1'){
//Add New Container
$forum_names = explode(",",$fvalue); //Break out Name and Description
if (count($forum_names) == 2){
$fname = $forum_names[0];
$fdesc = $forum_names[1];
}else{
$fname = $forum_names[0];
unset($fdesc);
}
$edit = array('name' => $fname, 'vid' => _forum_get_vid(), 'parent' => $curr_container, 'weight' => $weight_indx, 'description' => $fdesc);
$status = taxonomy_save_term($edit);
$containers = variable_get('forum_containers', array());
$containers[] = $edit['tid'];
variable_set('forum_containers', $containers);
$curr_container = $edit['tid'];
$c_order[] = $edit['tid']; //Add the new container to our index
unset($edit['tid']);
unset($edit['parent']);
$is_container = 0;
$weight_indx = $weight_indx + 1;
}
else {
//Add New Forum
$forum_names = explode(",",$fvalue); //Break out Name and Description
if (count($forum_names) == 2){
$fname = $forum_names[0];
$fdesc = $forum_names[1];
}else{
$fname = $forum_names[0];
unset($fdesc);
}
$edit['name'] = $fname;
$edit['description'] = $fdesc;
$edit['parent'] = $curr_container;
$edit['weight'] = $weight_indx;
$status = taxonomy_save_term($edit);
unset($edit['tid']); //Clear term so Taxonomy_save_term will generate a new term on next iteration
$is_container = 0;
$weight_indx = $weight_indx + 1;
}
break;
} //End Switch
}
unset($forum_names); //clean up variables
unset($c_order);
//End Multiple Forum Code Change
//2-19-2008 Josh Cohen
}
}
elseif ($node->type == 'forum') {//if the node is marked public, check the 'puclicity' settings and act accordingly
//setup variables for common operations
$sql = "SELECT tid, public FROM {og_term} WHERE nid = %d";
$container = og_forum_get_forum_container($node->og_groups[0]);
$gid = og_forum_gid_from_tid($node->tid);
$results = db_query($sql, $gid);
while ($result = db_fetch_object($results)) {
$forums[$result->tid] = $result->public;
}
$sql2 = "UPDATE {og_term} SET public = %d WHERE tid = %d";
//can we set the forum to public
if ($node->og_public == PRIVATE_BY_GROUP_OWNER) {
if ($forums[$node->tid] == PRIVATE_DEFAULT && $forums[$container] != PRIVATE_BY_GROUP_OWNER) {//the container isn't locked at private by group owner, and the forum is in an auto-settable state
db_query($sql2, PUBLIC_AUTO, $node->tid);
if ($forums[$container] == PRIVATE_DEFAULT) {
db_query($sql2, PUBLIC_AUTO, $container);
}
}
}
//can we set the forum private
elseif ($node->og_public == PRIVATE_DEFAULT) {
if ($forums[$node->tid] == PUBLIC_AUTO) {//the forum is in an auto settable state
$should_be_public = FALSE;
$sql3 = "SELECT DISTINCT oa.nid FROM {node} n INNER JOIN {og_ancestry} oa ON oa.nid = n.nid INNER JOIN {term_node} tn ON tn.nid = oa.nid
WHERE n.type = 'forum' AND oa.is_public = 1 AND tn.tid = %d";
if (!$count = db_num_rows(db_query($sql3, $node->tid))) {
db_query($sql2, PRIVATE_DEFAULT, $node->tid);
foreach ($forums as $tid => $public) {
if ($count = db_num_rows(db_query($sql3, $tid))) {
$should_be_public = TRUE;
}
}
if (!$should_be_public && $forums[$container] == PUBLIC_AUTO) {//all forums' posts are private in this container and the container is in an auto-settable state
db_query($sql2, PRIVATE_DEFAULT, $container);
}
}
}
}
}
break;
case 'update':
//Make sure if the group's title has changed, the title of it's root forum is updated as well.
if (og_is_group_type($node->type)) {
$tid = db_result(db_query('SELECT tid FROM {og_term} WHERE nid = %d', $node->nid));
if ($tid) {
$term = taxonomy_get_term($tid);
$term->parents = taxonomy_get_parents($tid);
$term->parent = array_keys($term->parents);
$term->name = $node->title;
$term = (array)$term;
$parents = taxonomy_get_parents($tid);
foreach ($parents as $parent) {
$pid[] = $parent->tid;
}
$term['parent'] = $pid;
taxonomy_save_term($term); //will have any other modules update the term's URL aliases
}
}
elseif ($node->type == 'forum') {//if the node is marked public, check the 'puclicity' settings and act accordingly
//setup variables for common operations
$sql = "SELECT tid, public FROM {og_term} WHERE nid = %d";
$container = og_forum_get_forum_container($node->og_groups[0]);
$gid = og_forum_gid_from_tid($node->tid);
$results = db_query($sql, $gid);
while ($result = db_fetch_object($results)) {
$forums[$result->tid] = $result->public;
}
$sql2 = "UPDATE {og_term} SET public = %d WHERE tid = %d";
//can we set the forum to public
if ($node->og_public == 1) {
if ($forums[$node->tid] == PRIVATE_DEFAULT && $forums[$container] != PRIVATE_BY_GROUP_OWNER) {//the container isn't locked at private by group owner, and the forum is in an auto-settable state
db_query($sql2, PUBLIC_AUTO, $node->tid);
if ($forums[$container] == PRIVATE_DEFAULT) {
db_query($sql2, PUBLIC_AUTO, $container);
}
}
}
//can we set the forum private
elseif ($node->og_public == 0) {
if ($forums[$node->tid] == PUBLIC_AUTO) {//the forum is in an auto settable state
$should_be_public = FALSE;
$sql3 = "SELECT DISTINCT oa.nid FROM {node} n INNER JOIN {og_ancestry} oa ON oa.nid = n.nid INNER JOIN {term_node} tn ON tn.nid = oa.nid
WHERE n.type = 'forum' AND oa.is_public = 1 AND tn.tid = %d";
if (!$count = db_num_rows(db_query($sql3, $node->tid))) {
db_query($sql2, PRIVATE_DEFAULT, $node->tid);
foreach ($forums as $tid => $public) {
if ($count = db_num_rows(db_query($sql3, $tid))) {
$should_be_public = TRUE;
}
}
if (!$should_be_public && $forums[$container] == PUBLIC_AUTO) {//all forums' posts are private in this container and the container is in an auto-settable state
db_query($sql2, PRIVATE_DEFAULT, $container);
}
}
}
}
}
break;
case 'delete':
// Delete existing terms for this og
if (og_is_group_type($node->type)) {
$result = db_query('SELECT tid FROM {og_term} WHERE nid = %d', $node->nid);
while ($term = db_fetch_object($result)) {
taxonomy_del_term($term->tid);
}
db_query('DELETE FROM {og_term} WHERE nid = %d', $node->nid);
}
break;
case 'view':
// Don't do anything when handling teasers
if ($teaser) {
break;
}
// If we're viewing a forum post in a group forum, set that
// group as the context.
if ($page && $node->og_groups && $node->type == 'forum') {
og_set_group_context(node_load($node->og_groups[0]));
if (is_numeric($node->tid)) {
$tid = $node->tid;
}
$parents = taxonomy_get_parents_all($tid);
// Breadcrumb navigation:
global $_menu;
if (isset($_menu)) {
$breadcrumb = array();
$breadcrumb[] = array('path' => "og", 'title' => t('Groups'));
$breadcrumb[] = array('path' => "node/". $node->og_groups[0], 'title' => $node->og_groups_names[0]);
if ($tid) {
$breadcrumb[] = array('path' => 'forum', 'title' => $title);
}
if ($parents) {
$parents = array_reverse($parents);
foreach ($parents as $p) {
$breadcrumb[] = array('path' => 'forum/' .$p->tid, 'title' => $p->name);
}
}
$breadcrumb[] = array('path' => "node/$node->nid", 'title' => $node->title);
$breadcrumb[] = array('path' => $_GET['q']);
menu_set_location($breadcrumb);
}
drupal_set_title(check_plain($node->title));
break;
}
case 'submit':
if ($node->type == 'forum') {
$gid = og_forum_gid_from_tid($node->tid);
$node->og_groups = array();
$node->og_groups[$gid] = $gid;
$node->og_groups = array_filter($node->og_groups);
$node->og_groups = array_keys($node->og_groups);
}
}
} // function og_forum_nodeapi()
/**
* Retrieve container for given group
*
* @param $group_id
* Organic group ID
* @return
* Forum container's term ID
*/
function og_forum_get_forum_container($group_id) {
// If it exists, grab the first term created for group; this will be the forum container; if not, it is a forum inside a generic container; find it
return db_result(db_query_range('SELECT tid FROM {og_term} WHERE nid = %d ORDER BY tid ASC', $group_id, 0, 1));
} // function og_forum_get_forum_container()
/**
* Check if a user is a group manager of the given group
*/
function og_forum_is_admin($group) {
global $user;
$result = db_query(og_list_users_sql(0), $group->nid);
$cntall = db_num_rows($result);
$cntpending = 0;
while ($row = db_fetch_object($result)) {
if ($user->uid == 1 && user_access('administer forums')) return TRUE;
if ($row->uid == $user->uid) {
if ($row->is_admin > 0) return TRUE;
}
}
return FALSE;
} // function og_forum_is_admin()
/**
* Implementation of hook_og_create_links().
*/
function og_forum_og_create_links($group) {
global $user;
$links = array();
// Get group's forum
$forum = og_forum_get_forum_container($group->nid);
if ($forum) {
$links[] = l(t('Group forums'), "forum/$forum", array('title' => t('View group forum discussions.')));
// Add forum creation link for the group managers
if ((og_forum_is_admin($group) && user_access('admin own group forums')) || user_access('administer forums')) {
$links[] = l(t('Manage group forums'), 'og_forum/manage/' . $group->nid, array('title' => t('Let you create, edit, delete group\'s forums.')));
}
}
return $links;
} // function og_forum_og_create_links()
/**
* Creates forums for all groups that don't have any yet.
*/
function og_forum_retroactively_apply() {
$counter = 0;
// Obtain list of all groups
$result = db_query('SELECT og.nid, n.title, n.type FROM {og} og INNER JOIN {node} n on og.nid = n.nid');
while ($group = db_fetch_object($result)) {
// See if terms are found for this group
if (!db_result(db_query('SELECT * FROM {og_term} ogt WHERE ogt.nid = %d', $group->nid))) {
// If not, fake a nodeapi insert
og_forum_nodeapi($group, 'insert');
$counter++;
}
}
drupal_set_message(t('%num groups had forums created', array('%num' => $counter)));
} // function og_forum_retroactively_apply()
/**
* Implementation of hook_form_alter().
*/
function og_forum_form_alter($form_id, &$form) {
// Auto-select group's forum when adding/editing a forum topic
if ($form_id == 'forum_node_form') {
$group = og_get_group_context();
//if we couldn't get the context from og, don't give up. Try getting it from the nid if we have one.
if (empty($group)) {
if (arg(0) == 'node' && arg(2) == 'edit' && is_numeric(arg(1))) {
$sql = "SELECT tid FROM {forum} WHERE nid = %d";
$result = db_fetch_object(db_query($sql, arg(1)));
og_forum_set_og_group_context_from_tid($result->tid);
$group = og_get_group_context();
}
}
$GID = $group->nid;
if ($GID) {
$results = db_query('SELECT ot.tid, th.parent FROM {og_term} ot LEFT JOIN {term_hierarchy} th ON ot.tid = th.tid WHERE nid = %d ORDER BY tid ASC', $GID);
while ($result = db_fetch_object($results)) {
$all_results[$result->tid] = $result->parent;
}
$vid = _forum_get_vid();
//set the forum selection drop down box
if (arg(1) == 'add' && arg(3)) {
$term = arg(3);
$form['taxonomy'][$vid]['#default_value'] = array($term);
}
elseif (arg(2) == 'edit') {
$term = $form['taxonomy'][$vid]['#default_value'][0];
$groups = $form['og_nodeapi']['visible']['og_groups'];
$form['og_nodeapi']['invisible']['og_groups'] = array('#type' => 'value', '#value' => $groups);
unset($form['og_nodeapi']['visible']['og_groups']);
}
elseif (arg(1) == 'ognodeadd') {//for og_user_roles compatibility
$term = $_GET['tid'];
$form['taxonomy'][$vid]['#default_value'] = array($term);
}
elseif (arg(1) == 'add' && !arg(3)) {
$first = reset($all_results);
if ($first == 0) {
$next = next($all_results);
$term = key($all_results);
$form['taxonomy'][$vid]['#default_value'] = array($term);
}
else {
$term = key($all_results);
$form['taxonomy'][$vid]['#default_value'] = array($term);
}
}
if (!user_access('administer forums')) {
foreach ($form['taxonomy'][$vid]['#options'] as $key => $the_rest) {
if ($key === '') {
continue;
}
reset($the_rest->option);
$option_key = key($the_rest->option);
if (is_array($all_results) && !array_key_exists($option_key, $all_results)) {
unset($form['taxonomy'][$vid]['#options'][$key]);
}
} //check to see if the audience is required or optional. if optional, don't do the following two lines
if (variable_get('og_audience_required', FALSE) == 1) {
if (count($form['og_nodeapi']['visible']['og_groups']['#default_value'])) {
drupal_add_js(drupal_get_path('module', 'og_forum'). '/og_forum.js');
$options = $form['og_nodeapi']['visible']['og_groups']['#options'];
$groups = $form['og_nodeapi']['visible']['og_groups']['#default_value'];
foreach ($groups as $key => $value) {
$groups[$key] = (string)$value;
}
unset($form['og_nodeapi']['visible']['og_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), '#attributes' => array('class' => 'og-audience-forum'));
// this 'value' element persists the audience value during submit process
$form['og_nodeapi']['invisible']['og_groups'] = array('#type' => 'value', '#value' => $assoc_groups);
if ($form['og_nodeapi']['visible']['og_public']['#default_value'] == 1) {
$form['og_nodeapi']['visible']['og_public']['#default_value'] = 1;
}
else {
$form['og_nodeapi']['visible']['og_public']['#default_value'] = 0;
}
}
}
}
}
else {
$results = db_query('SELECT ot.tid, th.parent FROM {og_term} ot LEFT JOIN {term_hierarchy} th ON ot.tid = th.tid ORDER BY tid ASC');
while ($result = db_fetch_object($results)) {
$all_results[$result->tid] = $result->parent;
}
$vid = _forum_get_vid();
$cut = FALSE;
if (arg(1) == 'add' && arg(3)) {
$cut = TRUE;
$term = arg(3);
$form['taxonomy'][$vid]['#default_value'] = array($term);
}
elseif (arg(2) == 'edit') {
$cut = TRUE;
$term = $form['taxonomy'][$vid]['#default_value'][0];
}
elseif (arg(1) == 'ognodeadd') {//for og_user_roles compatibility
$cut = TRUE;
$term = $_GET['tid'];
$form['taxonomy'][$vid]['#default_value'] = array($term);
}
if (!user_access('administer forums') && $cut) {
foreach ($form['taxonomy'][$vid]['#options'] as $key => $the_rest) {
if ($key == '') {
continue;
}
reset($the_rest->option);
$option_key = key($the_rest->option);
if (is_array($all_results) && array_key_exists($option_key, $all_results)) {
unset($form['taxonomy'][$vid]['#options'][$key]);
}
}
}
}
//$groups = $form['og_nodeapi']['visible']['og_groups'];
//$form['og_nodeapi']['invisible']['og_groups'] = array('#type' => 'value', '#value' => $groups);
//unset($form['og_nodeapi']['visible']['og_groups']);
$form['taxonomy']['#collapsible'] = TRUE;
$form['taxonomy']['#collapsed'] = TRUE;
}
if ($form_id == 'forum_form_container') {
$allow_public = variable_get('forum_allow_public', 0);
if (($allow_public && (user_access('make forums public')) || user_access('administer forums'))) {
$form['make_public'] = array(
'#type' => 'checkbox',
'#title' => t('Make container public'),
'#description' => t('This will allow all users to view this container. Only forums within this container that are also marked public will be visible to anonymous users.'),
'#default_value' => FALSE,
'#weight' => 0.004,
'#access' => 0,
);
}
}
if ($form_id == 'forum_form_forum') {
$allow_public = variable_get('forum_allow_public', 0);
if (($allow_public && (user_access('make forums public')) || user_access('administer forums'))) {
$form['make_public'] = array(
'#type' => 'checkbox',
'#title' => t('Make forum public'),
'#description' => t('This will allow all users to view this forum. The parent container must also be public to browse here. Otherwise users will need a direct link to this forum.'),
'#default_value' => FALSE,
'#weight' => 0.004,
'#access' => 0,
);
}
}
} // function og_forum_form_alter()
/**
* Let group managers manage their forums
*/
function og_forum_manage($group) {
global $user;
$allow_public = variable_get('forum_allow_public', 0);
og_set_theme($group->nid);
og_set_group_context($group);
// set a nice breadcrumb
_og_forum_manage_breadcrumb($group);
$content = '' .t('This page shows the forums associated with the %group group.', array('%group' => $group->title)). '
';
$og_terms = _og_forum_ogterms($group);
$forum_limit_reached = og_forum_forum_limit_reached($group->nid);
$header = array(t('Name'), t('Operations'));
$sql = "SELECT public, tid FROM {og_term} WHERE nid = %d";
$results = db_query($sql, $group->nid);
$all_tids = array();
while ($result = db_fetch_object($results)) {
$all_tids[$result->tid] = $result->public;
}
$tree = taxonomy_get_tree(_forum_get_vid());
if ($tree) {
foreach ($tree as $term) {
if (in_array($term->tid, $og_terms)) {
if (in_array($term->tid, variable_get('forum_containers', array()))) {//we're looking at a container
if ($forum_limit_reached && !(user_access('administer forums'))) {//the limit for the number of forums allowed was reached
$rows[] = array(array('data' => t('You have reached the maximum allowed number of forums for groups.'), 'colspan' => '3'));
$rows[] = array(str_repeat('-', $term->depth). ' ' .check_plain($term->name), array('data' => '', 'colspan' => '3'));
}
else {//the limit on the number of forums has not been reached, or there is no limit
$rows[] = array(str_repeat('-', $term->depth). ' ' .check_plain($term->name), array('data' => l(t('add forum'), "og_forum/manage/add/$group->nid/$term->tid"), 'colspan' => '3'));
}
}
else {//we're looking at a forum, not a container
if ((user_access('make forums public') || $allow_public) && $all_tids[$term->tid] < PUBLIC_AUTO) {//it's presently private
$rows[] = array(str_repeat('-', $term->depth). ' ' .check_plain($term->name), l(t('edit forum'), "og_forum/manage/edit/$group->nid/$term->tid"), l(t('make public'), "og_forum/manage/public/$group->nid/$term->tid"), l(t('reset publicity'), "og_forum/manage/reset/$group->nid/$term->tid"));
}
elseif ((user_access('make forums public') || $allow_public) && $all_tids[$term->tid] > PRIVATE_BY_GROUP_OWNER) {//it's presently public
$rows[] = array(str_repeat('-', $term->depth). ' ' .check_plain($term->name), l(t('edit forum'), "og_forum/manage/edit/$group->nid/$term->tid"), l(t('make private'), "og_forum/manage/private/$group->nid/$term->tid"), l(t('reset publicity'), "og_forum/manage/reset/$group->nid/$term->tid"));
}
else {
$rows[] = array(str_repeat('-', $term->depth). ' ' .check_plain($term->name), l(t('edit forum'), "og_forum/manage/edit/$group->nid/$term->tid"));
}
}
}
}
}
return $content . theme('table', $header, $rows);
} // function og_forum_manage()
/**
* Select the right form to display
*/
function og_forum_form_main($type, $edit = array()) {
if ($_POST['op'] == t('Delete') || $_POST['confirm']) {
return drupal_get_form('og_forum_confirm_delete', $edit['tid'], $group_id);
}
switch ($type) {
case 'add':
$group_id = $edit['group_id'];
return drupal_get_form('og_forum_form_forum', $edit, $group_id, $edit['tid']);
case 'edit':
$group_id = $edit['group_id'];
return drupal_get_form('og_forum_form_forum', $edit, $group_id);
}
} // function og_forum_form_main(
/**
* Render forum creation form
*/
function og_forum_form_forum($edit, $group_id = 0, $tid = 0) {
og_set_theme($gid);
if (!$edit['tid']) {
$tid = $edit['parent'];
}
$form['name'] = array('#type' => 'textfield',
'#title' => t('Forum name'),
'#default_value' => $edit['name'],
'#maxlength' => 64,
'#description' => t('The forum name is used to identify related discussions.'),
'#required' => TRUE,
);
$form['description'] = array('#type' => 'textarea',
'#title' => t('Description'),
'#default_value' => $edit['description'],
'#description' => t('The forum description can give users more information about the discussion topics it contains.'),
);
if (arg(2) == 'add') {
_og_forum_manage_breadcrumb(node_load($group_id), 'add');
$form['parent'] = array(
'#type' => 'hidden',
'#value' => $tid,
);
}
else {
_og_forum_manage_breadcrumb(node_load($group_id), 'edit');
$form['parent'] = array(
'#type' => 'hidden',
'#value' => $edit['parent'],
);
}
$form['group_id'] = array(
'#type' => 'hidden',
'#value' => $group_id,
);
$form['weight'] = array('#type' => 'weight',
'#title' => t('Weight'),
'#default_value' => $edit['weight'],
'#description' => t('When listing forums, those with lighter (smaller) weights get listed before containers with heavier (larger) weights. Forums with equal weights are sorted alphabetically.'),
);
$allow_public = variable_get('forum_allow_public', 0);
if (($allow_public && (user_access('make forums public')) || user_access('administer forums'))) {
$form['make_public'] = array(
'#type' => 'checkbox',
'#title' => t('Make forum public'),
'#description' => t('This will allow non-group members to view this forum.'),
'#default_value' => FALSE,
'#access' => 0,
);
}
$form['vid'] = array('#type' => 'hidden', '#value' => _forum_get_vid());
$form['submit' ] = array('#type' => 'submit', '#value' => t('Submit'));
if ($edit['tid']) {
$form['delete'] = array('#type' => 'submit', '#value' => t('Delete'));
$form['tid'] = array('#type' => 'hidden', '#value' => $edit['tid']);
}
$form['#base'] = 'og_forum_form';
return $form;
} // function og_forum_form_forum()
/**
* Validate group id and term id values
*/
function og_forum_form_validate($form_id, $form_values) {
global $user;
$error = true;
if (is_numeric($form_values['group_id'])) {
$group = node_load($form_values['group_id']);
// check that the user is the manager
if ($group && og_forum_is_admin($group) && (in_array($form_values['parent'], _og_forum_ogterms($group)) || $form_values['tid'])) {
$error = false;
}
}
// stop insertion if we found invalid values
if ($error) {
form_set_error('name', t('Internal error processing your data. Please contact website administrators.'));
}
} // function og_forum_form_validate()
/**
* Store created/updated forum on the db
*/
function og_forum_form_submit($form_id, $form_values) {
$container = false;
$type = t('forum');
$status = taxonomy_save_term($form_values);
switch ($status) {
case SAVED_NEW:
if ($container) {
$containers = variable_get('forum_containers', array());
$containers[] = $form_values['tid'];
variable_set('forum_containers', $containers);
}
drupal_set_message(t('Created new !type %term.', array('%term' => $form_values['name'], '!type' => $type)));
break;
case SAVED_UPDATED:
drupal_set_message(t('The !type %term has been updated.', array('%term' => $form_values['name'], '!type' => $type)));
break;
}
return 'og_forum/manage/' .$form_values['group_id'];
} // function og_forum_form_submit()
/**
* hook_taxonomy implementation
*
* This should replace og_forum's own management of terms which bypasses regular taxonomy. Using this function allows group
* forums to be managed both from within the group and at the site-wide forum admin pages.
*
* @param string $op
* @param string $type
* @param array $obj
*/
function og_forum_taxonomy($op, $type, $obj) {
switch ($op) {
case 'insert':
case 'update':
if (isset($obj['parent'])) {
$parent = (is_array ($obj['parent'])) ? $obj['parent'][0] : $obj['parent'];
$result = db_result(db_query("SELECT nid FROM {og_term} WHERE tid = %d", $parent));
if ($result) {
if (!db_result(db_query('SELECT tid FROM {og_term} WHERE tid = %d', $obj['tid']))) {
db_query('INSERT INTO {og_term} (tid, nid) VALUES (%d, %d)', $obj['tid'], $result);
}
}
}
break;
case 'delete':
if (isset($obj['tid'])) {
db_query("DELETE FROM {og_term} WHERE tid = %d", $obj['tid']);
}
break;
}
} // function og_forum_taxonomy()
/**
* Returns a confirmation page for deleting a forum taxonomy term.
*
* @param $tid ID of the term to be deleted
*/
function og_forum_confirm_delete($tid, $group_id) {
$term = taxonomy_get_term($tid);
$form['tid'] = array('#type' => 'value', '#value' => $tid);
$form['name'] = array('#type' => 'value', '#value' => $term->name);
$form['group_id'] = array('#type' => 'value', '#value' => $group_id);
$return_address = 'og_forum/manage/' .arg(3);
$form['return'] = array('#type' => 'value', '#value' => 'og_forum/manage/' .arg(3));
$form = confirm_form($form, t('Are you sure you want to delete the forum %name?', array('%name' => $term->name)), $return_address, t('Deleting a forum or container will delete all sub-forums and associated posts as well. This action cannot be undone.'), t('Delete'), t('Cancel'));
return $form;
} // function og_forum_confirm_delete()
/**
* Implementation of forms api _submit call. Deletes a forum after confirmation.
*/
function og_forum_confirm_delete_submit($form_id, $form_values) {
taxonomy_del_term($form_values['tid']);
$group_id = og_forum_gid_from_tid($form_values['tid']);
drupal_set_message(t('The forum %term and all sub-forums and associated posts have been deleted.', array('%term' => $form_values['name'])));
watchdog('content', t('forum: deleted %term and all its sub-forums and associated posts.', array('%term' => $form_values['name'])));
db_query('DELETE FROM {og_term} WHERE tid = %d', $form_values['tid']);
$return_address = $form_values['return'];
return $return_address;
} // function og_forum_confirm_delete_submit()
/**
* Set a nice breadcrumb for the manage pages
*/
function _og_forum_manage_breadcrumb($group, $op = NULL) {
$breadcrumb = array();
$breadcrumb[] = array(
'path' => 'forum',
'title' => $vocabulary->name
);
$breadcrumb[] = array(
'path' => 'node/' .$group->nid,
'title' => $group->title
);
switch ($op) {
case 'add':
$breadcrumb[] = array(
'path' => 'og_forum/manage/' .$group->nid,
'title' => t('Add'). ' ' .$group->title. ' ' .t('forums'),
);
break;
case 'edit':
$breadcrumb[] = array(
'path' => 'og_forum/manage' .$group->nid,
'title' => t('Edit'). ' ' .$group->title. ' ' .t('forums'),
);
break;
case 'default':
$breadcrumb[] = array(
'path' => 'og_forum/manage/' .$group->nid,
'title' => t('Manage'). ' ' .$group->title. ' ' .t('forums'),
);
break;
}
menu_set_location($breadcrumb);
} // function _og_forum_manage_breadcrumb()
/**
* get an array containing terms associated to this og
*/
function _og_forum_ogterms($group) {
$result = db_query('SELECT * FROM {og_term} WHERE nid = %d', $group->nid);
$og_terms = array();
while ($term = db_fetch_object($result)) {
$og_terms[] = $term->tid;
}
return $og_terms;
} // function _og_forum_ogterms()
/**
* Find out if the limit has been reached for group forums in a particular group
*
* @param integer $nid
* @return boolean
*/
function og_forum_forum_limit_reached($nid) {
$forum_limit = variable_get('forum_limit', 0);
if ($forum_limit == 0) return FALSE;
$sql = "SELECT DISTINCT tid FROM {og_term} WHERE nid = %d";
$result = db_query($sql, $nid);
$num = db_num_rows($result);
$num_forums = $num - 1; //because the container is part of the query result
if ($num_forums >= $forum_limit) {
return TRUE;
}
else {
return FALSE;
}
} // function og_forum_forum_limit_reached()
/**
* Set a forum as public, and its container as well
*
* @param int $gid The group id of the forum.
* @param int $tid The term id of the forum.
*/
function og_forum_public($gid, $tid) {
$container = og_forum_get_forum_container($gid);
$sql = "UPDATE {og_term} SET public = %d WHERE tid = %d and nid = %d";
db_query($sql, PUBLIC_BY_GROUP_OWNER, $tid, $gid);
db_query($sql, PUBLIC_BY_GROUP_OWNER, $container, $gid);
return drupal_goto('og_forum/manage/'. $gid);
} // function og_forum_public()
/**
* Set forum as private, and its container if no other forums in it are public
*
* @param int $gid
* @param int $tid
*/
function og_forum_private($gid, $tid) {
$container = og_forum_get_forum_container($gid);
$sql = "UPDATE {og_term} SET public = %d WHERE tid = %d and nid = %d";
db_query($sql, PRIVATE_BY_GROUP_OWNER, $tid, $gid);
$sql2 = "SELECT tid FROM {og_term} WHERE nid = %d AND tid <> %d AND public > 1";
$results = db_query($sql2, $gid, $container);//find out if any other forums are public
$result = db_num_rows($results);
if (!$result) {//if no other forums in the group are public, go ahead and make the container private
db_query($sql, PRIVATE_DEFAULT, $container, $gid);
}
return drupal_goto('og_forum/manage/'. $gid);
} // function og_forum_private()
/**
* Reset forum to default of PRIVATE_DEFAULT, and its container if no other forums in it are public
*
* @param int $gid
* @param int $tid
*/
function og_forum_reset($gid, $tid) {
$container = og_forum_get_forum_container($gid);
$sql = "UPDATE {og_term} SET public = %d WHERE tid = %d and nid = %d";
db_query($sql, PRIVATE_DEFAULT, $tid, $gid);
$sql2 = "SELECT tid FROM {og_term} WHERE nid = %d AND tid <> %d AND public > 1";
$results = db_query($sql2, $gid, $container);//find out if any other forums are public
$result = db_num_rows($results);
if (!$result) {//if no other forums in the group are public, go ahead and make the container private
db_query($sql, PRIVATE_DEFAULT, $container, $gid);
}
return drupal_goto('og_forum/manage/'. $gid);
} // function og_forum_reset()
/**
* Test whether a tid (forum or container) is public and return results.
*
* @param integer $tid
* @return boolean
*/
function og_forum_is_public($tid) {
$all_public = variable_get('forum_all_public', 0);
$sql = "SELECT tid, public, nid FROM {og_term} WHERE tid = %d";
$results = db_fetch_object(db_query($sql, $tid));
if (($results->public > PRIVATE_BY_GROUP_OWNER) || ($all_public)) {//I think this was too restrictive at using: ($results->public == 0 && $all_public)
return 1;
}
else {
return 0;
}
} // function og_forum_is_public()