'advanced_forum_markasread_access', 'page callback' => 'advanced_forum_markasread', 'type' => MENU_CALLBACK, ); $items['admin/settings/advanced-forum'] = array( 'access arguments' => array('administer advanced forum'), 'description' => 'Configure Advanced Forum with these settings.', 'page arguments' => array('advanced_forum_settings_page'), 'page callback' => 'drupal_get_form', 'title' => 'Advanced Forum', ); return $items; } /** * Implementation of hook_menu_alter(). * * Take over the forum page creation so we can add more information. */ function advanced_forum_menu_alter(&$callbacks) { $callbacks['forum']['page callback'] = 'advanced_forum_page'; } /** * Implementation of hook_theme(). */ function advanced_forum_theme() { $items['advf_forum_statistics'] = array( 'template' => 'advf-forum-statistics', ); $items['advanced_forum_topic_legend'] = array( 'template' => 'advanced_forum-topic-legend', ); $items['advanced_forum_topic_header'] = array( 'template' => 'advanced_forum-topic-header', 'arguments' => array( 'node' => NULL, 'comment_count' => NULL, ) ); $items['advanced_forum_forum_legend'] = array( 'template' => 'advanced_forum-forum-legend', ); $items['advanced_forum_user_picture'] = array( 'arguments' => array( 'account' => NULL, ) ); $items['advanced_forum_reply_link'] = array( 'arguments' => array( 'node' => NULL, ) ); return $items; } /** * Implementation of hook_theme_registry_alter(). */ function advanced_forum_theme_registry_alter(&$theme_registry) { // Kill the next/previous forum topic navigation links. if (!variable_get('advanced_forum_use_topic_navigation', FALSE)) { foreach ($theme_registry['forum_topic_navigation']['preprocess functions'] as $key => $value) { if ($value = 'template_preprocess_forum_topic_navigation') { unset($theme_registry['forum_topic_navigation']['preprocess functions'][$key]); } } } // --- The following section manipulates the theme registry so the .tpl files // --- for the given templates can be found first in the (sub)theme directory // --- then in ancestor themes, if any, then in the designated styles // --- directory for advanced forum, and finally in the advanced forum naked // --- style as a base style. // Affected templates $templates = array('node', 'comment', 'comment_wrapper', 'forums', 'forum_list', 'forum_topic_list', 'forum_icon', 'forum_submitted', 'author_pane', 'advf_forum_statistics', 'advanced_forum_topic_legend', 'advanced_forum_forum_legend', 'advanced_forum_topic_header', ); // Find all our ancestor themes and put them in an array. global $theme; $themes = list_themes(); $ancestor_paths = array(); $ancestor = $theme; while ($ancestor && isset($themes[$ancestor]->base_theme)) { array_unshift($ancestor_paths, dirname($themes[$themes[$ancestor]->base_theme]->filename)); $ancestor = $themes[$ancestor]->base_theme; } $current_style = advanced_forum_path_to_style(); $naked_path = drupal_get_path('module', 'advanced_forum') . '/styles/naked'; foreach ($templates as $template) { // Sanity check in case the template is not being used. if (is_array($theme_registry[$template])) { // If there was a path in there, store it. $existing_path = array_shift($theme_registry[$template]['theme paths']); // Slide the paths we are adding in before the existing one. if ($naked_path == $current_style) { // The style is already naked, so no need to add it twice. array_unshift($theme_registry[$template]['theme paths'], $existing_path, $current_style); } else { // Style is not naked so slip naked in as a default style. array_unshift($theme_registry[$template]['theme paths'], $existing_path, $naked_path, $current_style); } // If there are any ancestor paths (ie: we are in a subtheme, add those) foreach ($ancestor_paths as $ancestor_path) { $theme_registry[$template]['theme paths'][] = $ancestor_path; } // Put the active theme's path last since that takes precidence. $theme_registry[$template]['theme paths'][] = advanced_forum_path_to_theme(); } } } // 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 $options = array(); $available_styles = advanced_forum_get_styles(); foreach ($available_styles as $style_name => $style) { $options[$style_name] = $style_name; } $form['advanced_forum_general']['advanced_forum_style'] = array( '#type' => 'select', '#title' => t('Advanced forum style'), '#options' => $options, '#description' => t('Choose which style to use for your forums. This will apply independent of site 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')) { $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); } // 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 ($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) { $variables['template_files'][] = 'advanced_forum-topic-header'; // Build the reply link / button $variables['reply_link'] = theme('advanced_forum_reply_link', $variables['node']); // 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']); } /** * 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_'. $node->type, 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); $links['comment_forbidden']['html'] = TRUE; } return theme('links', $links, array('class' => 'forum-links')); } /** * 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; } // Determine the template file to use for the node. if (isset($_GET['page']) && $_GET['page'] > 0) { // This is the repeated node on the top of subsequent pages. // We send this to a special .tpl so people can adjust it to their needs. $variables['template_files'][] = "advf-forum-repeat-post"; } elseif (arg(1) == 'reply') { // Use the preview version $variables['template_files'][] = "advf-forum-preview-post"; } else { // Use our combined node/comment template file $variables['template_files'][] = "advf-forum-post"; } // The node is the first post, aka topic head $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(), 'advf-author-pane'); // Load the signature. if (module_exists('signature_forum')) { // If Signature For Forums is installed, use that $variables['signature'] = signature_forum_get_signature($variables['node']); } elseif (variable_get('user_signatures', 0)) { // Otherwise load Drupal's built in one, if enabled. $variables['signature'] = check_markup($variables['account']->signature, $variables['node']->format); } } /** * Preprocesses template variables for the comment template. */ function advanced_forum_preprocess_comment(&$variables) { if (advanced_forum_treat_as_forum_post('comment', $variables)) { if (arg(1) == 'reply') { // Use the preview version $variables['template_files'][] = "advf-forum-preview-post"; } else { // Use our combined node/comment template file $variables['template_files'][] = 'advf-forum-post'; } // This is a comment, not the node. $variables['top_post'] = FALSE; // 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(), 'advf-author-pane'); if (arg(1) != 'reply') { // Because the $links array isn't available here, we recreate it $node = node_load($variables['comment']->nid); $links = module_invoke_all('link', 'comment', $variables['comment']); drupal_alter('link', $links, $node); 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; } // Since we have to load the node anyway for our links trick, make it avail $variables['node'] = $node; // Title if (variable_get('comment_subject_field_' . $node->type, 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); } // 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, array('query' => $query, 'fragment' => $fragment));; // Link to page created by Comment Page module, if it exists $variables['page_link'] = ''; if (!empty($variables['comment']->page_url) && !(arg(0) == 'comment' && arg(1) == $variables['comment']->cid)) { $variables['page_link'] = l(t('(permalink)'), $variables['comment']->page_url); } // Load the signature. if (module_exists('signature_forum')) { // If Signature For Forums is installed, use that $variables['signature'] = signature_forum_get_signature($variables['comment']); } elseif (variable_get('user_signatures', 0)) { if ($variables['account']->signature) { // Otherwise load Drupal's built in one, if enabled. $variables['signature'] = check_markup($variables['account']->signature, $variables['comment']->format); } } } } function advanced_forum_preprocess_comment_wrapper(&$variables) { if (advanced_forum_treat_as_forum_post('comment-wrapper', $variables)) { $variables['template_files'][] = 'advf-comment-wrapper'; $variables['reply_link'] = ''; if ($variables['node']->comment != COMMENT_NODE_READ_WRITE || variable_get('comment_form_location_'. $variables['node']->type, 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. * * This function adds additional functionality to the core forum preprocess. */ function advanced_forum_preprocess_forums($variables) { $variables['template_files'][] = 'advf-forums'; 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['template_files'][] = 'advanced_forum-forum-legend'; $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['template_files'][] = 'advanced_forum-topic-legend'; $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. * * This function adds additional functionality to the core forum preprocess. */ function advanced_forum_preprocess_forum_list(&$variables) { $variables['template_files'][] = 'advf-forum-list'; 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; $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 $variables['forums'][$id]->new_posts = advanced_forum_unread_comments_in_forum($forum->tid, $user->uid) + $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", array('fragment' => '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 post 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'); } $variables['forum_legend'] = theme('advanced_forum_forum_legend'); } /** * Preprocesses template variables for the submitted by/in template. * * This function adds additional functionality to the core forum preprocess. */ function advanced_forum_preprocess_forum_submitted(&$variables) { $variables['template_files'][] = 'advf-forum-submitted'; // Avoid E_ALL warning $variables['topic_link'] = ''; if (isset($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", array('query' => $query, 'fragment' => $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. * * This function adds additional functionality to the core forum preprocess. */ function advanced_forum_preprocess_forum_topic_list(&$variables) { // Take control of the template file. $variables['template_files'][] = 'advf-forum-topic-list'; // Redo the table header so we can make our adjustments. This relies on this // header being unaltered from the forum module or it will be messed up. I // decided to do it this way rather than making it better able to adapt for // perfomance reasons. global $forum_topic_list_header; $new_header = array(); $forum_topic_list_header[0]['class'] = 'topic-icon'; $new_header[] = $forum_topic_list_header[0]; $forum_topic_list_header[1]['class'] = 'topic-topic'; $new_header[] = $forum_topic_list_header[1]; $forum_topic_list_header[2]['class'] = 'topic-replies'; $new_header[] = $forum_topic_list_header[2]; // Topic views require the statistics module so don't show if it's not enabled if (module_exists('statistics')) { $new_header[] = array('data' => t('Views'), 'class' => 'topic-views'); } // Allow admins to turn off the created column if (!variable_get('advanced_forum_hide_created', 0)) { $forum_topic_list_header[3]['class'] = 'topic-created'; $new_header[] = $forum_topic_list_header[3]; } $forum_topic_list_header[4]['class'] = 'topic-lreply'; $new_header[] = $forum_topic_list_header[4]; $forum_topic_list_header = $new_header; // 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; $was_sticky = FALSE; // 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->forum_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. * * This function adds additional functionality to the core forum preprocess. */ function advanced_forum_preprocess_forum_icon(&$variables) { $variables['template_files'][] = 'advf-forum-icon'; $variables['iconpath'] = advanced_forum_path_to_images(); } // 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) { _advanced_forum_add_files(); $topics = ''; $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('forums', $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(); $vid = variable_get('forum_nav_vocabulary', ''); $_forums = taxonomy_get_tree($vid, $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.vid = r.vid WHERE n.status = 1 GROUP BY r.tid"; $sql = db_rewrite_sql($sql); $_counts = db_query($sql); while ($count = db_fetch_object($_counts)) { $counts[$count->tid] = $count; } } foreach ($_forums as $forum) { // Check if this term is a container if (in_array($forum->tid, variable_get('forum_containers', array()))) { $forum->container = 1; } if (!empty($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.vid = tn.vid 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 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(); if (!empty($topic->last_comment_timestamp)) { $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.created > %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.created > %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'); } } /** * Access callback for menus and link display. * * This separate function is needed because the Drupal 6 menu system doesn't * run hook_menu() every time and the logged-in status of the user can get * cached and re-used for other users. */ function advanced_forum_markasread_access() { global $user; return user_access('access content') && $user->uid; } // STYLE UTILITY FUNCTIONS ***************************************************/ // Include the file that handles the plugin system adapted from panels. include_once drupal_get_path('module', 'advanced_forum') . '/advf-plugins.inc'; function advanced_forum_advforum_styles() { $items = array(); $items['naked'] = array( 'directory' => 'styles/naked', ); $items['naked_stacked'] = array( 'directory' => 'styles/naked_stacked', ); $items['blue_lagoon'] = array( 'directory' => 'styles/blue_lagoon', ); $items['blue_lagoon_stacked'] = array( 'directory' => 'styles/blue_lagoon_stacked', ); $items['boxy'] = array( 'directory' => 'styles/boxy', ); $items['boxy_stacked'] = array( 'directory' => 'styles/boxy_stacked', ); $items['flatgrey'] = array( 'directory' => 'styles/flatgrey', ); return $items; } /** * Returns the name of the forum style to use. */ function advanced_forum_get_current_style() { return variable_get('advanced_forum_style', 'naked'); } /** * Returns the path to actual site theme in use because path_to_theme is flaky. */ function advanced_forum_path_to_theme() { global $theme; if (!empty($theme)) { // Normally, the global theme variable is set, so we use that. return drupal_get_path('theme', $theme); } // For some reason I've never figured out, some users are reporting // that the global theme variable is not set when this is called. // As a band-aid solution, this will pull the default theme out of the // database and use that. $default_theme = variable_get('theme_default', 'garland'); return drupal_get_path('theme', $default_theme); } /** * Returns the 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(); // Get the path information $style_info = advanced_forum_get_style($style); $style_path = $style_info['path']; } return $style_path; } /** * Returns the path to the advanced forum image directory */ function advanced_forum_path_to_images() { static $image_path; global $language; if (!$image_path) { // If there is an override in settings, use it $image_path = variable_get('advanced_forum_image_directory', ''); if (empty($image_path)) { // Otherwise assume it's in the style's directory $image_path = advanced_forum_path_to_style() . '/images'; } if (!file_exists($image_path)) { // If the style doesn't have an images directory, fall back to naked. $image_path = drupal_get_path('module', 'advanced_forum') . '/styles/naked/images'; } } //Add language prefix to path if exist $language_prefix = $language->language; $image_path_language_prefix = $image_path . '/' . $language_prefix; if (file_exists($image_path_language_prefix)) { $image_path = $image_path_language_prefix; } 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')) { 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.'), 'html' => TRUE)); } } return '