View source
<?php
function discussthis_help($section = '') {
$output = '';
switch ($section) {
case 'admin/help#discussthis':
$output = '<p>' . t('Displays links to discussion forums for a given node. Administrators can select the types of nodes for which this is enabled, and for each of these, which forum new topics should be created in.') . '</p>';
$output .= '<ul><li><a href="admin/settings/discussthis">Discuss This configuration settings</a></li>';
$output .= '<li><a href="admin/user/access#module-discussthis">Discuss This permissions configuration</a></li></ul>';
$output .= filter_filter('process', 2, null, file_get_contents(dirname(__FILE__) . '/README.txt'));
break;
}
return $output;
}
function discussthis_perm() {
return array(
'administer discuss this',
'override discuss this forums',
'access discuss this links',
'initiate discuss this topics',
);
}
function discussthis_menu($may_cache) {
$items = array();
if (!$may_cache) {
$items[] = array(
'path' => 'admin/settings/discussthis',
'title' => t('Discuss This'),
'description' => t('Configure discuss this module defaults, including what node types and what forums to link to.'),
'callback' => 'drupal_get_form',
'callback arguments' => 'discussthis_admin',
'access' => user_access('administer discuss this'),
'type' => MENU_NORMAL_ITEM,
);
$items[] = array(
'path' => 'discussthis/new',
'callback' => 'drupal_get_form',
'callback arguments' => array(
'discussthis_new',
arg(2),
),
'access' => user_access('initiate discuss this topics'),
'type' => MENU_CALLBACK,
);
$items[] = array(
'path' => 'discussthis/autocomplete',
'title' => t('Autocomplete forum topics'),
'callback' => 'discussthis_autocomplete',
'access' => user_access('access content'),
'type' => MENU_CALLBACK,
);
}
return $items;
}
function discussthis_nodeapi(&$node, $op, $teaser, $page) {
$enabled = variable_get('discussthis_node_' . $node->type, 0);
if ($enabled) {
switch ($op) {
case 'validate':
break;
case 'insert':
case 'update':
if ($node && user_access('override discuss this forums')) {
$forum_tid = $node->discussthis['forum'];
$typed_title = $node->discussthis['topic'];
$typed_title = str_replace('""', '"', preg_replace('/^"(.*)"$/', '\\1', $typed_title));
$typed_title = trim($typed_title);
_discussthis_set_forum($node->nid, $forum_tid);
_discussthis_set_topic($node->nid, $typed_title);
}
break;
case 'view':
if (!$teaser && user_access('access discuss this links')) {
$topic_nid = _discussthis_get_topic($node->nid);
if ($show_comments = variable_get('discussthis_comments', 10)) {
$result = db_query_range('SELECT c.nid, c.uid, c.name, c.subject, c.cid, c.timestamp FROM {comments} c INNER JOIN {node} n ON n.nid = c.nid WHERE c.nid = %d AND n.status = 1 AND c.status = %d ORDER BY c.cid DESC', $topic_nid, COMMENT_PUBLISHED, 0, $show_comments);
while ($comment = db_fetch_object($result)) {
$comments[] = theme('discussthis_comment', $topic_nid, $comment);
}
$node->content['discussthis_comments'] = array(
'#value' => theme('item_list', $comments),
'#weight' => 50,
);
}
}
break;
case 'load':
break;
case 'delete':
break;
}
}
elseif ($node->type == 'forum') {
switch ($op) {
case 'load':
$discuss_nid = _discussthis_get_node($node->nid);
if ($discuss_nid) {
drupal_set_message("this forum topic is associated with node {$discuss_nid}");
$node->discuss_nid = $discuss_nid;
}
break;
case 'delete':
$sql = 'DELETE FROM {discussthis} WHERE topic_nid = %d';
db_query($sql, $node->nid);
break;
case 'insert':
case 'update':
_discussthis_set_tid($node->discuss_nid, $node->nid);
break;
}
}
}
function discussthis_link($type, $node = null, $teaser = false) {
if ($type == 'node') {
global $user;
$links = array();
$enabled = variable_get('discussthis_node_' . $node->type, 0);
$display = variable_get('discussthis_teaser_' . $node->type, 2);
if (!$enabled || $teaser && !$display) {
return $links;
}
if (!$teaser && $display == 1) {
return $links;
}
$topic_nid = _discussthis_get_topic($node->nid);
if ($user->uid) {
if ($topic_nid && user_access('access discuss this links')) {
$links['discussthis'] = array(
'title' => t('Discuss This!'),
'href' => 'node/' . $topic_nid,
);
}
if ($topic_nid == 0 && user_access('initiate discuss this topics')) {
$links['discussthis'] = array(
'title' => t('Discuss This!'),
'href' => 'discussthis/new/' . $node->nid,
);
}
}
else {
if ($topic_nid) {
$destination = 'destination=' . drupal_urlencode("discussthis/new/" . $node->nid);
}
else {
$destination = 'destination=' . drupal_urlencode("node/" . $topic_nid);
}
if (variable_get('user_register', 1)) {
$links['discussthis'] = array(
'title' => t('Login/Register to Discuss'),
'href' => 'user',
'query' => $destination,
);
}
else {
$links['discussthis'] = array(
'title' => t('Login to Discuss'),
'href' => 'user/login',
'query' => $destination,
);
}
}
return $links;
}
}
function discussthis_form_alter($form_id, &$form) {
if (isset($form['type'])) {
$type = $form['type']['#value'];
}
elseif (isset($form['orig_type'])) {
$type = $form['orig_type']['#value'];
}
else {
return;
}
if ($type == 'forum' && isset($_GET['did'])) {
$discuss_node = node_load($_GET['did']);
$default_body = 'Following is a discussion on the [node-type-name] item titled: [node-link]' . '.<br /> Below is the discussion so far. Feel free to add your own comments!<br />';
$form['title']['#type'] = 'item';
$form['title']['#value'] = token_replace(variable_get('discussthis_newsubject', 'Discuss This: [node-title]'), 'discussthis', $discuss_node);
$desc = token_replace(variable_get('discussthis_newtemplate', $default_body), 'discussthis', $discuss_node);
$form['discussthis'] = array(
'#type' => 'fieldset',
'#title' => t('Discuss This'),
'#collapsible' => TRUE,
'#collapsed' => FALSE,
'#weight' => -2,
);
$form['discussthis']['description'] = array(
'#type' => 'item',
'#value' => $desc,
);
$form['discuss_nid'] = array(
'#type' => 'value',
'#value' => $discuss_node->nid,
);
}
if (!variable_get('discussthis_node_' . $type, 0)) {
return;
}
switch ($form_id) {
case $type . '_node_form':
$nid = $form['nid']['#value'];
$forum_tid = _discussthis_get_forum($nid, $type);
$forum_nid = _discussthis_get_topic($nid);
$topic = node_load(array(
'nid' => $forum_nid,
));
if ($forum_tid && user_access('override discuss this forums')) {
$forums = forum_get_forums();
foreach ($forums as $tid => $forum) {
if (!$forum->container) {
$discussthis_forums[$tid] = $forum->name;
}
}
$form['discussthis'] = array(
'#type' => 'fieldset',
'#title' => t('Discuss This'),
'#collapsible' => true,
'#collapsed' => true,
'#weight' => 1,
'#tree' => true,
);
$form['discussthis']['forum'] = array(
'#type' => 'select',
'#title' => t('Forum for new discussions on this node'),
'#required' => true,
'#description' => t('Select the forum where a NEW discussion will be created if none exist.'),
'#options' => $discussthis_forums,
'#default_value' => $forum_tid,
'#weight' => 2,
);
$form['discussthis']['topic'] = array(
'#type' => 'textfield',
'#title' => t('Forum topic for discussions on this node'),
'#description' => t('The forum topic where discussions of this node appear'),
'#default_value' => $topic->title,
'#autocomplete_path' => 'discussthis/autocomplete/' . $forum_tid,
'#maxlength' => 255,
'#weight' => 3,
);
}
break;
}
}
function discussthis_token_list($type = 'all') {
if ($type == 'discussthis' || $type == 'all') {
$tokens['discussthis']['node-link'] = t('A link to the original node under discussion.');
$tokens['discussthis']['node-title'] = t('The title of the original node.');
$tokens['discussthis']['node-type-name'] = t('The name of the original node\'s type.');
$tokens['discussthis']['node-type'] = t('The original node\'s type.');
$tokens['discussthis']['node-teaser'] = t('Node teaser');
$tokens['discussthis']['node-body'] = t('Node body');
$tokens['discussthis']['node-body-50'] = t('First 100 characters of a body');
$tokens['discussthis']['node-body-100'] = t('First 100 characters of a body');
$tokens['discussthis']['node-body-200'] = t('First 200 characters of a body');
$tokens['discussthis']['node-body-400'] = t('First 400 characters of a body');
return $tokens;
}
}
function discussthis_token_values($type, $object = NULL, $options = array()) {
if ($type == 'discussthis') {
$object->body = str_replace('<!--break-->', '', $object->body);
$tokens['node-link'] = l(t($object->title), 'node/' . $object->nid);
$tokens['node-title'] = t($object->title);
$tokens['node-type-name'] = node_get_types('name', $object);
$tokens['node-type'] = $object->type;
$tokens['node-teaser'] = check_plain(preg_replace(array(
'/\\<\\/p\\>/',
'/\\n/',
), ' ', $object->teaser));
$tokens['node-body'] = check_plain(preg_replace(array(
'/\\<\\/p\\>/',
'/\\n/',
), ' ', $object->body));
$tokens['node-body-50'] = substr(check_plain(preg_replace(array(
'/\\<\\/p\\>/',
'/\\n/',
), ' ', $object->body)), 0, 50);
$tokens['node-body-100'] = substr(check_plain(preg_replace(array(
'/\\<\\/p\\>/',
'/\\n/',
), ' ', $object->body)), 0, 100);
$tokens['node-body-200'] = substr(check_plain(preg_replace(array(
'/\\<\\/p\\>/',
'/\\n/',
), ' ', $object->body)), 0, 200);
$tokens['node-body-400'] = substr(check_plain(preg_replace(array(
'/\\<\\/p\\>/',
'/\\n/',
), ' ', $object->body)), 0, 400);
return $tokens;
}
}
function discussthis_admin() {
drupal_add_js(drupal_get_path('module', 'discussthis') . '/discussthis.js');
drupal_add_css(drupal_get_path('module', 'discussthis') . '/discussthis.css');
$node_types = node_get_types('names');
$discussthis_nodetypes = variable_get('discussthis_nodetypes', $node_types);
$form['discussthis_newsubject'] = array(
'#type' => 'textfield',
'#title' => t('Title for newly created Forum discussions'),
'#size' => 30,
'#maxlength' => 60,
'#default_value' => variable_get('discussthis_newsubject', 'Discuss This: [node-title]'),
'#weight' => -3,
);
$default_body = 'Following is a discussion on the [node-type-name] item titled: [node-link]' . '.<br /> Below is the discussion so far. Feel free to add your own comments!<br />';
$form['discussthis_newtemplate'] = array(
'#type' => 'textarea',
'#title' => t('Template for auto-created Forum discussions'),
'#description' => theme('token_help', 'discussthis'),
'#default_value' => variable_get('discussthis_newtemplate', $default_body),
'#weight' => -2,
);
$form['discussthis_comments'] = array(
'#type' => 'select',
'#title' => t('How many recent comments should be displayed with non-teaser node view?'),
'#options' => array(
0 => 'none',
1 => '1',
2 => '2',
3 => '3',
4 => '4',
5 => '5',
10 => '10',
),
'#default_value' => variable_get('discussthis_comments', 10),
);
$form['discussthis_nodetypes'] = array(
'#type' => 'checkboxes',
'#title' => t('Which node types should use the Discuss This feature'),
'#description' => t('Select all node types which should allow Discuss This links and a corresponding Default forum in which to create the topic. Also choose whether links should be displayed on Full node views, Teaser views, or both.'),
'#default_value' => $discussthis_nodetypes,
'#options' => $node_types,
);
$forums = forum_get_forums();
$discussthis_forums = array(
'0' => '-- select --',
);
foreach ($forums as $tid => $forum) {
if (!$forum->container) {
$discussthis_forums[$tid] = $forum->name;
}
}
foreach ($discussthis_nodetypes as $type => $name) {
$form['defaults']['discussthis_node_' . $type] = array(
'#prefix' => '<span class="conditional">',
'#suffix' => '</span>',
'#type' => 'select',
'#default_value' => variable_get('discussthis_node_' . $type, 0),
'#options' => $discussthis_forums,
);
$form['defaults']['discussthis_teaser_' . $type] = array(
'#prefix' => '<span class="conditional">',
'#suffix' => '</span>',
'#type' => 'select',
'#default_value' => variable_get('discussthis_teaser_' . $type, 0),
'#options' => array(
'0' => t('Full view only'),
'1' => t('Teaser view only'),
'2' => t('Both'),
),
);
}
$form['#validate'] = array(
'discussthis_admin_validate' => array(),
);
$form['#theme'] = 'discussthis_admin';
return system_settings_form($form);
}
function discussthis_admin_validate($form_id, $form_values) {
$node_types = node_get_types('names');
foreach ($form_values['discussthis_nodetypes'] as $type => $enabled) {
if ($enabled && $form_values['discussthis_node_' . $type] == 0) {
form_set_error('discussthis_node_' . $type, t('Please select a default Forum for ' . $node_types[$type] . ' nodes.'));
}
}
}
function theme_discussthis_admin($form) {
$types = '<ul>';
foreach ($form['discussthis_nodetypes']['#options'] as $type => $name) {
$types .= '<li>';
$types .= drupal_render($form['discussthis_nodetypes'][$type]);
$types .= '<span class="conditional-select">';
$types .= drupal_render($form['defaults']['discussthis_node_' . $type]);
$types .= drupal_render($form['defaults']['discussthis_teaser_' . $type]);
$types .= '</span>';
$types .= '</li>';
}
$types .= '</ul>';
$output .= drupal_render($form['discussthis_nodetypes']);
$output .= $types;
$output .= drupal_render($form['discussthis_comments']);
$output .= drupal_render($form['discussthis_newsubject']);
$output .= drupal_render($form['discussthis_newtemplate']);
$output .= drupal_render($form);
return $output;
}
function discussthis_new($nid) {
$node = node_load(array(
'nid' => $nid,
));
$tid = _discussthis_get_forum($nid, $node->type);
$form['discuss-tid'] = array(
'#type' => 'value',
'#value' => $tid,
);
$form['discuss-nid'] = array(
'#type' => 'value',
'#value' => $nid,
);
$message = t('Do you want to be the first to Discuss "%item"?', array(
'%item' => $node->title,
));
$desc = t('No one has started this discussion yet. If you click Discuss This, you will be able to submit a new forum topic to discuss this %node-type', array(
'%node-type' => $node->type,
));
$topic_nid = _discussthis_get_topic($nid);
if ($topic_nid) {
drupal_goto('comment/reply/' . $topic_nid, null, 'comment-form');
}
return confirm_form($form, $message, $destination, $desc, t('Discuss This!'));
}
function discussthis_new_submit($form_id, &$form_values) {
return array(
'path' => 'node/add/forum/' . $form_values['discuss-tid'],
'query' => 'did=' . $form_values['discuss-nid'],
);
}
function discussthis_autocomplete($tid, $string = '') {
if ($string != '') {
$result = db_query_range(db_rewrite_sql('SELECT n.nid,n.title FROM {node} n WHERE n.type = "forum" AND LOWER(n.title) LIKE LOWER("%s%%")'), $string, 0, 10);
$matches = array();
while ($node = db_fetch_object($result)) {
$n = $node->title;
if (strpos($node->title, ',') !== false || strpos($node->title, '"') !== false) {
$n = '"' . str_replace('"', '""', $node->title) . '"';
}
$matches[$n] = check_plain($node->title);
}
echo drupal_to_js($matches);
exit;
}
}
function _discussthis_get_forum($nid, $type) {
$sql = 'SELECT forum_tid FROM {discussthis_forums} WHERE nid=%d';
$forum_tid = db_result(db_query($sql, $nid));
if (!$forum_tid) {
$forum_tid = variable_get('discussthis_node_' . $type, 0);
}
return $forum_tid;
}
function _discussthis_set_forum($nid, $tid) {
$sql = 'REPLACE INTO {discussthis_forums} (nid,forum_tid) VALUES (%d,%d)';
db_query($sql, $nid, $tid);
}
function _discussthis_get_topic($nid) {
$sql = 'SELECT topic_nid FROM {discussthis} WHERE nid=%d';
$topic = db_result(db_query($sql, $nid));
if ($topic) {
return $topic;
}
else {
return 0;
}
}
function _discussthis_get_node($topic_nid) {
$sql = 'SELECT nid FROM {discussthis} WHERE topic_nid=%d';
$nid = db_result(db_query($sql, $topic_nid));
if ($nid) {
return $nid;
}
else {
return 0;
}
}
function _discussthis_set_topic($nid, $title) {
$sql = 'SELECT n.nid,n.title FROM {node} n WHERE n.title like "%s" and n.type = "forum"';
$result = db_query(db_rewrite_sql($sql), $title);
$topic = db_fetch_object($result);
if ($topic->nid) {
_discussthis_set_tid($nid, $topic->nid);
}
else {
$sql = 'DELETE FROM {discussthis} WHERE nid=%d';
db_query($sql, $nid);
}
}
function _discussthis_set_tid($nid, $topic_nid) {
$sql = 'REPLACE INTO {discussthis} (nid,topic_nid) VALUES (%d,%d)';
db_query($sql, $nid, $topic_nid);
}
function theme_discussthis_comment($topic_nid, $comment) {
$output = "<div class=\"discussthis-comment\">\n";
$output .= ' <span class="subject">' . l($comment->subject, 'node/' . $topic_nid, null, null, "comment-{$comment->cid}") . '</span> ';
$output .= '<span class="credit">' . t('by') . ' ' . theme('username', $comment) . "</span>\n";
$output .= "</div>\n";
return $output;
}