'forum', 'title' => t('Forums'), 'callback' => 'advanced_forum_page', 'access' => user_access('access content'), 'type' => MENU_SUGGESTED_ITEM); global $user; $items[] = array( 'path' => "forum/markasread", 'title' => 'Helper page to mark forums read.', 'callback' => 'advanced_forum_markasread', 'access' => advanced_forum_markasread_access(), 'type' => MENU_CALLBACK, ); // Add menu entry for settings page $items[] = array( 'path' => "admin/settings/advanced-forum", 'title' => t('Advanced Forum'), 'callback' => 'drupal_get_form', 'callback arguments' => array('advanced_forum_settings_page'), 'access' => user_access('administer advanced forum'), ); } return $items; } // SETTINGS PAGE *************************************************************/ /** * Defines the Advanced Forum settings form. */ function advanced_forum_settings_page() { /* General settings */ $form['advanced_forum_general'] = array( '#type' => 'fieldset', '#title' => t('General'), '#collapsible' => TRUE, '#collapsed' => FALSE, ); // Choose style $form['advanced_forum_general']['advanced_forum_style'] = array( '#type' => 'textfield', '#title' => t('Advanced forum style'), '#size' => 25, '#description' => t('Name of advanced forum style. Defaults to "naked" Don\'t forget to copy this style to your theme.'), '#default_value' => variable_get('advanced_forum_style', 'naked'), ); // Choose image directory $form['advanced_forum_general']['advanced_forum_image_directory'] = array( '#type' => 'textfield', '#title' => t('Image directory'), '#size' => 50, '#description' => t('Images are assumed to be in the "images" subdirectory of your style. If you need images to be somewhere else, put the full path here.'), '#default_value' => variable_get('advanced_forum_image_directory', ''), ); // Use buttons for links $form['advanced_forum_general']['advanced_forum_button_links'] = array( '#type' => 'checkbox', '#title' => t('Use graphical buttons for links'), '#default_value' => variable_get('advanced_forum_button_links', 1), '#description' => t('Included buttons are in English. Uncheck this to use translatable links instead.'), ); // Theme all site comments as forums $form['advanced_forum_general']['advanced_forum_theme_all_comments'] = array( '#type' => 'checkbox', '#title' => t('Treat all site comments like forum posts'), '#default_value' => variable_get('advanced_forum_theme_all_comments', 0), '#description' => t('Choosing yes causes advanced forum to consider every comment a forum comment and attempt to theme it that way. Some changes to your theme may be required.'), ); /* Forum / topic list settings */ $form['advanced_forum_lists'] = array( '#type' => 'fieldset', '#title' => t('Forum and topic lists'), '#collapsible' => TRUE, '#collapsed' => FALSE, ); // Hide 'created' column $form['advanced_forum_lists']['advanced_forum_hide_created'] = array( '#type' => 'checkbox', '#title' => t('Hide the created column on the topic list'), '#default_value' => variable_get('advanced_forum_hide_created', 0), '#description' => t('This allows you to hide the created column on the topic list. Useful if you want to move the created by information to underneath the topic title.'), ); // Pager max $form['advanced_forum_lists']['advanced_forum_topic_pager_max'] = array( '#type' => 'textfield', '#title' => t('Maximum number of pages to show on per title pager'), '#size' => 5, '#description' => t('Used on the pager under topic titles in topic list. e.g. entering 5 will get you 1,2,3,4 ... 10'), '#default_value' => variable_get('advanced_forum_topic_pager_max', 5), ); // Retrieve new comments on forum listing $form['advanced_forum_lists']['advanced_forum_get_new_comments'] = array( '#type' => 'checkbox', '#title' => t('Get the number of new comments per forum on the forum list'), '#default_value' => variable_get('advanced_forum_get_new_comments', 0), '#description' => t('Core forum shows the number of new topics. If checked, Advanced Forum will get the number of new comments as well and show it under "posts" on the forum overview. Slow query not recommended on large forums.'), ); // Title length max $form['advanced_forum_lists']['advanced_forum_topic_title_length'] = array( '#type' => 'textfield', '#title' => t('Number of characters to display for the topic title'), '#size' => 5, '#description' => t('Used on main forum page. Enter 0 to use the full title.'), '#default_value' => variable_get('advanced_forum_topic_title_length', 15), ); // Time ago cutoff $form['advanced_forum_lists']['advanced_forum_time_ago_cutoff'] = array( '#type' => 'textfield', '#title' => t('Number of hours before switching to date posted in displays'), '#size' => 5, '#description' => t('Will show "time ago" until this cutoff and then switch to actual date posted .'), '#default_value' => variable_get('advanced_forum_time_ago_cutoff', 48), ); /* Topic settings */ $form['advanced_forum_topics'] = array( '#type' => 'fieldset', '#title' => t('Topics'), '#collapsible' => TRUE, '#collapsed' => FALSE, ); // Use topic navigation $form['advanced_forum_topics']['advanced_forum_use_topic_navigation'] = array( '#type' => 'checkbox', '#title' => t('Use topic navigation'), '#default_value' => variable_get('advanced_forum_use_topic_navigation', 0), '#description' => t('Core forum gets the next and previous topics and shows links to them under the top post. This is turned off by default as the query has performance issues and the placement of the links is poor.'), ); if (module_exists('imagecache') && function_exists('imagecache_presets')) { $options = array('' => ''); $presets = imagecache_presets(); foreach ($presets AS $preset) { $options[$preset['presetname']] = $preset['presetname']; } $form['advanced_forum_topics']['advanced_forum_user_picture_preset'] = array( '#type' => 'select', '#title' => t('User picture preset'), '#options' => $options, '#description' => t('Imagecache preset to use for forum avatars. Leave blank to not use this feature.'), '#default_value' => variable_get('advanced_forum_user_picture_preset', ''), ); } // Send our form to Drupal to make a settings page return system_settings_form($form); } // THEME TO PREPROCESS CONVERTER *********************************************/ /** * Provides D5 compatability wrapper for node/comment preprocess functions. */ function advanced_forum_addvars($hook, $variables) { switch ($hook) { case 'node': case 'comment': advanced_forum_call_preprocess($hook, $variables); } return $variables; } // Add in the D6 backports from the forum, taxonomy, and comment modules include_once drupal_get_path('module', 'advanced_forum') .'/d6_compat.inc'; /** * Implementation of theme_forum_display(). */ function phptemplate_forum_display($forums, $topics, $parents, $tid, $sortby, $forum_per_page) { // Create a $variables array from the parameters $variables['forums'] = $forums; $variables['topics'] = $topics; $variables['parents'] = $parents; $variables['tid'] = $tid; $variables['sortby'] = $sortby; $variables['forum_per_page'] = $forum_per_page; // Pass the parameters into our preprocess function advanced_forum_call_preprocess('forums', $variables); // Set the template file $forum_style = advanced_forum_get_current_style(); return _phptemplate_callback('advf_forums', $variables, array("$forum_style/advf-forums")); } /** * Theme function for advf_forum_statistics(). */ function theme_advf_forum_statistics() { $variables = array(); // Pass the parameters into our preprocess function advanced_forum_call_preprocess('advf_forum_statistics', $variables); // Set the template file $forum_style = advanced_forum_get_current_style(); return _phptemplate_callback("advf_forum_statistics", $variables, array("$forum_style/advf-forum-statistics")); } /** * Theme function for advanced_forum_forum_legend(). */ function theme_advanced_forum_forum_legend() { $variables = array(); // Pass the parameters into our preprocess function advanced_forum_call_preprocess('advanced_forum_forum_legend', $variables); // Set the template file $forum_style = advanced_forum_get_current_style(); return _phptemplate_callback("advanced_forum_forum_legend", $variables, array("$forum_style/advanced_forum-forum-legend")); } /** * Theme function for advanced_forum_topic_legend(). */ function theme_advanced_forum_topic_legend() { $variables = array(); // Pass the parameters into our preprocess function advanced_forum_call_preprocess('advanced_forum_topic_legend', $variables); // Set the template file $forum_style = advanced_forum_get_current_style(); return _phptemplate_callback("advanced_forum_topic_legend", $variables, array("$forum_style/advanced_forum-topic-legend")); } /** * Theme function for advanced_forum_forum_legend(). */ function theme_advanced_forum_topic_header($node, $comment_count) { $variables = array(); $variables['node'] = $node; $variables['comment_count'] = $comment_count; // Pass the parameters into our preprocess function advanced_forum_call_preprocess('advanced_forum_topic_header', $variables); // Set the template file $forum_style = advanced_forum_get_current_style(); return _phptemplate_callback("advanced_forum_topic_header", $variables, array("$forum_style/advanced_forum-topic-header")); } /** * Theme function to format the reply link at the top/bottom of topic. */ function theme_advanced_forum_reply_link($node) { if (user_access('post comments')) { if ($node->comment == COMMENT_NODE_READ_WRITE) { if (variable_get('comment_form_location', COMMENT_FORM_SEPARATE_PAGE) == COMMENT_FORM_SEPARATE_PAGE) { // Comment form on seperate page $links['topic_reply'] = array( 'title' => t('Post Reply'), 'href' => "comment/reply/$node->nid", 'attributes' => array('title' => t('Share your thoughts and opinions related to this posting.')), 'fragment' => 'comment-form' ); } else { // Comment form is already on the page $links['topic_reply'] = array( 'title' => t('Post Reply'), 'href' => $_GET['q'], 'attributes' => array('title' => t('Share your thoughts and opinions related to this posting.')), 'fragment' => 'comment-form', 'query' => ($_GET['page']) ? "page=" . $_GET['page'] : NULL, ); } // Change to using a button if so set if (variable_get('advanced_forum_button_links', 1)) { $links['topic_reply']['title'] = advanced_forum_theme_image(t('post-reply.png'), t('Post reply')); $links['topic_reply']['html'] = TRUE; } } else { // Post is locked $links['topic_locked'] = array( 'title' => t('Topic Locked'), 'attributes' => array('title' => t('This topic is locked')), ); // Change to using a button if so set if (variable_get('advanced_forum_button_links', 1)) { $links['topic_locked']['title'] = advanced_forum_theme_image(t('locked-topic.png'), t('Locked')); $links['topic_locked']['html'] = TRUE; } } } else { // User does not have rights to post $links['comment_forbidden']['title'] = theme('comment_post_forbidden', $node->nid); $links['comment_forbidden']['html'] = TRUE; } return theme('links', $links, array('class' => 'forum-links')); } /** * Implementation of theme_forum_list(). */ function phptemplate_forum_list($forums, $parents, $tid) { // Create a $variables array from the parameters $variables['forums'] = $forums; $variables['parents'] = $parents; $variables['tid'] = $tid; // Pass the parameters into our preprocess function advanced_forum_call_preprocess('forum_list', $variables); // Set the template file $forum_style = advanced_forum_get_current_style(); return _phptemplate_callback("advf_forum_list", $variables, array("$forum_style/advf-forum-list")); } /* * Provides D5 compatability wrapper for theme_forum_submitted. * Note: this function does not exist at all in D5's forum.module */ function phptemplate_forum_submitted($topic) { // Create a $variables array from the parameters $variables['topic'] = $topic; // Pass the parameters into our preprocess function advanced_forum_call_preprocess('forum_submitted', $variables); // Set the template file $forum_style = advanced_forum_get_current_style(); return _phptemplate_callback("advf_forum_submitted", $variables, array("$forum_style/advf-forum-submitted")); } /** * Implementation of theme_forum_topic_list(). */ function phptemplate_forum_topic_list($tid, $topics, $sortby, $forum_per_page) { // Create a $variables array from the parameters $variables['tid'] = $tid; $variables['topics'] = $topics; $variables['sortby'] = $sortby; $variables['forum_per_page'] = $forum_per_page; // Pass the parameters into our preprocess function advanced_forum_call_preprocess('forum_topic_list', $variables); // Set the template file $forum_style = advanced_forum_get_current_style(); return _phptemplate_callback("advf_forum_topic_list", $variables, array("$forum_style/advf-forum-topic-list")); } /** * Implementation of theme_forum_topic_navigation */ function phptemplate_forum_topic_navigation($node) { // Removes post title navigation from forum posts. return ; } /** * Implementation of theme_forum_icon */ function phptemplate_forum_icon($new_posts, $num_posts = 0, $comment_mode = 0, $sticky = 0, $topic_id = 0) { // Create a $variables array from the parameters $variables['new_posts'] = $new_posts; $variables['num_posts'] = $num_posts; $variables['comment_mode'] = $comment_mode; $variables['sticky'] = $sticky; $variables['topic_id'] = $topic_id; // Pass the parameters into our preprocess function advanced_forum_call_preprocess('forum_icon', $variables); // Set the template file $forum_style = advanced_forum_get_current_style(); return _phptemplate_callback("advf_forum_icon", $variables, array("$forum_style/advf-forum-icon")); } // TEMPLATE PREPROCESS *******************************************************/ /** * Preprocesses template variables for the author pane. */ function advanced_forum_preprocess_author_pane(&$variables) { // Author pane is used in various places. The only way to be sure to only // hit it when we are using it is to check the template suggestion. if (strpos($variables['template_suggestion'], 'advf-author-pane')) { // Attempt to override the user picture fetched by Author Pane from core. $sized_picture = theme('advanced_forum_user_picture', $variables['account']); if (!empty($sized_picture)) { $variables['picture'] = $sized_picture; } } } /** * Preprocesses template variables for the topic header template. */ function advanced_forum_preprocess_advanced_forum_topic_header(&$variables) { // Build the reply link / button $variables['reply_link'] = theme('advanced_forum_reply_link', $variables['node'], $variables['comment_count']); // Total & new replies if (!empty($variables['comment_count'])) { $variables['total_posts'] = format_plural($variables['comment_count'], '1 reply', '@count replies'); $variables['last_post'] = advanced_forum_last_post_link($variables['node']); } else { $variables['total_posts'] = t('No replies'); } $variables['new_posts'] = advanced_forum_first_new_post_link($variables['node'], $variables['comment_count']); } /** * Preprocesses template variables for the node template. */ function advanced_forum_preprocess_node(&$variables) { if (!advanced_forum_treat_as_forum_post('node', $variables)) { // We only deal with forum posts. return; } // Set the static variables of the comment wrapper theme function. if (function_exists('phptemplate_comment_wrapper')) { phptemplate_comment_wrapper(NULL, 'forum', $variables['node']); } $forum_style = advanced_forum_get_current_style(); if ($_GET['page'] > 0) { // This is the repeated node on the top of subsequent pages. // We send this to a special .tpl so people can wipe it out or whatever $variables['template_files'][] = "$forum_style/advf-forum-repeat-post"; } else { // Use our combined node/comment template file $variables['template_files'][] = "$forum_style/advf-forum-post"; } // The node is the first post, aka topic $variables['top_post'] = TRUE; // Build the topic header $variables['topic_header'] = theme('advanced_forum_topic_header', $variables['node'], $variables['comment_count']); /* Node links changes */ // Change first post from "add comment" to "Reply" if (!empty($variables['node']->links) && !empty($variables['node']->links['comment_add'])) { $variables['node']->links['comment_add']['title'] = t('Reply'); } // Change links over to buttons when possible and wanted. _advanced_forum_buttonify_links($variables['node']->links); // Remake the links with our changes $variables['links'] = theme('links', $variables['node']->links, array('class' => 'links inline forum-links')); // Make an array version of $links $variables['links_array'] = $variables['node']->links; // User information / author pane $variables['account'] = user_load(array('uid' => $variables['node']->uid)); $variables['author_pane'] = theme('author_pane', $variables['account'], advanced_forum_path_to_images(), "$forum_style/advf-author-pane"); } /** * Preprocesses template variables for the comment template. */ function advanced_forum_preprocess_comment(&$variables) { if (advanced_forum_treat_as_forum_post('comment', $variables)) { // Use our combined node/comment template file // D5 won't find templates in subdirectories so we need to give it that $forum_style = advanced_forum_get_current_style(); $variables['template_files'][] = "$forum_style/advf-forum-post"; // Thread is being shown in the forum (not on the front page or in a view) $variables['is_forum'] = TRUE; // This is a comment, not the node. $variables['top_post'] = FALSE; // We need some information from the parent node so load it here $node = node_load($variables['comment']->nid); $variables['node'] = $node; // Title if (variable_get('comment_subject_field', 1) == 0) { // if comment titles are disabled, don't display it. $variables['title'] = ''; } else { // Assign the subject to the title variable for consistancy with nodes. $variables['title'] = check_plain($variables['comment']->subject); } // Just use the date for the submitted on. $variables['submitted'] = format_date($variables['comment']->timestamp); // Assign the comment to the content variable for consistancy with nodes. $variables['content'] = $variables['comment']->comment; // User information $account_id = $variables['comment']->uid; if ($account_id == 0) { // Anonymous user. Make a fake user object for theme_username $variables['account']->name = $variables['comment']->name; $variables['account']->homepage = $variables['comment']->homepage; } else { // Load up the real user object $variables['account'] = user_load(array('uid' => $variables['comment']->uid)); } // Create the author pane $variables['author_pane'] = theme('author_pane', $variables['account'], advanced_forum_path_to_images(), "$forum_style/advf-author-pane"); // Because the $links array isn't available here, we recreate it if (arg(1) != 'reply') { $links = module_invoke_all('link', 'comment', $variables['comment']); foreach (module_implements('link_alter') as $module) { $function = $module .'_link_alter'; $function($node, $links); } unset($links['comment_parent']); // Iconify common links (optional to avoid translation issues) _advanced_forum_buttonify_links($links); // Remake the links with our changes $variables['links'] = theme('links', $links, array('class' => 'links forum-links')); $variables['links_array'] = $links; } // Comment number with link if (!isset($post_number)) { static $post_number = 0; } _advanced_forum_topic_nid($variables['node']->nid); $post_per_page = _comment_get_display_setting('comments_per_page', $variables['node']); $page_number = $_GET['page']; if (!$page_number) { $page_number = 0; } $post_number++; $fragment = 'comment-' . $variables['comment']->cid; $query = ($page_number) ? 'page=' . $page_number : NULL; $linktext = '#' . (($page_number * $post_per_page) + $post_number); $linkpath = 'node/' . _advanced_forum_topic_nid(); $variables['comment_link'] = l($linktext, $linkpath, NULL, $query, $fragment); // Link to page created by Comment Page module, if it exists if (!empty($variables['comment']->page_url) && !(arg(0) == 'comment' && arg(1) == $variables['comment']->cid)) { $variables['page_link'] = l('(permalink)', $variables['comment']->page_url); } } } /** * Preprocesses template variables for the comment wrapper template. */ function advanced_forum_preprocess_comment_wrapper(&$variables) { if (advanced_forum_treat_as_forum_post('comment-wrapper', $variables)) { $variables['reply_link'] = ''; if ($variables['node']->comment != COMMENT_NODE_READ_WRITE || variable_get('comment_form_location', COMMENT_FORM_SEPARATE_PAGE) == COMMENT_FORM_SEPARATE_PAGE) { // If the post is locked or the comment form is on a seperate page, build // the reply/locked link / button $variables['reply_link'] = theme('advanced_forum_reply_link', $variables['node']); } } } /** * Preprocesses template variables for the forum template. */ function advanced_forum_preprocess_forums(&$variables) { if (empty($variables['topics'])) { // We don't want the links on the top of the forum overview $variables['links_orig'] = $variables['links']; $variables['links'] = array(); $variables['forum_description'] = ''; } else { // Grab the forum description and make it available to the template file $forum = taxonomy_get_term($variables['tid']); $variables['forum_description'] = $forum->description; // To avoid translation issues, make the button version optional if (variable_get('advanced_forum_button_links', 1)) { if (isset($variables['links']['forum'])) { $title_image = advanced_forum_theme_image(t('new-topic.png'), t('New topic')); $variables['links']['forum']['title'] = $title_image; $variables['links']['forum']['html'] = TRUE; } if (isset($variables['links']['poll'])) { $title_image = advanced_forum_theme_image(t('new-poll.png'), t('New poll')); $variables['links']['poll']['title'] = $title_image; $variables['links']['poll']['html'] = TRUE; } } } // Add in the mark as read link if user has access if (advanced_forum_markasread_access()) { $tid = $variables['tid']; if ($tid) { $title = t('Mark all topics read'); $link = "forum/markasread/$tid"; } else { $title = t('Mark all forums read'); $link = "forum/markasread"; } // To avoid translation issues, make the button version optional if (variable_get('advanced_forum_button_links', 1)) { $title_image = advanced_forum_theme_image(t('mark-read.png'), t('Mark read')); $variables['links']['markasread'] = array('title' => $title_image, 'href' => $link, 'html' => TRUE); $variables['links_orig']['markasread'] = array('title' => $title_image, 'href' => $link, 'html' => TRUE); } else { $variables['links']['markasread'] = array('title' => $title, 'href' => $link); $variables['links_orig']['markasread'] = array('title' => $title, 'href' => $link); } } } /** * Preprocesses template variables for the forum statistics template. */ function advanced_forum_preprocess_advf_forum_statistics(&$variables) { $variables['template_files'][] = 'advf-forum-statistics'; $variables['topics'] = advanced_forum_statistics_topics(); $variables['posts'] = advanced_forum_statistics_comments() + $variables['topics']; $variables['users'] = advanced_forum_statistics_users(); $authenticated_users = advanced_forum_statistics_online_users(); $variables['online_users'] = implode(', ', $authenticated_users); $variables['current_users'] = count($authenticated_users); $variables['current_guests'] = sess_count(time() - variable_get('user_block_seconds_online', 900)); $variables['current_total'] = $variables['current_users'] + $variables['current_guests']; $latest_user = advanced_forum_statistics_latest_user(); $variables['latest_user'] = theme('username', $latest_user); } /** * Preprocesses template variables for the forum statistics template. */ function advanced_forum_preprocess_advanced_forum_forum_legend(&$variables) { $variables['folder_new_posts'] = advanced_forum_theme_image(t('forum-folder-new-posts.png'), t('Forum Contains New Posts')); $variables['folder_default'] = advanced_forum_theme_image(t('forum-folder.png'), t('Forum Contains No New Posts')); $variables['folder_locked'] = advanced_forum_theme_image(t('forum-folder-locked.png'), t('Forum is Locked')); } function advanced_forum_preprocess_advanced_forum_topic_legend(&$variables) { $variables['topic_new'] = advanced_forum_theme_image(t('topic-new.png'), t('New Posts')); $variables['topic_hot_new'] = advanced_forum_theme_image(t('topic-hot-new.png'), t('Hot Thread (New)')); $variables['topic_hot'] = advanced_forum_theme_image(t('topic-hot.png'), t('Hot Thread (No New)')); $variables['topic_default'] = advanced_forum_theme_image(t('topic-default.png'), t('No New Posts')); $variables['topic_sticky'] = advanced_forum_theme_image(t('topic-sticky.png'), t('Sticky Thread')); $variables['topic_closed'] = advanced_forum_theme_image(t('topic-closed.png'), t('Locked Thread')); } /** * Preprocesses template variables for the forum list template. */ function advanced_forum_preprocess_forum_list(&$variables) { global $user; $number_of_forums = count($variables['forums']); $forum_counter = 0; foreach ($variables['forums'] as $id => $forum) { // Counter to label the rows by position $forum_counter++; switch ($forum_counter) { case "1": $row_classes = 'first-row'; break; case $number_of_forums: $row_classes = 'last-row'; break; default: $row_classes = 'middle-row'; } if ($forum->is_container) { $row_classes .= ' container'; } $variables['forums'][$id]->row_classes = $row_classes; $variables['forums'][$id]->new_posts = 0; $variables['forums'][$id]->new_text_posts = ''; $variables['forums'][$id]->new_url_posts = ''; $variables['forums'][$id]->old_posts = $forum->num_posts; $variables['forums'][$id]->position = $position; $current_container = $current_container_depth = 0; if ($forum->is_container) { $current_container = $forum->tid; $current_container_depth = $forum->depth; $variables['forums'][$id]->container_id = $current_container; } else { if ($forum->depth > $current_container_depth ) { $variables['forums'][$id]->container_id = $current_container; } else { $variables['forums'][$id]->container_id = 0; } } if ($user->uid) { // Show number of new posts as well as topics if (variable_get('advanced_forum_get_new_comments', 0)) { // This can cause performance issues, so allow it to be turned off $number_of_new_comments = advanced_forum_unread_comments_in_forum($forum->tid, $user->uid); $variables['forums'][$id]->new_posts = $number_of_new_comments + $variables['forums'][$id]->new_topics; if ($variables['forums'][$id]->new_posts) { $variables['forums'][$id]->new_text_posts = format_plural($variables['forums'][$id]->new_posts, '1 new', '@count new'); $variables['forums'][$id]->new_url_posts = url("forum/$forum->tid", NULL, 'new'); } $variables['forums'][$id]->old_posts = $forum->num_posts - $variables['forums'][$id]->new_posts; } } // If there are new topics/posts, change the icon if ($forum->new_topics || $forum->new_posts) { $variables['forums'][$id]->icon = advanced_forum_theme_image(t('forum-folder-new-posts.png'), t('New posts folder')); } else { $variables['forums'][$id]->icon = advanced_forum_theme_image(t('forum-folder.png'), t('Folder')); } // Make container description more accessable if (!empty($variables['parents']['0'])) { $variables['container_description'] = $variables['parents']['0']->description; } } if (user_access('view forum statistics')) { $variables['forum_statistics'] = theme('advf_forum_statistics'); } // Set a variable for displaying the forum legend. $variables['forum_legend'] = theme('advanced_forum_forum_legend'); } /** * Preprocesses template variables for the submitted by/in template. */ function advanced_forum_preprocess_forum_submitted(&$variables) { if ($variables['topic']->node_title) { $nid = $variables['topic']->nid; // Make a fake node object to avoid the node load $node = new stdClass(); $node->nid = $nid; $node->type = $variables['topic']->type; // Find the page of the first unread comment, if any $num_comments = db_result(db_query('SELECT COUNT(cid) FROM {comments} WHERE nid = %d', $nid)); $new_replies = comment_num_new($nid); $query = comment_new_page_count($num_comments, $new_replies, $node); // Format the node title with a link $title_length = variable_get('advanced_forum_topic_title_length', 15); if ($title_length == 0) { $short_topic_title = $variables['topic']->node_title; } else { $short_topic_title = truncate_utf8($variables['topic']->node_title, $title_length, TRUE, TRUE); } $fragment = ($new_replies) ? 'new' : NULL; $variables['topic_link'] = l($short_topic_title, "node/$nid", NULL, $query, $fragment); } // For items posted more than $cutoff hours ago, offer an actual date. $cutoff = variable_get('advanced_forum_time_ago_cutoff', 48) * 60 * 60; if (isset($variables['topic']->timestamp)) { $timestamp = $variables['topic']->timestamp; if (time() - $timestamp > $cutoff) { $variables['date_posted'] = format_date($timestamp, 'small'); } } } /** * Preprocesses template variables for the topic list template. */ function advanced_forum_preprocess_forum_topic_list(&$variables) { // Redo the table header so we can add in views. global $forum_topic_list_header; $forum_topic_list_header = array(); $forum_topic_list_header[] = array('data' => ' ', 'class' => 'column_icon'); $forum_topic_list_header[] = array('data' => t('Topic'), 'field' => 'n.title', 'class' => 'column_topic'); $forum_topic_list_header[] = array('data' => t('Replies'), 'field' => 'l.comment_count', 'class' => 'column_replies'); // Topic views require the statistics module so don't show if it's not enabled if (module_exists('statistics')) { $forum_topic_list_header[] = array('data' => t('Views'), 'class' => 'column_views'); } // Allow admins to turn off the created column if (!variable_get('advanced_forum_hide_created', 0)) { $forum_topic_list_header[] = array('data' => t('Created'), 'field' => 'n.created', 'class' => 'column_created'); } $forum_topic_list_header[] = array('data' => t('Last reply'), 'field' => 'l.last_comment_timestamp', 'class' => 'column_lreply'); // Create the tablesorting header. $ts = tablesort_init($forum_topic_list_header); $header = ''; foreach ($forum_topic_list_header as $cell) { $cell = tablesort_header($cell, $forum_topic_list_header, $ts); $header .= _theme_table_cell($cell, TRUE); } $variables['header'] = $header; // Grab the forum description and make it available to the template file $forum = taxonomy_get_term($variables['topic_id']); $variables['forum_description'] = $forum->description; // Do our own topic processing. if (!empty($variables['topics'])) { $row = 0; // Find out how many pages to show on the topic pager. We do this outside // the loop because it will be the same for all topics. $max_pages_to_display = variable_get('advanced_forum_topic_pager_max', 5); foreach ($variables['topics'] as $id => $topic) { // Get a pager to add to the topic, if there is one $variables['topics'][$id]->pager = _advanced_forum_create_topic_pager($max_pages_to_display, $topic); // Make shadow copy point to actual thread and tell you new the forum name if ($variables['topics'][$id]->moved == TRUE) { $term = taxonomy_get_term($topic->tid); $variables['topics'][$id]->message = l(t('This topic has been moved to !forum', array('!forum' => $term->name)), "node/$topic->nid"); } // Send the NID into the icon theme code so it can be linked to the topic $variables['topics'][$id]->icon = theme('forum_icon', $topic->new, $topic->num_comments, $topic->comment_mode, $topic->sticky, $topic->nid); // Add in the number of views if (module_exists('statistics')) { $variables['topics'][$id]->views = _advanced_forum_get_topic_views_count($topic->nid); } // Set classes based on stickiness. This allows themers to seperate out // all the sticky posts into their own section. if ($topic->sticky) { $sticky_class = 'sticky-topic'; $was_sticky = TRUE; } elseif ($was_sticky) { $sticky_class = 'first-not-sticky not-sticky'; $was_sticky = FALSE; } else { $sticky_class = 'not-sticky'; } $topic->sticky_class = $sticky_class; } // Set a variable for displaying the topic legend. $variables['topic_legend'] = theme('advanced_forum_topic_legend'); } } /** * Preprocesses template variables for the forum icon template. */ function advanced_forum_preprocess_forum_icon(&$variables) { $variables['iconpath'] = advanced_forum_path_to_images(); return; } // CORE FORUM PAGE OVERRIDE **************************************************/ /** * Menu callback; prints a forum listing. * * This is copied from the forum module and adapted. */ function advanced_forum_page($tid = 0) { if (!is_numeric($tid)) { return MENU_NOT_FOUND; } $tid = (int)$tid; drupal_add_css(drupal_get_path('module', 'forum') .'/forum.css'); _advanced_forum_add_files(); $forum_per_page = variable_get('forum_per_page', 25); $sortby = variable_get('forum_order', 1); $forums = advanced_forum_get_forums($tid); $parents = taxonomy_get_parents_all($tid); if ($tid && !in_array($tid, variable_get('forum_containers', array()))) { $topics = forum_get_topics($tid, $sortby, $forum_per_page); } return theme('forum_display', $forums, $topics, $parents, $tid, $sortby, $forum_per_page); } /** * Returns a list of all forums for a given taxonomy id * * This is copied from the forum module and adapted. * * 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 advanced_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 n.nid, n.title, n.type, 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; $last_post->nid = $topic->nid; // Note, we call it "node_title" otherwise it gets picked up on the // topic list as well. $last_post->node_title = $topic->title; $last_post->type = $topic->type; $forum->last_post = $last_post; $forums[$forum->tid] = $forum; } return $forums; } // MARK AS READ **************************************************************/ /** * Marks all posts in forums or in a given forum as read by the current user. */ function advanced_forum_markasread() { global $user; // See if we're on a forum or on the forum overview // Path will be /forum/markasread or /forum/markasread/tid $current_forum_id = arg(2); if ($current_forum_id) { // Delete the current history entries so already visited nodes get updated. $sql = "DELETE h FROM {history} AS h INNER JOIN {term_node} AS tn ON (h.nid = tn.nid) WHERE h.uid = %d AND tn.tid = %d"; db_query($sql, $user->uid, $current_forum_id); // Update the history table with all forum nodes newer than the cutoff. $sql = "INSERT INTO {history} (uid, nid, timestamp) SELECT DISTINCT %d, n.nid, %d FROM {node} AS n INNER JOIN {term_node} AS tn ON n.nid = tn.nid INNER JOIN {node_comment_statistics} AS ncs ON ncs.nid = n.nid WHERE (n.changed > %d OR ncs.last_comment_timestamp > %d) AND tn.tid = %d"; $args = array($user->uid, time(), NODE_NEW_LIMIT, NODE_NEW_LIMIT, $current_forum_id); db_query($sql, $args); // Readpath integration if (module_exists('readpath')) { readpath_clear_readpath(); } drupal_set_message(t('All content in this forum has been marked as read')); drupal_goto('forum/'. $current_forum_id); } else { // We are on the forum overview, requesting all forums be marked read $forum_vocabulary_id = variable_get('forum_nav_vocabulary', ''); // Delete the current history entries so already visited nodes get updated. $sql = "DELETE h FROM {history} AS h INNER JOIN {term_node} AS tn ON (h.nid = tn.nid) INNER JOIN {term_data} AS td ON (td.tid = tn.tid) WHERE h.uid = %d AND td.vid = %d"; db_query($sql, $user->uid, $forum_vocabulary_id); // Update the history table with all forum nodes newer than the cutoff. $sql = "INSERT INTO {history} (uid, nid, timestamp) SELECT DISTINCT %d, n.nid, %d FROM {node} AS n INNER JOIN {term_node} AS tn ON n.nid=tn.nid INNER JOIN {node_comment_statistics} AS ncs ON ncs.nid = n.nid INNER JOIN {term_data} AS td ON tn.tid = td.tid WHERE (n.changed > %d OR ncs.last_comment_timestamp > %d) AND td.vid = %d"; $args = array($user->uid, time(), NODE_NEW_LIMIT, NODE_NEW_LIMIT, $forum_vocabulary_id); db_query($sql, $args); // Readpath integration if (module_exists('readpath')) { readpath_clear_readpath(); } drupal_set_message(t('All forum content been marked as read')); drupal_goto('forum'); } } /** * Helper function to tell whether a user should be able to mark forums read. */ function advanced_forum_markasread_access() { global $user; return user_access('access content') && $user->uid; } // STYLE UTILITY FUNCTIONS ***************************************************/ /** * Returns the name of the forum style to use. */ function advanced_forum_get_current_style() { return variable_get('advanced_forum_style', 'naked'); } /** * Returns the full path to the advanced forum style, including the style name */ function advanced_forum_path_to_style() { static $style_path; if (!$style_path) { // Retrieve the style name $style = advanced_forum_get_current_style(); // Check first if there is a subtheme. This function is defined in Zen // and potentially may exist in other themes with subthemes. init_theme(); if (function_exists("path_to_subtheme")) { $path_to_subtheme = path_to_subtheme(); $style_path = $path_to_subtheme . '/' . $style; } // If we had no luck finding the style in a subtheme, find the style path // the normal way. if (empty($path_to_subtheme) || empty($style_path) || !file_exists($style_path)) { $style_path = path_to_theme() . '/' . $style; } } return $style_path; } /** * Returns the path to the advanced forum image directory */ function advanced_forum_path_to_images() { static $image_path; if (!$image_path) { $image_path = advanced_forum_path_to_style() . '/images'; } return $image_path; } /** * Wrapper around theme_image that automatically includes the path. */ function advanced_forum_theme_image($image_file, $alt = NULL, $title = NULL) { $image = advanced_forum_path_to_images() . "/$image_file"; if ($title = NULL) { $title = $alt; } if (file_exists($image)) { return theme('image', $image, $alt, $title); } else { return false; } } /** * Theme function to return imagecached version of the user picture. */ function theme_advanced_forum_user_picture($account) { // Get the imagecache preset to use, if any. $preset = variable_get('advanced_forum_user_picture_preset', ''); // Only proceed if user pictures are enabled, and there is a preset set, and // imagecache is enabled. For performace reasons, we return nothing if these // critera aren't met because we only call this function when the non // imagecached version is already created. If you use this function elsewhere // you will need to provide a picture when imagecache is not used. if (variable_get('user_pictures', 0) && !empty($preset) && module_exists('imagecache') && function_exists('imagecache_presets')) { if ($account->picture && file_exists($account->picture)) { // User has picture, so use that $alt = t("@user's picture", array('@user' => $account->name ? $account->name : 'Visitor')); $picture = theme('imagecache', $preset, $account->picture); } else { // User doesn't have a picture so use the default, if any $default_picture = variable_get('user_picture_default', ''); if ($default_picture) { $picture = theme('imagecache', $preset, $default_picture); } } if (!empty($picture)) { // If the user has access to view profiles, link the picture if (!empty($account->uid) && user_access('access user profiles')) { $picture = l($picture, "user/$account->uid", array('title' => t('View user profile.')), NULL, NULL, FALSE, TRUE); } } return '