You are here

talk.module in Talk 7

Same filename and directory in other branches
  1. 5 talk.module
  2. 6 talk.module

Comments are displayed in a separate 'talk' tab, for node types you wish

File

talk.module
View source
<?php

/**
 * @file
 * Comments are displayed in a separate 'talk' tab, for node types you wish
 */

/**
 * Implements hook_help().
 */
function talk_help($path, $arg) {
  switch ($path) {
    case 'admin/help#talk':
      $output = '<p>' . t('The talk module gives you the option to display comments on a separate tab. The option is per content type and can be set in the workflow options of a content type. You can control the text that shows in the tab, title, and link to the "talk" page.  You may use tokens in the patterns you set such as [node:title], [node:comment-count], or [node:comment-count-new].') . '</p>';
      return $output;
  }
}

/**
 * Implementation of hook_menu().
 */
function talk_menu() {
  $items = array();
  $items['node/%node/talk'] = array(
    'title callback' => 'talk_title',
    'title arguments' => array(
      1,
    ),
    'page callback' => 'talk_handle',
    'page arguments' => array(
      1,
    ),
    'access callback' => '_talk_access',
    'access arguments' => array(
      1,
    ),
    'type' => MENU_LOCAL_TASK,
    'weight' => 1,
  );
  $items['admin/config/content/talk'] = array(
    'title' => 'Talk page',
    'description' => 'Configure settings for the talk page.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'talk_admin_form',
    ),
    'access arguments' => array(
      'administer site configuration',
    ),
  );
  return $items;
}
function talk_menu_alter(&$items) {
  $items['comment/%']['page callback'] = 'talk_permalink';
}

/**
 * Page callback for talk view page.
 */
function talk_permalink($cid) {
  if (($comment = comment_load($cid)) && ($node = node_load($comment->nid))) {

    // Find the current display page for this comment.
    $page = comment_get_display_page($comment->cid, $node->type);
    if (!talk_activated($node->type)) {

      // Set $_GET['q'] and $_GET['page'] ourselves so that the node callback
      // behaves as it would when visiting the page directly.
      $_GET['q'] = 'node/' . $node->nid;
      $_GET['page'] = $page;

      // Return the node view, this will show the correct comment in context.
      return menu_execute_active_handler('node/' . $node->nid, FALSE);
    }
    else {
      drupal_goto("node/{$node->nid}/talk/{$comment->nid}", array(
        'fragment' => "comment-{$comment->cid}",
      ), 301);
    }
  }
  return MENU_NOT_FOUND;
}

/**
 * Helper item for talk_menu: access callback.
 */
function _talk_access($node) {
  return $node->nid && _talk_node_comment_value($node) && talk_activated($node->type) && user_access('access comments') && node_access('view', $node) && (variable_get('talk_page_no_comments', TRUE) || $node->comment_count);
}

/**
 * Menu call back for admin form.
 */
function talk_admin_form() {
  $form = array();
  if (module_exists('help')) {
    $token_list_link = l(t('View token list'), 'admin/help/token', array(
      'attributes' => array(
        'target' => '_blank',
      ),
    ));
  }
  else {
    $token_list_link = '';
  }
  $form['talk_page'] = array(
    '#type' => 'textfield',
    '#title' => t('Title of the "talk" page'),
    '#default_value' => talk_title(NULL, 'page'),
    '#description' => t('If token is enabled, you can use tokens like [node:title] or [node:nid]. ' . $token_list_link),
  );
  $form['talk_link'] = array(
    '#type' => 'textfield',
    '#title' => t('Link from the node "links" to the "talk" page'),
    '#default_value' => talk_title(NULL, 'link'),
    '#description' => t('If token is enabled, you can use tokens like [node:title] or [node:nid]. Leave blank to disable. ' . $token_list_link),
  );
  $form['talk_tab'] = array(
    '#type' => 'textfield',
    '#title' => t('Link from the node "tab" to the "talk" page'),
    '#default_value' => talk_title(NULL, 'tab'),
    '#description' => t('If token is enabled, you can use tokens like [node:title] or [node:nid]. ' . $token_list_link),
  );
  $form['talk_page_no_comments'] = array(
    '#type' => 'checkbox',
    '#title' => t('Display a "talk" page if there are no comments'),
    '#default_value' => variable_get('talk_page_no_comments', TRUE),
    '#description' => t('If the talk page is shown when there are no comments, users will be able to add new comments from the talk page even when there are no comments; otherwise, comments will have to be added in a different method, such as via the "add new comment" link on nodes.'),
  );
  $form['talk_addcmnt_teaser'] = array(
    '#type' => 'checkbox',
    '#title' => t('Display comment summary in teasers'),
    '#default_value' => variable_get('talk_addcmnt_teaser', TRUE),
    '#description' => t('If checked, then the comment summary (# of comments, # of new comments, "Add new comment") links will be displayed for node teasers. [Default: ON]'),
  );
  return system_settings_form($form);
}

/**
 * Provide an appropriate title for the context.
 *
 * @param object $node
 *   Optional node object.
 * @param string $type
 *   Optional string for context: tab, page, link.
 * @return string
 */
function talk_title($node = NULL, $type = 'tab') {
  return theme('talk_title', array(
    'node' => $node,
    'type' => $type,
  ));
}

/**
 * Theme function to create a talk title.
 */
function theme_talk_title($variables) {
  $node = $variables['node'];
  $type = $variables['type'];
  $title = variable_get('talk_' . $type, t('Talk'));
  if (module_exists('token') && isset($node->nid)) {
    global $user;
    $title = token_replace($title, array(
      'global' => NULL,
      'user' => $user,
      'node' => $node,
    ));
  }
  return html_entity_decode(check_plain($title), ENT_QUOTES);
}

/**
 * Menu callback for talk page.
 */
function talk_handle($node) {
  drupal_set_title(talk_title($node, 'page'));
  $add_comments = _talk_node_comment_value($node) == COMMENT_NODE_OPEN && user_access('post comments');
  return theme('talkpage', array(
    'node' => $node,
    'add_comments' => $add_comments,
  ));
}

/**
 * Implements hook_node_load().
 */
function talk_node_load($nodes, $types) {
  foreach ($nodes as &$node) {
    if (talk_activated($node->type) && arg(0) == 'node' && !arg(2)) {

      // Overwrite setting of comment module and set comments for this node to disabled.
      // This prevents the comments of being displayed.
      $node->comment_original_value = $node->comment;
      $node->comment = 0;
    }
  }
}

/**
 * Implements hook_node_view().
 */
function talk_node_view($node, $view_mode, $langcode) {
  global $conf;
  $clone = clone $node;
  $clone->comment = _talk_node_comment_value($clone);
  $recover = FALSE;
  if (array_key_exists('comment_form_location_' . $node->type, $conf)) {
    $original_setting = $conf['comment_form_location_' . $node->type];
    $recover = TRUE;
  }
  $conf['comment_form_location_' . $node->type] = COMMENT_FORM_SEPARATE_PAGE;
  comment_node_view($clone, $view_mode, $langcode);
  if ($recover) {
    $conf['comment_form_location_' . $node->type] = $original_setting;
  }
  else {
    unset($conf['comment_form_location_' . $node->type]);
  }

  // Display comment summary
  $addcmnt = _talk_node_comment_value($node) == COMMENT_NODE_OPEN && ($view_mode != "teaser" || variable_get('talk_addcmnt_teaser', TRUE));
  if ($addcmnt) {
    $links = $clone->content['links']['comment']['#links'];
    $node->content['links']['comment'] = array(
      '#theme' => 'links__node__comment__talk',
      '#attributes' => array(
        'class' => array(
          'links',
          'inline',
        ),
      ),
    );
    foreach ($links as $link) {
      if (talk_activated($node->type)) {
        if (isset($link['href']) && $link['href'] == 'node/' . $node->nid) {
          $link['href'] .= '/talk';
        }
      }
      $node->content['links']['comment']['#links'][] = $link;
    }
  }

  // Add the Talk link if user has access and it's not blank
  if (_talk_access($node) && strlen(variable_get('talk_link', '')) > 0) {
    $node->content['links']['comment']['#links'][] = array(
      'href' => 'node/' . $node->nid . '/talk',
      'title' => talk_title($node, 'link'),
    );
  }

  // Remove comments from page if viewing a node page for a node type for which
  // Talk is enabled.
  if (talk_activated($node->type) && arg(0) == 'node' && !arg(2)) {
    $node->content['comments'] = array();
  }
}

/**
 * Implements hook_form_alter().
 */
function talk_form_alter(&$form, $form_state, $form_id) {

  // Add option to comment options of node types.
  if ($form_id == 'node_type_form' && isset($form['#node_type'])) {
    $form['comment']['comment_talk'] = array(
      '#type' => 'checkbox',
      '#title' => t('Display comments on separate talk page'),
      '#prefix' => '<strong>' . t('Talk pages:') . '</strong>',
      '#weight' => 5,
      '#default_value' => talk_activated($form['#node_type']->type),
    );
  }
  if (isset($form['#node']->type) && talk_activated($form['#node']->type) && $form['#form_id'] == 'comment_node_' . $form['#node']->type . '_form') {
    $form['#submit'][] = 'talk_comment_hijack';
  }
}

/**
 * Changes the destination to the talk page after posting a comment.
 */
function talk_comment_hijack($form, &$form_state) {
  if (is_array($form_state['redirect'])) {
    $form_state['redirect'][0] .= '/talk';
  }
  else {
    $form_state['redirect'] .= '/talk';
  }
}

/**
 * Is talk page option activated for node tpye?
 */
function talk_activated($node_type) {
  return variable_get('comment_talk_' . $node_type, FALSE);
}

/**
 * Value of 'comment' of node.
 */
function _talk_node_comment_value(&$node) {
  return isset($node->comment_original_value) ? $node->comment_original_value : $node->comment;
}

/**
 * Implementats hook_theme().
 */
function talk_theme() {
  return array(
    'talkpage' => array(
      'template' => 'talkpage',
      'variables' => array(
        'node' => NULL,
        'add_comments' => NULL,
      ),
    ),
    'talk_comments' => array(
      'variables' => array(
        'node' => NULL,
      ),
    ),
    'talk_title' => array(
      'variables' => array(
        'node' => NULL,
        'type' => NULL,
      ),
    ),
  );
}

/**
 * Template preprocess function.
 *
 * @param $node
 *   The node whose talk page is being displayed.
 * @param $add_comments
 *   Boolean that indicates if adding comments is allowed for current user.
 * @ingroup themeable
 */
function template_preprocess_talkpage(&$variables) {
  $node = $variables['node'];
  $variables['title'] = talk_title($node, 'page');
  $comments = theme('talk_comments', array(
    'node' => $node,
  ));
  $variables['comment_count'] = $node->comment_count;
  $variables['comments'] = $comments;
}

/**
 *  A theme function to provide flexible rendering of the comments.
 *
 *  @param $node
 *    The node whose talk page is being displayed.
 */
function theme_talk_comments($variables) {
  $node = clone $variables['node'];
  $node->comment = _talk_node_comment_value($node);
  comment_node_view($node, 'full');
  if ($node->comment == COMMENT_NODE_OPEN) {
    if (user_access('post comments')) {

      // If comment form on same page as Talk, alter "Add new comment" link
      if (variable_get('comment_form_location_' . $node->type, COMMENT_FORM_BELOW) == COMMENT_FORM_BELOW) {
        $links_comments =& $node->content['links']['comment']['#links'];
        if (isset($links_comments['comment-add'])) {
          $links_comments['comment-add']['href'] = "node/{$node->nid}/talk";
        }
      }
    }
  }
  return drupal_render($node->content);
}

/**
 * Implements hook_token_list(). Documents the individual
 * tokens handled by the module.
 */
function talk_token_list($type = 'all') {
  $tokens = array();
  if ($type == 'comment' || $type == 'all') {
    $tokens['comment']['comment-talk-url'] = t('The comment view url (Talk compatible).');
  }
  return $tokens;
}

/**
 * Implements hook_token_values().
 */
function talk_token_values($type, $object = NULL, $options = array()) {
  switch ($type) {
    case 'comment':
      if ($comment = (object) $object) {
        $talk = '';
        $node = node_load($comment->nid);
        if (talk_activated($node->type)) {
          $talk = '/talk';
        }
        $values['comment-talk-url'] = url('node/' . $comment->nid . $talk, array(
          'fragment' => 'comment-' . $comment->cid,
          'absolute' => TRUE,
        ));
        return $values;
      }
      break;
  }
}

Functions

Namesort descending Description
talk_activated Is talk page option activated for node tpye?
talk_admin_form Menu call back for admin form.
talk_comment_hijack Changes the destination to the talk page after posting a comment.
talk_form_alter Implements hook_form_alter().
talk_handle Menu callback for talk page.
talk_help Implements hook_help().
talk_menu Implementation of hook_menu().
talk_menu_alter
talk_node_load Implements hook_node_load().
talk_node_view Implements hook_node_view().
talk_permalink Page callback for talk view page.
talk_theme Implementats hook_theme().
talk_title Provide an appropriate title for the context.
talk_token_list Implements hook_token_list(). Documents the individual tokens handled by the module.
talk_token_values Implements hook_token_values().
template_preprocess_talkpage Template preprocess function.
theme_talk_comments A theme function to provide flexible rendering of the comments.
theme_talk_title Theme function to create a talk title.
_talk_access Helper item for talk_menu: access callback.
_talk_node_comment_value Value of 'comment' of node.