View source
<?php
define('COMMENT_NOT_PUBLISHED', 0);
define('COMMENT_PUBLISHED', 1);
define('COMMENT_MODE_FLAT', 0);
define('COMMENT_MODE_THREADED', 1);
define('COMMENT_ANONYMOUS_MAYNOT_CONTACT', 0);
define('COMMENT_ANONYMOUS_MAY_CONTACT', 1);
define('COMMENT_ANONYMOUS_MUST_CONTACT', 2);
define('COMMENT_FORM_SEPARATE_PAGE', 0);
define('COMMENT_FORM_BELOW', 1);
define('COMMENT_NODE_HIDDEN', 0);
define('COMMENT_NODE_CLOSED', 1);
define('COMMENT_NODE_OPEN', 2);
function comment_help($path, $arg) {
switch ($path) {
case 'admin/help#comment':
$output = '<h3>' . t('About') . '</h3>';
$output .= '<p>' . t('The Comment module allows users to comment on site content, set commenting defaults and permissions, and moderate comments. For more information, see the online handbook entry for <a href="@comment">Comment module</a>.', array(
'@comment' => 'http://drupal.org/documentation/modules/comment/',
)) . '</p>';
$output .= '<h3>' . t('Uses') . '</h3>';
$output .= '<dl>';
$output .= '<dt>' . t('Default and custom settings') . '</dt>';
$output .= '<dd>' . t("Each <a href='@content-type'>content type</a> can have its own default comment settings configured as: <em>Open</em> to allow new comments, <em>Hidden</em> to hide existing comments and prevent new comments, or <em>Closed</em> to view existing comments, but prevent new comments. These defaults will apply to all new content created (changes to the settings on existing content must be done manually). Other comment settings can also be customized per content type, and can be overridden for any given item of content. When a comment has no replies, it remains editable by its author, as long as the author has a user account and is logged in.", array(
'@content-type' => url('admin/structure/types'),
)) . '</dd>';
$output .= '<dt>' . t('Comment approval') . '</dt>';
$output .= '<dd>' . t("Comments from users who have the <em>Skip comment approval</em> permission are published immediately. All other comments are placed in the <a href='@comment-approval'>Unapproved comments</a> queue, until a user who has permission to <em>Administer comments</em> publishes or deletes them. Published comments can be bulk managed on the <a href='@admin-comment'>Published comments</a> administration page.", array(
'@comment-approval' => url('admin/content/comment/approval'),
'@admin-comment' => url('admin/content/comment'),
)) . '</dd>';
$output .= '</dl>';
return $output;
}
}
function comment_entity_info() {
$return = array(
'comment' => array(
'label' => t('Comment'),
'base table' => 'comment',
'uri callback' => 'comment_uri',
'fieldable' => TRUE,
'controller class' => 'CommentController',
'entity keys' => array(
'id' => 'cid',
'bundle' => 'node_type',
'label' => 'subject',
'language' => 'language',
),
'bundles' => array(),
'view modes' => array(
'full' => array(
'label' => t('Full comment'),
'custom settings' => FALSE,
),
),
'static cache' => FALSE,
),
);
foreach (node_type_get_names() as $type => $name) {
$return['comment']['bundles']['comment_node_' . $type] = array(
'label' => t('@node_type comment', array(
'@node_type' => $name,
)),
'node bundle' => $type,
'admin' => array(
'path' => 'admin/structure/types/manage/%comment_node_type/comment',
'bundle argument' => 4,
'real path' => 'admin/structure/types/manage/' . str_replace('_', '-', $type) . '/comment',
'access arguments' => array(
'administer content types',
),
),
);
}
return $return;
}
function comment_node_type_load($name) {
if ($type = node_type_get_type(strtr($name, array(
'-' => '_',
)))) {
return 'comment_node_' . $type->type;
}
}
function comment_uri($comment) {
return array(
'path' => 'comment/' . $comment->cid,
'options' => array(
'fragment' => 'comment-' . $comment->cid,
),
);
}
function comment_field_extra_fields() {
$return = array();
foreach (node_type_get_types() as $type) {
if (variable_get('comment_subject_field_' . $type->type, 1) == 1) {
$return['comment']['comment_node_' . $type->type] = array(
'form' => array(
'author' => array(
'label' => t('Author'),
'description' => t('Author textfield'),
'weight' => -2,
),
'subject' => array(
'label' => t('Subject'),
'description' => t('Subject textfield'),
'weight' => -1,
),
),
);
}
}
return $return;
}
function comment_theme() {
return array(
'comment_block' => array(
'variables' => array(),
),
'comment_preview' => array(
'variables' => array(
'comment' => NULL,
),
),
'comment' => array(
'template' => 'comment',
'render element' => 'elements',
),
'comment_post_forbidden' => array(
'variables' => array(
'node' => NULL,
),
),
'comment_wrapper' => array(
'template' => 'comment-wrapper',
'render element' => 'content',
),
);
}
function comment_menu() {
$items['admin/content/comment'] = array(
'title' => 'Comments',
'description' => 'List and edit site comments and the comment approval queue.',
'page callback' => 'comment_admin',
'access arguments' => array(
'administer comments',
),
'type' => MENU_LOCAL_TASK | MENU_NORMAL_ITEM,
'file' => 'comment.admin.inc',
);
$items['admin/content/comment/new'] = array(
'title' => 'Published comments',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -10,
);
$items['admin/content/comment/approval'] = array(
'title' => 'Unapproved comments',
'title callback' => 'comment_count_unpublished',
'page arguments' => array(
'approval',
),
'access arguments' => array(
'administer comments',
),
'type' => MENU_LOCAL_TASK,
);
$items['comment/%'] = array(
'title' => 'Comment permalink',
'page callback' => 'comment_permalink',
'page arguments' => array(
1,
),
'access arguments' => array(
'access comments',
),
);
$items['comment/%/view'] = array(
'title' => 'View comment',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -10,
);
$items['comment/%comment/edit'] = array(
'title' => 'Edit',
'page callback' => 'comment_edit_page',
'page arguments' => array(
1,
),
'access callback' => 'comment_access',
'access arguments' => array(
'edit',
1,
),
'type' => MENU_LOCAL_TASK,
'weight' => 0,
);
$items['comment/%/approve'] = array(
'title' => 'Approve',
'page callback' => 'comment_approve',
'page arguments' => array(
1,
),
'access arguments' => array(
'administer comments',
),
'file' => 'comment.pages.inc',
'weight' => 1,
);
$items['comment/%/delete'] = array(
'title' => 'Delete',
'page callback' => 'comment_confirm_delete_page',
'page arguments' => array(
1,
),
'access arguments' => array(
'administer comments',
),
'type' => MENU_LOCAL_TASK,
'file' => 'comment.admin.inc',
'weight' => 2,
);
$items['comment/reply/%node'] = array(
'title' => 'Add new comment',
'page callback' => 'comment_reply',
'page arguments' => array(
2,
),
'access callback' => 'node_access',
'access arguments' => array(
'view',
2,
),
'file' => 'comment.pages.inc',
);
return $items;
}
function comment_menu_alter(&$items) {
$items['admin/content']['description'] = 'Administer content and comments.';
$items['admin/structure/types/manage/%comment_node_type/comment/fields']['title'] = 'Comment fields';
$items['admin/structure/types/manage/%comment_node_type/comment/fields']['weight'] = 3;
$items['admin/structure/types/manage/%comment_node_type/comment/display']['title'] = 'Comment display';
$items['admin/structure/types/manage/%comment_node_type/comment/display']['weight'] = 4;
}
function comment_count_unpublished() {
$count = db_query('SELECT COUNT(cid) FROM {comment} WHERE status = :status', array(
':status' => COMMENT_NOT_PUBLISHED,
))
->fetchField();
return t('Unapproved comments (@count)', array(
'@count' => $count,
));
}
function comment_node_type_insert($info) {
_comment_body_field_create($info);
}
function comment_node_type_update($info) {
if (!empty($info->old_type) && $info->type != $info->old_type) {
field_attach_rename_bundle('comment', 'comment_node_' . $info->old_type, 'comment_node_' . $info->type);
}
}
function comment_node_type_delete($info) {
field_attach_delete_bundle('comment', 'comment_node_' . $info->type);
$settings = array(
'comment',
'comment_default_mode',
'comment_default_per_page',
'comment_anonymous',
'comment_subject_field',
'comment_preview',
'comment_form_location',
);
foreach ($settings as $setting) {
variable_del($setting . '_' . $info->type);
}
}
function _comment_body_field_create($info) {
if (!field_read_field('comment_body', array(
'include_inactive' => TRUE,
))) {
$field = array(
'field_name' => 'comment_body',
'type' => 'text_long',
'entity_types' => array(
'comment',
),
);
field_create_field($field);
}
if (!field_read_instance('comment', 'comment_body', 'comment_node_' . $info->type, array(
'include_inactive' => TRUE,
))) {
field_attach_create_bundle('comment', 'comment_node_' . $info->type);
$instance = array(
'field_name' => 'comment_body',
'label' => 'Comment',
'entity_type' => 'comment',
'bundle' => 'comment_node_' . $info->type,
'settings' => array(
'text_processing' => 1,
),
'required' => TRUE,
'display' => array(
'default' => array(
'label' => 'hidden',
'type' => 'text_default',
'weight' => 0,
),
),
);
field_create_instance($instance);
}
}
function comment_permission() {
return array(
'administer comments' => array(
'title' => t('Administer comments and comment settings'),
),
'access comments' => array(
'title' => t('View comments'),
),
'post comments' => array(
'title' => t('Post comments'),
),
'skip comment approval' => array(
'title' => t('Skip comment approval'),
),
'edit own comments' => array(
'title' => t('Edit own comments'),
),
);
}
function comment_block_info() {
$blocks['recent']['info'] = t('Recent comments');
$blocks['recent']['properties']['administrative'] = TRUE;
return $blocks;
}
function comment_block_configure($delta = '') {
$form['comment_block_count'] = array(
'#type' => 'select',
'#title' => t('Number of recent comments'),
'#default_value' => variable_get('comment_block_count', 10),
'#options' => drupal_map_assoc(array(
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
25,
30,
)),
);
return $form;
}
function comment_block_save($delta = '', $edit = array()) {
variable_set('comment_block_count', (int) $edit['comment_block_count']);
}
function comment_block_view($delta = '') {
if (user_access('access comments')) {
$block['subject'] = t('Recent comments');
$block['content'] = theme('comment_block');
return $block;
}
}
function comment_permalink($cid) {
if (($comment = comment_load($cid)) && ($node = node_load($comment->nid))) {
$page = comment_get_display_page($comment->cid, $node->type);
$_GET['q'] = 'node/' . $node->nid;
$_GET['page'] = $page;
return menu_execute_active_handler('node/' . $node->nid, FALSE);
}
return MENU_NOT_FOUND;
}
function comment_get_recent($number = 10) {
$query = db_select('comment', 'c');
$query
->innerJoin('node', 'n', 'n.nid = c.nid');
$query
->addTag('node_access');
$comments = $query
->fields('c')
->condition('c.status', COMMENT_PUBLISHED)
->condition('n.status', NODE_PUBLISHED)
->orderBy('c.created', 'DESC')
->orderBy('c.cid', 'DESC')
->range(0, $number)
->execute()
->fetchAll();
return $comments ? $comments : array();
}
function comment_new_page_count($num_comments, $new_replies, $node) {
$mode = variable_get('comment_default_mode_' . $node->type, COMMENT_MODE_THREADED);
$comments_per_page = variable_get('comment_default_per_page_' . $node->type, 50);
$pagenum = NULL;
$flat = $mode == COMMENT_MODE_FLAT ? TRUE : FALSE;
if ($num_comments <= $comments_per_page) {
$pageno = 0;
}
elseif ($flat) {
$count = $num_comments - $new_replies;
$pageno = $count / $comments_per_page;
}
else {
$unread_threads_query = db_select('comment')
->fields('comment', array(
'thread',
))
->condition('nid', $node->nid)
->condition('status', COMMENT_PUBLISHED)
->orderBy('created', 'DESC')
->orderBy('cid', 'DESC')
->range(0, $new_replies);
$first_thread = db_select($unread_threads_query, 'thread')
->fields('thread', array(
'thread',
))
->orderBy('SUBSTRING(thread, 1, (LENGTH(thread) - 1))')
->range(0, 1)
->execute()
->fetchField();
$first_thread = substr($first_thread, 0, -1);
$count = db_query('SELECT COUNT(*) FROM {comment} WHERE nid = :nid AND status = :status AND SUBSTRING(thread, 1, (LENGTH(thread) - 1)) < :thread', array(
':status' => COMMENT_PUBLISHED,
':nid' => $node->nid,
':thread' => $first_thread,
))
->fetchField();
$pageno = $count / $comments_per_page;
}
if ($pageno >= 1) {
$pagenum = array(
'page' => intval($pageno),
);
}
return $pagenum;
}
function theme_comment_block() {
$items = array();
$number = variable_get('comment_block_count', 10);
foreach (comment_get_recent($number) as $comment) {
$items[] = l($comment->subject, 'comment/' . $comment->cid, array(
'fragment' => 'comment-' . $comment->cid,
)) . ' <span>' . t('@time ago', array(
'@time' => format_interval(REQUEST_TIME - $comment->changed),
)) . '</span>';
}
if ($items) {
return theme('item_list', array(
'items' => $items,
));
}
else {
return t('No comments available.');
}
}
function comment_node_view($node, $view_mode) {
$links = array();
if ($node->comment != COMMENT_NODE_HIDDEN) {
if ($view_mode == 'rss') {
$node->rss_elements[] = array(
'key' => 'comments',
'value' => url('node/' . $node->nid, array(
'fragment' => 'comments',
'absolute' => TRUE,
)),
);
}
elseif ($view_mode == 'teaser') {
if (user_access('access comments')) {
if (!empty($node->comment_count)) {
$links['comment-comments'] = array(
'title' => format_plural($node->comment_count, '1 comment', '@count comments'),
'href' => "node/{$node->nid}",
'attributes' => array(
'title' => t('Jump to the first comment of this posting.'),
),
'fragment' => 'comments',
'html' => TRUE,
);
if ($new = comment_num_new($node->nid)) {
$links['comment-new-comments'] = array(
'title' => format_plural($new, '1 new comment', '@count new comments'),
'href' => "node/{$node->nid}",
'query' => comment_new_page_count($node->comment_count, $new, $node),
'attributes' => array(
'title' => t('Jump to the first new comment of this posting.'),
),
'fragment' => 'new',
'html' => TRUE,
);
}
}
}
if ($node->comment == COMMENT_NODE_OPEN) {
if (user_access('post comments')) {
$links['comment-add'] = array(
'title' => t('Add new comment'),
'href' => "comment/reply/{$node->nid}",
'attributes' => array(
'title' => t('Add a new comment to this page.'),
),
'fragment' => 'comment-form',
);
}
else {
$links['comment_forbidden'] = array(
'title' => theme('comment_post_forbidden', array(
'node' => $node,
)),
'html' => TRUE,
);
}
}
}
elseif ($view_mode != 'search_index' && $view_mode != 'search_result') {
if ($node->comment == COMMENT_NODE_OPEN) {
$comment_form_location = variable_get('comment_form_location_' . $node->type, COMMENT_FORM_BELOW);
if (user_access('post comments')) {
if ($comment_form_location == COMMENT_FORM_SEPARATE_PAGE || !empty($node->comment_count) && user_access('access comments')) {
$links['comment-add'] = array(
'title' => t('Add new comment'),
'attributes' => array(
'title' => t('Share your thoughts and opinions related to this posting.'),
),
'href' => "node/{$node->nid}",
'fragment' => 'comment-form',
);
if ($comment_form_location == COMMENT_FORM_SEPARATE_PAGE) {
$links['comment-add']['href'] = "comment/reply/{$node->nid}";
}
}
}
else {
$links['comment_forbidden'] = array(
'title' => theme('comment_post_forbidden', array(
'node' => $node,
)),
'html' => TRUE,
);
}
}
}
$node->content['links']['comment'] = array(
'#theme' => 'links__node__comment',
'#links' => $links,
'#attributes' => array(
'class' => array(
'links',
'inline',
),
),
);
if ($node->comment && $view_mode == 'full' && node_is_page($node) && empty($node->in_preview)) {
$node->content['comments'] = comment_node_page_additions($node);
}
}
}
function comment_node_page_additions($node) {
$additions = array();
if ($node->comment_count && user_access('access comments') || user_access('administer comments')) {
$mode = variable_get('comment_default_mode_' . $node->type, COMMENT_MODE_THREADED);
$comments_per_page = variable_get('comment_default_per_page_' . $node->type, 50);
if ($cids = comment_get_thread($node, $mode, $comments_per_page)) {
$comments = comment_load_multiple($cids);
comment_prepare_thread($comments);
$build = comment_view_multiple($comments, $node);
$build['pager']['#theme'] = 'pager';
$additions['comments'] = $build;
}
}
if (user_access('post comments') && $node->comment == COMMENT_NODE_OPEN && variable_get('comment_form_location_' . $node->type, COMMENT_FORM_BELOW) == COMMENT_FORM_BELOW) {
$build = drupal_get_form("comment_node_{$node->type}_form", (object) array(
'nid' => $node->nid,
));
$additions['comment_form'] = $build;
}
if ($additions) {
$additions += array(
'#theme' => 'comment_wrapper__node_' . $node->type,
'#node' => $node,
'comments' => array(),
'comment_form' => array(),
);
}
return $additions;
}
function comment_get_thread($node, $mode, $comments_per_page) {
$query = db_select('comment', 'c')
->extend('PagerDefault');
$query
->addField('c', 'cid');
$query
->condition('c.nid', $node->nid)
->addTag('node_access')
->addTag('comment_filter')
->addMetaData('node', $node)
->limit($comments_per_page);
$count_query = db_select('comment', 'c');
$count_query
->addExpression('COUNT(*)');
$count_query
->condition('c.nid', $node->nid)
->addTag('node_access')
->addTag('comment_filter')
->addMetaData('node', $node);
if (!user_access('administer comments')) {
$query
->condition('c.status', COMMENT_PUBLISHED);
$count_query
->condition('c.status', COMMENT_PUBLISHED);
}
if ($mode === COMMENT_MODE_FLAT) {
$query
->orderBy('c.cid', 'ASC');
}
else {
$query
->addExpression('SUBSTRING(c.thread, 1, (LENGTH(c.thread) - 1))', 'torder');
$query
->orderBy('torder', 'ASC');
}
$query
->setCountQuery($count_query);
$cids = $query
->execute()
->fetchCol();
return $cids;
}
function comment_prepare_thread(&$comments) {
$first_new = TRUE;
$divs = 0;
foreach ($comments as $key => $comment) {
if ($first_new && $comment->new != MARK_READ) {
$first_new = FALSE;
$comment->first_new = TRUE;
}
$comment->depth = count(explode('.', $comment->thread)) - 1;
if ($comment->depth > $divs) {
$comment->divs = 1;
$divs++;
}
else {
$comment->divs = $comment->depth - $divs;
while ($comment->depth < $divs) {
$divs--;
}
}
$comments[$key] = $comment;
}
$comments[$key]->divs_final = $divs;
}
function comment_view($comment, $node, $view_mode = 'full', $langcode = NULL) {
if (!isset($langcode)) {
$langcode = $GLOBALS['language_content']->language;
}
comment_build_content($comment, $node, $view_mode, $langcode);
$build = $comment->content;
unset($comment->content);
$build += array(
'#theme' => 'comment__node_' . $node->type,
'#comment' => $comment,
'#node' => $node,
'#view_mode' => $view_mode,
'#language' => $langcode,
);
if (empty($comment->in_preview)) {
$prefix = '';
$is_threaded = isset($comment->divs) && variable_get('comment_default_mode_' . $node->type, COMMENT_MODE_THREADED) == COMMENT_MODE_THREADED;
if (!empty($comment->first_new)) {
$prefix .= "<a id=\"new\"></a>\n";
}
if ($is_threaded) {
$prefix .= $comment->divs <= 0 ? str_repeat('</div>', abs($comment->divs)) : "\n" . '<div class="indented">';
}
$prefix .= "<a id=\"comment-{$comment->cid}\"></a>\n";
$build['#prefix'] = $prefix;
if ($is_threaded && !empty($comment->divs_final)) {
$build['#suffix'] = str_repeat('</div>', $comment->divs_final);
}
}
$type = 'comment';
drupal_alter(array(
'comment_view',
'entity_view',
), $build, $type);
return $build;
}
function comment_build_content($comment, $node, $view_mode = 'full', $langcode = NULL) {
if (!isset($langcode)) {
$langcode = $GLOBALS['language_content']->language;
}
$comment->content = array();
$view_mode = key(entity_view_mode_prepare('comment', array(
$comment->cid => $comment,
), $view_mode, $langcode));
field_attach_prepare_view('comment', array(
$comment->cid => $comment,
), $view_mode, $langcode);
entity_prepare_view('comment', array(
$comment->cid => $comment,
), $langcode);
$comment->content += field_attach_view('comment', $comment, $view_mode, $langcode);
$comment->content['links'] = array(
'#theme' => 'links__comment',
'#pre_render' => array(
'drupal_pre_render_links',
),
'#attributes' => array(
'class' => array(
'links',
'inline',
),
),
);
if (empty($comment->in_preview)) {
$comment->content['links']['comment'] = array(
'#theme' => 'links__comment__comment',
'#links' => comment_links($comment, $node),
'#attributes' => array(
'class' => array(
'links',
'inline',
),
),
);
}
module_invoke_all('comment_view', $comment, $view_mode, $langcode);
module_invoke_all('entity_view', $comment, 'comment', $view_mode, $langcode);
$comment->content += array(
'#view_mode' => $view_mode,
);
}
function comment_links($comment, $node) {
$links = array();
if ($node->comment == COMMENT_NODE_OPEN) {
if (user_access('administer comments') && user_access('post comments')) {
$links['comment-delete'] = array(
'title' => t('delete'),
'href' => "comment/{$comment->cid}/delete",
'html' => TRUE,
);
$links['comment-edit'] = array(
'title' => t('edit'),
'href' => "comment/{$comment->cid}/edit",
'html' => TRUE,
);
$links['comment-reply'] = array(
'title' => t('reply'),
'href' => "comment/reply/{$comment->nid}/{$comment->cid}",
'html' => TRUE,
);
if ($comment->status == COMMENT_NOT_PUBLISHED) {
$links['comment-approve'] = array(
'title' => t('approve'),
'href' => "comment/{$comment->cid}/approve",
'html' => TRUE,
'query' => array(
'token' => drupal_get_token("comment/{$comment->cid}/approve"),
),
);
}
}
elseif (user_access('post comments')) {
if (comment_access('edit', $comment)) {
$links['comment-edit'] = array(
'title' => t('edit'),
'href' => "comment/{$comment->cid}/edit",
'html' => TRUE,
);
}
$links['comment-reply'] = array(
'title' => t('reply'),
'href' => "comment/reply/{$comment->nid}/{$comment->cid}",
'html' => TRUE,
);
}
else {
$links['comment_forbidden']['title'] = theme('comment_post_forbidden', array(
'node' => $node,
));
$links['comment_forbidden']['html'] = TRUE;
}
}
return $links;
}
function comment_view_multiple($comments, $node, $view_mode = 'full', $weight = 0, $langcode = NULL) {
$build = array();
$entities_by_view_mode = entity_view_mode_prepare('comment', $comments, $view_mode, $langcode);
foreach ($entities_by_view_mode as $entity_view_mode => $entities) {
field_attach_prepare_view('comment', $entities, $entity_view_mode, $langcode);
entity_prepare_view('comment', $entities, $langcode);
foreach ($entities as $entity) {
$build[$entity->cid] = comment_view($entity, $node, $entity_view_mode, $langcode);
}
}
foreach ($comments as $comment) {
$build[$comment->cid]['#weight'] = $weight;
$weight++;
}
uasort($build, 'element_sort');
$build['#sorted'] = TRUE;
return $build;
}
function comment_form_node_type_form_alter(&$form, $form_state) {
if (isset($form['type'])) {
$form['comment'] = array(
'#type' => 'fieldset',
'#title' => t('Comment settings'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#group' => 'additional_settings',
'#attributes' => array(
'class' => array(
'comment-node-type-settings-form',
),
),
'#attached' => array(
'js' => array(
drupal_get_path('module', 'comment') . '/comment-node-form.js',
),
),
);
$form['comment']['comment'] = array(
'#type' => 'select',
'#title' => t('Default comment setting for new content'),
'#default_value' => variable_get('comment_' . $form['#node_type']->type, COMMENT_NODE_OPEN),
'#options' => array(
COMMENT_NODE_OPEN => t('Open'),
COMMENT_NODE_CLOSED => t('Closed'),
COMMENT_NODE_HIDDEN => t('Hidden'),
),
);
$form['comment']['comment_default_mode'] = array(
'#type' => 'checkbox',
'#title' => t('Threading'),
'#default_value' => variable_get('comment_default_mode_' . $form['#node_type']->type, COMMENT_MODE_THREADED),
'#description' => t('Show comment replies in a threaded list.'),
);
$form['comment']['comment_default_per_page'] = array(
'#type' => 'select',
'#title' => t('Comments per page'),
'#default_value' => variable_get('comment_default_per_page_' . $form['#node_type']->type, 50),
'#options' => _comment_per_page(),
);
$form['comment']['comment_anonymous'] = array(
'#type' => 'select',
'#title' => t('Anonymous commenting'),
'#default_value' => variable_get('comment_anonymous_' . $form['#node_type']->type, COMMENT_ANONYMOUS_MAYNOT_CONTACT),
'#options' => array(
COMMENT_ANONYMOUS_MAYNOT_CONTACT => t('Anonymous posters may not enter their contact information'),
COMMENT_ANONYMOUS_MAY_CONTACT => t('Anonymous posters may leave their contact information'),
COMMENT_ANONYMOUS_MUST_CONTACT => t('Anonymous posters must leave their contact information'),
),
'#access' => user_access('post comments', drupal_anonymous_user()),
);
$form['comment']['comment_subject_field'] = array(
'#type' => 'checkbox',
'#title' => t('Allow comment title'),
'#default_value' => variable_get('comment_subject_field_' . $form['#node_type']->type, 1),
);
$form['comment']['comment_form_location'] = array(
'#type' => 'checkbox',
'#title' => t('Show reply form on the same page as comments'),
'#default_value' => variable_get('comment_form_location_' . $form['#node_type']->type, COMMENT_FORM_BELOW),
);
$form['comment']['comment_preview'] = array(
'#type' => 'radios',
'#title' => t('Preview comment'),
'#default_value' => variable_get('comment_preview_' . $form['#node_type']->type, DRUPAL_OPTIONAL),
'#options' => array(
DRUPAL_DISABLED => t('Disabled'),
DRUPAL_OPTIONAL => t('Optional'),
DRUPAL_REQUIRED => t('Required'),
),
);
}
}
function comment_form_node_form_alter(&$form, $form_state) {
$node = $form['#node'];
$form['comment_settings'] = array(
'#type' => 'fieldset',
'#access' => user_access('administer comments'),
'#title' => t('Comment settings'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#group' => 'additional_settings',
'#attributes' => array(
'class' => array(
'comment-node-settings-form',
),
),
'#attached' => array(
'js' => array(
drupal_get_path('module', 'comment') . '/comment-node-form.js',
),
),
'#weight' => 30,
);
$comment_count = isset($node->nid) ? db_query('SELECT comment_count FROM {node_comment_statistics} WHERE nid = :nid', array(
':nid' => $node->nid,
))
->fetchField() : 0;
$comment_settings = $node->comment == COMMENT_NODE_HIDDEN && empty($comment_count) ? COMMENT_NODE_CLOSED : $node->comment;
$form['comment_settings']['comment'] = array(
'#type' => 'radios',
'#title' => t('Comments'),
'#title_display' => 'invisible',
'#parents' => array(
'comment',
),
'#default_value' => $comment_settings,
'#options' => array(
COMMENT_NODE_OPEN => t('Open'),
COMMENT_NODE_CLOSED => t('Closed'),
COMMENT_NODE_HIDDEN => t('Hidden'),
),
COMMENT_NODE_OPEN => array(
'#description' => t('Users with the "Post comments" permission can post comments.'),
),
COMMENT_NODE_CLOSED => array(
'#description' => t('Users cannot post comments, but existing comments will be displayed.'),
),
COMMENT_NODE_HIDDEN => array(
'#description' => t('Comments are hidden from view.'),
),
);
if (empty($comment_count)) {
$form['comment_settings']['comment'][COMMENT_NODE_HIDDEN]['#access'] = FALSE;
$form['comment_settings']['comment'][COMMENT_NODE_CLOSED]['#description'] = t('Users cannot post comments.');
}
}
function comment_node_load($nodes, $types) {
$comments_enabled = array();
foreach ($nodes as $node) {
if ($node->comment != COMMENT_NODE_HIDDEN) {
$comments_enabled[] = $node->nid;
}
else {
$node->cid = 0;
$node->last_comment_timestamp = $node->created;
$node->last_comment_name = '';
$node->last_comment_uid = $node->uid;
$node->comment_count = 0;
}
}
if (!empty($comments_enabled)) {
$result = db_query('SELECT nid, cid, last_comment_timestamp, last_comment_name, last_comment_uid, comment_count FROM {node_comment_statistics} WHERE nid IN (:comments_enabled)', array(
':comments_enabled' => $comments_enabled,
));
foreach ($result as $record) {
$nodes[$record->nid]->cid = $record->cid;
$nodes[$record->nid]->last_comment_timestamp = $record->last_comment_timestamp;
$nodes[$record->nid]->last_comment_name = $record->last_comment_name;
$nodes[$record->nid]->last_comment_uid = $record->last_comment_uid;
$nodes[$record->nid]->comment_count = $record->comment_count;
}
}
}
function comment_node_prepare($node) {
if (!isset($node->comment)) {
$node->comment = variable_get("comment_{$node->type}", COMMENT_NODE_OPEN);
}
}
function comment_node_insert($node) {
if (variable_get('comment_maintain_node_statistics', TRUE)) {
db_insert('node_comment_statistics')
->fields(array(
'nid' => $node->nid,
'cid' => 0,
'last_comment_timestamp' => $node->changed,
'last_comment_name' => NULL,
'last_comment_uid' => $node->uid,
'comment_count' => 0,
))
->execute();
}
}
function comment_node_delete($node) {
$cids = db_query('SELECT cid FROM {comment} WHERE nid = :nid', array(
':nid' => $node->nid,
))
->fetchCol();
comment_delete_multiple($cids);
db_delete('node_comment_statistics')
->condition('nid', $node->nid)
->execute();
}
function comment_node_update_index($node) {
$index_comments =& drupal_static(__FUNCTION__);
if ($index_comments === NULL) {
$perms = array(
'access comments' => array(),
'search content' => array(),
);
$result = db_query("SELECT rid, permission FROM {role_permission} WHERE permission IN ('access comments', 'search content')");
foreach ($result as $record) {
$perms[$record->permission][$record->rid] = $record->rid;
}
$index_comments = TRUE;
foreach ($perms['search content'] as $rid) {
if (!isset($perms['access comments'][$rid]) && ($rid <= DRUPAL_AUTHENTICATED_RID || !isset($perms['access comments'][DRUPAL_AUTHENTICATED_RID]))) {
$index_comments = FALSE;
break;
}
}
}
if ($index_comments) {
$mode = variable_get('comment_default_mode_' . $node->type, COMMENT_MODE_THREADED);
$comments_per_page = variable_get('comment_default_per_page_' . $node->type, 50);
if ($node->comment && ($cids = comment_get_thread($node, $mode, $comments_per_page))) {
$comments = comment_load_multiple($cids);
comment_prepare_thread($comments);
$build = comment_view_multiple($comments, $node);
return drupal_render($build);
}
}
return '';
}
function comment_update_index() {
variable_set('node_cron_comments_scale', 1.0 / max(1, db_query('SELECT MAX(comment_count) FROM {node_comment_statistics}')
->fetchField()));
}
function comment_node_search_result($node) {
if (user_access('access comments') && $node->comment != COMMENT_NODE_HIDDEN) {
$comments = db_query('SELECT comment_count FROM {node_comment_statistics} WHERE nid = :nid', array(
'nid' => $node->nid,
))
->fetchField();
if ($node->comment != COMMENT_NODE_CLOSED || $comments > 0) {
return array(
'comment' => format_plural($comments, '1 comment', '@count comments'),
);
}
}
}
function comment_user_cancel($edit, $account, $method) {
switch ($method) {
case 'user_cancel_block_unpublish':
$comments = comment_load_multiple(array(), array(
'uid' => $account->uid,
));
foreach ($comments as $comment) {
$comment->status = 0;
comment_save($comment);
}
break;
case 'user_cancel_reassign':
$comments = comment_load_multiple(array(), array(
'uid' => $account->uid,
));
foreach ($comments as $comment) {
$comment->uid = 0;
comment_save($comment);
}
break;
}
}
function comment_user_delete($account) {
$cids = db_query('SELECT c.cid FROM {comment} c WHERE uid = :uid', array(
':uid' => $account->uid,
))
->fetchCol();
comment_delete_multiple($cids);
}
function comment_access($op, $comment) {
global $user;
if ($op == 'edit') {
return $user->uid && $user->uid == $comment->uid && $comment->status == COMMENT_PUBLISHED && user_access('edit own comments') || user_access('administer comments');
}
}
function comment_save($comment) {
global $user;
$transaction = db_transaction();
try {
$defaults = array(
'mail' => '',
'homepage' => '',
'name' => '',
'status' => user_access('skip comment approval') ? COMMENT_PUBLISHED : COMMENT_NOT_PUBLISHED,
);
foreach ($defaults as $key => $default) {
if (!isset($comment->{$key})) {
$comment->{$key} = $default;
}
}
if (!isset($comment->node_type)) {
$node = node_load($comment->nid);
$comment->node_type = 'comment_node_' . $node->type;
}
if (!empty($comment->cid) && !isset($comment->original)) {
$comment->original = entity_load_unchanged('comment', $comment->cid);
}
field_attach_presave('comment', $comment);
module_invoke_all('comment_presave', $comment);
module_invoke_all('entity_presave', $comment, 'comment');
if ($comment->cid) {
drupal_write_record('comment', $comment, 'cid');
db_ignore_slave();
_comment_update_node_statistics($comment->nid);
field_attach_update('comment', $comment);
module_invoke_all('comment_update', $comment);
module_invoke_all('entity_update', $comment, 'comment');
}
else {
if (!empty($comment->thread)) {
$thread = $comment->thread;
}
elseif ($comment->pid == 0) {
$max = db_query('SELECT MAX(thread) FROM {comment} WHERE nid = :nid', array(
':nid' => $comment->nid,
))
->fetchField();
$max = rtrim($max, '/');
$parts = explode('.', $max);
$firstsegment = $parts[0];
$thread = int2vancode(vancode2int($firstsegment) + 1) . '/';
}
else {
$parent = comment_load($comment->pid);
$parent->thread = (string) rtrim((string) $parent->thread, '/');
$max = db_query("SELECT MAX(thread) FROM {comment} WHERE thread LIKE :thread AND nid = :nid", array(
':thread' => $parent->thread . '.%',
':nid' => $comment->nid,
))
->fetchField();
if ($max == '') {
$thread = $parent->thread . '.' . int2vancode(0) . '/';
}
else {
$max = rtrim($max, '/');
$parts = explode('.', $max);
$parent_depth = count(explode('.', $parent->thread));
$last = $parts[$parent_depth];
$thread = $parent->thread . '.' . int2vancode(vancode2int($last) + 1) . '/';
}
}
if (empty($comment->created)) {
$comment->created = REQUEST_TIME;
}
if (empty($comment->changed)) {
$comment->changed = $comment->created;
}
if ($comment->uid === $user->uid && isset($user->name)) {
$comment->name = $user->name;
}
if (empty($comment->pid)) {
$comment->pid = 0;
}
$comment->thread = $thread;
$comment->hostname = ip_address();
drupal_write_record('comment', $comment);
db_ignore_slave();
_comment_update_node_statistics($comment->nid);
field_attach_insert('comment', $comment);
module_invoke_all('comment_insert', $comment);
module_invoke_all('entity_insert', $comment, 'comment');
}
if ($comment->status == COMMENT_PUBLISHED) {
module_invoke_all('comment_publish', $comment);
}
unset($comment->original);
} catch (Exception $e) {
$transaction
->rollback('comment');
watchdog_exception('comment', $e);
throw $e;
}
}
function comment_delete($cid) {
comment_delete_multiple(array(
$cid,
));
}
function comment_delete_multiple($cids) {
$comments = comment_load_multiple($cids);
if ($comments) {
$transaction = db_transaction();
try {
db_delete('comment')
->condition('cid', array_keys($comments), 'IN')
->execute();
foreach ($comments as $comment) {
field_attach_delete('comment', $comment);
module_invoke_all('comment_delete', $comment);
module_invoke_all('entity_delete', $comment, 'comment');
$child_cids = db_query('SELECT cid FROM {comment} WHERE pid = :cid', array(
':cid' => $comment->cid,
))
->fetchCol();
comment_delete_multiple($child_cids);
_comment_update_node_statistics($comment->nid);
}
} catch (Exception $e) {
$transaction
->rollback();
watchdog_exception('comment', $e);
throw $e;
}
}
}
function comment_load_multiple($cids = array(), $conditions = array(), $reset = FALSE) {
return entity_load('comment', $cids, $conditions, $reset);
}
function comment_load($cid, $reset = FALSE) {
$comment = comment_load_multiple(array(
$cid,
), array(), $reset);
return $comment ? $comment[$cid] : FALSE;
}
class CommentController extends DrupalDefaultEntityController {
protected function buildQuery($ids, $conditions = array(), $revision_id = FALSE) {
$query = parent::buildQuery($ids, $conditions, $revision_id);
$query
->innerJoin('node', 'n', 'base.nid = n.nid');
$query
->addField('n', 'type', 'node_type');
$query
->innerJoin('users', 'u', 'base.uid = u.uid');
$query
->addField('u', 'name', 'registered_name');
$query
->fields('u', array(
'uid',
'signature',
'signature_format',
'picture',
));
return $query;
}
protected function attachLoad(&$comments, $revision_id = FALSE) {
foreach ($comments as $key => $comment) {
$comment->name = $comment->uid ? $comment->registered_name : $comment->name;
$comment->new = node_mark($comment->nid, $comment->changed);
$comment->node_type = 'comment_node_' . $comment->node_type;
$comments[$key] = $comment;
}
parent::attachLoad($comments, $revision_id);
}
}
function comment_num_new($nid, $timestamp = 0) {
global $user;
if ($user->uid) {
if (!$timestamp) {
$timestamp = node_last_viewed($nid);
}
$timestamp = $timestamp > NODE_NEW_LIMIT ? $timestamp : NODE_NEW_LIMIT;
return db_query('SELECT COUNT(cid) FROM {comment} WHERE nid = :nid AND created > :timestamp AND status = :status', array(
':nid' => $nid,
':timestamp' => $timestamp,
':status' => COMMENT_PUBLISHED,
))
->fetchField();
}
else {
return FALSE;
}
}
function comment_get_display_ordinal($cid, $node_type) {
$query = db_select('comment', 'c1');
$query
->innerJoin('comment', 'c2', 'c2.nid = c1.nid');
$query
->addExpression('COUNT(*)', 'count');
$query
->condition('c2.cid', $cid);
if (!user_access('administer comments')) {
$query
->condition('c1.status', COMMENT_PUBLISHED);
}
$mode = variable_get('comment_default_mode_' . $node_type, COMMENT_MODE_THREADED);
if ($mode == COMMENT_MODE_FLAT) {
$query
->condition('c1.cid', $cid, '<');
}
else {
$query
->where('SUBSTRING(c1.thread, 1, (LENGTH(c1.thread) -1)) < SUBSTRING(c2.thread, 1, (LENGTH(c2.thread) -1))');
}
return $query
->execute()
->fetchField();
}
function comment_get_display_page($cid, $node_type) {
$ordinal = comment_get_display_ordinal($cid, $node_type);
$comments_per_page = variable_get('comment_default_per_page_' . $node_type, 50);
return floor($ordinal / $comments_per_page);
}
function comment_edit_page($comment) {
drupal_set_title(t('Edit comment %comment', array(
'%comment' => $comment->subject,
)), PASS_THROUGH);
$node = node_load($comment->nid);
return drupal_get_form("comment_node_{$node->type}_form", $comment);
}
function comment_forms() {
$forms = array();
foreach (node_type_get_types() as $type) {
$forms["comment_node_{$type->type}_form"]['callback'] = 'comment_form';
}
return $forms;
}
function comment_form($form, &$form_state, $comment) {
global $user;
if (!isset($form_state['comment'])) {
$defaults = array(
'name' => '',
'mail' => '',
'homepage' => '',
'subject' => '',
'comment' => '',
'cid' => NULL,
'pid' => NULL,
'language' => LANGUAGE_NONE,
'uid' => 0,
);
foreach ($defaults as $key => $value) {
if (!isset($comment->{$key})) {
$comment->{$key} = $value;
}
}
$form_state['comment'] = $comment;
}
else {
$comment = $form_state['comment'];
}
$node = node_load($comment->nid);
$form['#node'] = $node;
$form['#id'] = drupal_html_id('comment_form');
$form['#attributes']['class'][] = 'comment-form';
$form['#theme'] = array(
'comment_form__node_' . $node->type,
'comment_form',
);
$anonymous_contact = variable_get('comment_anonymous_' . $node->type, COMMENT_ANONYMOUS_MAYNOT_CONTACT);
$is_admin = !empty($comment->cid) && user_access('administer comments');
if (!$user->uid && $anonymous_contact != COMMENT_ANONYMOUS_MAYNOT_CONTACT) {
$form['#attached']['library'][] = array(
'system',
'jquery.cookie',
);
$form['#attributes']['class'][] = 'user-info-from-cookie';
}
if (empty($comment->cid) && empty($comment->pid)) {
$form['#action'] = url('comment/reply/' . $comment->nid);
}
if (isset($form_state['comment_preview'])) {
$form += $form_state['comment_preview'];
}
if ($is_admin) {
$form['author'] = array(
'#type' => 'fieldset',
'#title' => t('Administration'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#weight' => -2,
);
}
else {
$form['author'] = array(
'#weight' => -2,
);
}
if ($is_admin) {
$author = !$comment->uid && $comment->name ? $comment->name : $comment->registered_name;
$status = isset($comment->status) ? $comment->status : COMMENT_NOT_PUBLISHED;
$date = !empty($comment->date) ? $comment->date : format_date($comment->created, 'custom', 'Y-m-d H:i O');
}
else {
if ($user->uid) {
$author = $user->name;
}
else {
$author = $comment->name ? $comment->name : '';
}
$status = user_access('skip comment approval') ? COMMENT_PUBLISHED : COMMENT_NOT_PUBLISHED;
$date = '';
}
if ($is_admin) {
$form['author']['name'] = array(
'#type' => 'textfield',
'#title' => t('Authored by'),
'#default_value' => $author,
'#maxlength' => 60,
'#size' => 30,
'#description' => t('Leave blank for %anonymous.', array(
'%anonymous' => variable_get('anonymous', t('Anonymous')),
)),
'#autocomplete_path' => 'user/autocomplete',
);
}
elseif ($user->uid) {
$form['author']['_author'] = array(
'#type' => 'item',
'#title' => t('Your name'),
'#markup' => theme('username', array(
'account' => $user,
)),
);
$form['author']['name'] = array(
'#type' => 'value',
'#value' => $author,
);
}
else {
$form['author']['name'] = array(
'#type' => 'textfield',
'#title' => t('Your name'),
'#default_value' => $author,
'#required' => !$user->uid && $anonymous_contact == COMMENT_ANONYMOUS_MUST_CONTACT,
'#maxlength' => 60,
'#size' => 30,
);
}
$form['author']['mail'] = array(
'#type' => 'textfield',
'#title' => t('E-mail'),
'#default_value' => $comment->mail,
'#required' => !$user->uid && $anonymous_contact == COMMENT_ANONYMOUS_MUST_CONTACT,
'#maxlength' => 64,
'#size' => 30,
'#description' => t('The content of this field is kept private and will not be shown publicly.'),
'#access' => $is_admin || !$user->uid && $anonymous_contact != COMMENT_ANONYMOUS_MAYNOT_CONTACT,
);
$form['author']['homepage'] = array(
'#type' => 'textfield',
'#title' => t('Homepage'),
'#default_value' => $comment->homepage,
'#maxlength' => 255,
'#size' => 30,
'#access' => $is_admin || !$user->uid && $anonymous_contact != COMMENT_ANONYMOUS_MAYNOT_CONTACT,
);
$form['author']['date'] = array(
'#type' => 'textfield',
'#title' => t('Authored on'),
'#default_value' => $date,
'#maxlength' => 25,
'#size' => 20,
'#access' => $is_admin,
);
$form['author']['status'] = array(
'#type' => 'radios',
'#title' => t('Status'),
'#default_value' => $status,
'#options' => array(
COMMENT_PUBLISHED => t('Published'),
COMMENT_NOT_PUBLISHED => t('Not published'),
),
'#access' => $is_admin,
);
$form['subject'] = array(
'#type' => 'textfield',
'#title' => t('Subject'),
'#maxlength' => 64,
'#default_value' => $comment->subject,
'#access' => variable_get('comment_subject_field_' . $node->type, 1) == 1,
'#weight' => -1,
);
$form['is_anonymous'] = array(
'#type' => 'value',
'#value' => $comment->cid ? !$comment->uid : !$user->uid,
);
foreach (array(
'cid',
'pid',
'nid',
'language',
'uid',
) as $key) {
$form[$key] = array(
'#type' => 'value',
'#value' => $comment->{$key},
);
}
$form['node_type'] = array(
'#type' => 'value',
'#value' => 'comment_node_' . $node->type,
);
$form['actions'] = array(
'#type' => 'actions',
);
$form['actions']['submit'] = array(
'#type' => 'submit',
'#value' => t('Save'),
'#access' => $comment->cid && user_access('administer comments') || variable_get('comment_preview_' . $node->type, DRUPAL_OPTIONAL) != DRUPAL_REQUIRED || isset($form_state['comment_preview']),
'#weight' => 19,
);
$form['actions']['preview'] = array(
'#type' => 'submit',
'#value' => t('Preview'),
'#access' => variable_get('comment_preview_' . $node->type, DRUPAL_OPTIONAL) != DRUPAL_DISABLED,
'#weight' => 20,
'#submit' => array(
'comment_form_build_preview',
),
);
$comment->node_type = 'comment_node_' . $node->type;
$langcode = entity_language('comment', $comment);
field_attach_form('comment', $comment, $form, $form_state, $langcode);
return $form;
}
function comment_form_build_preview($form, &$form_state) {
$comment = comment_form_submit_build_comment($form, $form_state);
$form_state['comment_preview'] = comment_preview($comment);
$form_state['rebuild'] = TRUE;
}
function comment_preview($comment) {
global $user;
drupal_set_title(t('Preview comment'), PASS_THROUGH);
$node = node_load($comment->nid);
if (!form_get_errors()) {
$comment_body = field_get_items('comment', $comment, 'comment_body');
$comment->format = $comment_body[0]['format'];
if (!empty($comment->name)) {
$account = user_load_by_name($comment->name);
}
elseif ($user->uid && empty($comment->is_anonymous)) {
$account = $user;
}
if (!empty($account->uid)) {
$comment->uid = $account->uid;
$comment->name = check_plain($account->name);
$comment->signature = $account->signature;
$comment->signature_format = $account->signature_format;
$comment->picture = $account->picture;
}
elseif (empty($comment->name)) {
$comment->name = variable_get('anonymous', t('Anonymous'));
}
$comment->created = !empty($comment->created) ? $comment->created : REQUEST_TIME;
$comment->changed = REQUEST_TIME;
$comment->in_preview = TRUE;
$comment_build = comment_view($comment, $node);
$comment_build['#weight'] = -100;
$form['comment_preview'] = $comment_build;
}
if ($comment->pid) {
$build = array();
if ($comments = comment_load_multiple(array(
$comment->pid,
), array(
'status' => COMMENT_PUBLISHED,
))) {
$parent_comment = $comments[$comment->pid];
$build = comment_view($parent_comment, $node);
}
}
else {
$build = node_view($node);
}
$form['comment_output_below'] = $build;
$form['comment_output_below']['#weight'] = 100;
return $form;
}
function comment_form_validate($form, &$form_state) {
global $user;
entity_form_field_validate('comment', $form, $form_state);
if (!empty($form_state['values']['cid'])) {
$account = user_load_by_name($form_state['values']['name']);
$form_state['values']['uid'] = $account ? $account->uid : 0;
if ($form_state['values']['date'] && strtotime($form_state['values']['date']) === FALSE) {
form_set_error('date', t('You have to specify a valid date.'));
}
if ($form_state['values']['name'] && !$form_state['values']['is_anonymous'] && !$account) {
form_set_error('name', t('You have to specify a valid author.'));
}
}
elseif ($form_state['values']['is_anonymous']) {
if ($form_state['values']['name']) {
$query = db_select('users', 'u');
$query
->addField('u', 'uid', 'uid');
$taken = $query
->condition('name', db_like($form_state['values']['name']), 'LIKE')
->countQuery()
->execute()
->fetchField();
if ($taken) {
form_set_error('name', t('The name you used belongs to a registered user.'));
}
}
}
if ($form_state['values']['mail'] && !valid_email_address($form_state['values']['mail'])) {
form_set_error('mail', t('The e-mail address you specified is not valid.'));
}
if ($form_state['values']['homepage'] && !valid_url($form_state['values']['homepage'], TRUE)) {
form_set_error('homepage', t('The URL of your homepage is not valid. Remember that it must be fully qualified, i.e. of the form <code>http://example.com/directory</code>.'));
}
}
function comment_submit($comment) {
if (is_array($comment)) {
$comment += array(
'subject' => '',
);
$comment = (object) $comment;
}
if (empty($comment->date)) {
$comment->date = 'now';
}
$comment->created = strtotime($comment->date);
$comment->changed = REQUEST_TIME;
if (!$comment->is_anonymous && !empty($comment->name) && ($account = user_load_by_name($comment->name))) {
$comment->uid = $account->uid;
}
if ($comment->is_anonymous && (!isset($comment->name) || $comment->name === '')) {
$comment->name = variable_get('anonymous', t('Anonymous'));
}
if (trim($comment->subject) == '') {
$field = field_info_field('comment_body');
$langcode = field_is_translatable('comment', $field) ? entity_language('comment', $comment) : LANGUAGE_NONE;
$comment_body = $comment->comment_body[$langcode][0];
if (isset($comment_body['format'])) {
$comment_text = check_markup($comment_body['value'], $comment_body['format']);
}
else {
$comment_text = check_plain($comment_body['value']);
}
$comment->subject = truncate_utf8(trim(decode_entities(strip_tags($comment_text))), 29, TRUE);
if ($comment->subject == '') {
$comment->subject = t('(No subject)');
}
}
return $comment;
}
function comment_form_submit_build_comment($form, &$form_state) {
$comment = $form_state['comment'];
entity_form_submit_build_entity('comment', $comment, $form, $form_state);
comment_submit($comment);
return $comment;
}
function comment_form_submit($form, &$form_state) {
$node = node_load($form_state['values']['nid']);
$comment = comment_form_submit_build_comment($form, $form_state);
if (user_access('post comments') && (user_access('administer comments') || $node->comment == COMMENT_NODE_OPEN)) {
if (user_is_anonymous()) {
user_cookie_save(array_intersect_key($form_state['values'], array_flip(array(
'name',
'mail',
'homepage',
))));
}
comment_save($comment);
$form_state['values']['cid'] = $comment->cid;
watchdog('content', 'Comment posted: %subject.', array(
'%subject' => $comment->subject,
), WATCHDOG_NOTICE, l(t('view'), 'comment/' . $comment->cid, array(
'fragment' => 'comment-' . $comment->cid,
)));
if ($comment->status == COMMENT_NOT_PUBLISHED) {
if (!user_access('administer comments')) {
drupal_set_message(t('Your comment has been queued for review by site administrators and will be published after approval.'));
}
}
else {
drupal_set_message(t('Your comment has been posted.'));
}
$query = array();
$page = comment_get_display_page($comment->cid, $node->type);
if ($page > 0) {
$query['page'] = $page;
}
$redirect = array(
'node/' . $node->nid,
array(
'query' => $query,
'fragment' => 'comment-' . $comment->cid,
),
);
}
else {
watchdog('content', 'Comment: unauthorized comment submitted or comment submitted to a closed post %subject.', array(
'%subject' => $comment->subject,
), WATCHDOG_WARNING);
drupal_set_message(t('Comment: unauthorized comment submitted or comment submitted to a closed post %subject.', array(
'%subject' => $comment->subject,
)), 'error');
$redirect = 'node/' . $node->nid;
}
$form_state['redirect'] = $redirect;
cache_clear_all();
}
function template_preprocess_comment(&$variables) {
$comment = $variables['elements']['#comment'];
$node = $variables['elements']['#node'];
$variables['comment'] = $comment;
$variables['node'] = $node;
$variables['author'] = theme('username', array(
'account' => $comment,
));
$variables['created'] = format_date($comment->created);
if ($comment->changed == $comment->created) {
$variables['changed'] = $variables['created'];
}
else {
$variables['changed'] = format_date($comment->changed);
}
$variables['new'] = !empty($comment->new) ? t('new') : '';
$variables['picture'] = theme_get_setting('toggle_comment_user_picture') ? theme('user_picture', array(
'account' => $comment,
)) : '';
$variables['signature'] = $comment->signature;
$uri = entity_uri('comment', $comment);
$uri['options'] += array(
'attributes' => array(
'class' => array(
'permalink',
),
'rel' => 'bookmark',
),
);
$variables['title'] = l($comment->subject, $uri['path'], $uri['options']);
$variables['permalink'] = l(t('Permalink'), $uri['path'], $uri['options']);
$variables['submitted'] = t('Submitted by !username on !datetime', array(
'!username' => $variables['author'],
'!datetime' => $variables['created'],
));
field_attach_preprocess('comment', $comment, $variables['elements'], $variables);
foreach (element_children($variables['elements']) as $key) {
$variables['content'][$key] = $variables['elements'][$key];
}
if (isset($comment->in_preview)) {
$variables['status'] = 'comment-preview';
}
else {
$variables['status'] = $comment->status == COMMENT_NOT_PUBLISHED ? 'comment-unpublished' : 'comment-published';
}
if ($variables['status'] != 'comment-published') {
$variables['classes_array'][] = $variables['status'];
}
if ($variables['new']) {
$variables['classes_array'][] = 'comment-new';
}
if (!$comment->uid) {
$variables['classes_array'][] = 'comment-by-anonymous';
}
else {
if ($comment->uid == $variables['node']->uid) {
$variables['classes_array'][] = 'comment-by-node-author';
}
if ($comment->uid == $variables['user']->uid) {
$variables['classes_array'][] = 'comment-by-viewer';
}
}
}
function theme_comment_post_forbidden($variables) {
$node = $variables['node'];
global $user;
$authenticated_post_comments =& drupal_static(__FUNCTION__, NULL);
if (!$user->uid) {
if (!isset($authenticated_post_comments)) {
$comment_roles = user_roles(TRUE, 'post comments');
$authenticated_post_comments = isset($comment_roles[DRUPAL_AUTHENTICATED_RID]);
}
if ($authenticated_post_comments) {
if (variable_get('comment_form_location_' . $node->type, COMMENT_FORM_BELOW) == COMMENT_FORM_SEPARATE_PAGE) {
$destination = array(
'destination' => "comment/reply/{$node->nid}#comment-form",
);
}
else {
$destination = array(
'destination' => "node/{$node->nid}#comment-form",
);
}
if (variable_get('user_register', USER_REGISTER_VISITORS_ADMINISTRATIVE_APPROVAL)) {
return t('<a href="@login">Log in</a> or <a href="@register">register</a> to post comments', array(
'@login' => url('user/login', array(
'query' => $destination,
)),
'@register' => url('user/register', array(
'query' => $destination,
)),
));
}
else {
return t('<a href="@login">Log in</a> to post comments', array(
'@login' => url('user/login', array(
'query' => $destination,
)),
));
}
}
}
}
function template_preprocess_comment_wrapper(&$variables) {
$variables['node'] = $variables['content']['#node'];
$variables['display_mode'] = variable_get('comment_default_mode_' . $variables['node']->type, COMMENT_MODE_THREADED);
$variables['content'] += array(
'comment_form' => array(),
);
}
function _comment_get_modes() {
return array(
COMMENT_MODE_FLAT => t('Flat list'),
COMMENT_MODE_THREADED => t('Threaded list'),
);
}
function _comment_per_page() {
return drupal_map_assoc(array(
10,
30,
50,
70,
90,
150,
200,
250,
300,
));
}
function _comment_update_node_statistics($nid) {
if (!variable_get('comment_maintain_node_statistics', TRUE)) {
return;
}
$count = db_query('SELECT COUNT(cid) FROM {comment} WHERE nid = :nid AND status = :status', array(
':nid' => $nid,
':status' => COMMENT_PUBLISHED,
))
->fetchField();
if ($count > 0) {
$last_reply = db_query_range('SELECT cid, name, changed, uid FROM {comment} WHERE nid = :nid AND status = :status ORDER BY cid DESC', 0, 1, array(
':nid' => $nid,
':status' => COMMENT_PUBLISHED,
))
->fetchObject();
db_update('node_comment_statistics')
->fields(array(
'cid' => $last_reply->cid,
'comment_count' => $count,
'last_comment_timestamp' => $last_reply->changed,
'last_comment_name' => $last_reply->uid ? '' : $last_reply->name,
'last_comment_uid' => $last_reply->uid,
))
->condition('nid', $nid)
->execute();
}
else {
$node = db_query('SELECT uid, created FROM {node} WHERE nid = :nid', array(
':nid' => $nid,
))
->fetchObject();
db_update('node_comment_statistics')
->fields(array(
'cid' => 0,
'comment_count' => 0,
'last_comment_timestamp' => $node->created,
'last_comment_name' => '',
'last_comment_uid' => $node->uid,
))
->condition('nid', $nid)
->execute();
}
}
function int2vancode($i = 0) {
$num = base_convert((int) $i, 10, 36);
$length = strlen($num);
return chr($length + ord('0') - 1) . $num;
}
function vancode2int($c = '00') {
return base_convert(substr($c, 1), 36, 10);
}
function comment_action_info() {
return array(
'comment_publish_action' => array(
'label' => t('Publish comment'),
'type' => 'comment',
'configurable' => FALSE,
'behavior' => array(
'changes_property',
),
'triggers' => array(
'comment_presave',
'comment_insert',
'comment_update',
),
),
'comment_unpublish_action' => array(
'label' => t('Unpublish comment'),
'type' => 'comment',
'configurable' => FALSE,
'behavior' => array(
'changes_property',
),
'triggers' => array(
'comment_presave',
'comment_insert',
'comment_update',
),
),
'comment_unpublish_by_keyword_action' => array(
'label' => t('Unpublish comment containing keyword(s)'),
'type' => 'comment',
'configurable' => TRUE,
'behavior' => array(
'changes_property',
),
'triggers' => array(
'comment_presave',
'comment_insert',
'comment_update',
),
),
'comment_save_action' => array(
'label' => t('Save comment'),
'type' => 'comment',
'configurable' => FALSE,
'triggers' => array(
'comment_insert',
'comment_update',
),
),
);
}
function comment_publish_action($comment, $context = array()) {
if (isset($comment->subject)) {
$subject = $comment->subject;
$comment->status = COMMENT_PUBLISHED;
}
else {
$cid = $context['cid'];
$subject = db_query('SELECT subject FROM {comment} WHERE cid = :cid', array(
':cid' => $cid,
))
->fetchField();
db_update('comment')
->fields(array(
'status' => COMMENT_PUBLISHED,
))
->condition('cid', $cid)
->execute();
}
watchdog('action', 'Published comment %subject.', array(
'%subject' => $subject,
));
}
function comment_unpublish_action($comment, $context = array()) {
if (isset($comment->subject)) {
$subject = $comment->subject;
$comment->status = COMMENT_NOT_PUBLISHED;
}
else {
$cid = $context['cid'];
$subject = db_query('SELECT subject FROM {comment} WHERE cid = :cid', array(
':cid' => $cid,
))
->fetchField();
db_update('comment')
->fields(array(
'status' => COMMENT_NOT_PUBLISHED,
))
->condition('cid', $cid)
->execute();
}
watchdog('action', 'Unpublished comment %subject.', array(
'%subject' => $subject,
));
}
function comment_unpublish_by_keyword_action($comment, $context) {
$node = node_load($comment->nid);
$build = comment_view($comment, $node);
$text = drupal_render($build);
foreach ($context['keywords'] as $keyword) {
if (strpos($text, $keyword) !== FALSE) {
$comment->status = COMMENT_NOT_PUBLISHED;
comment_save($comment);
watchdog('action', 'Unpublished comment %subject.', array(
'%subject' => $comment->subject,
));
break;
}
}
}
function comment_unpublish_by_keyword_action_form($context) {
$form['keywords'] = array(
'#title' => t('Keywords'),
'#type' => 'textarea',
'#description' => t('The comment will be unpublished if it contains any of the phrases above. Use a case-sensitive, comma-separated list of phrases. Example: funny, bungee jumping, "Company, Inc."'),
'#default_value' => isset($context['keywords']) ? drupal_implode_tags($context['keywords']) : '',
);
return $form;
}
function comment_unpublish_by_keyword_action_submit($form, $form_state) {
return array(
'keywords' => drupal_explode_tags($form_state['values']['keywords']),
);
}
function comment_save_action($comment) {
comment_save($comment);
cache_clear_all();
watchdog('action', 'Saved comment %title', array(
'%title' => $comment->subject,
));
}
function comment_ranking() {
return array(
'comments' => array(
'title' => t('Number of comments'),
'join' => array(
'type' => 'LEFT',
'table' => 'node_comment_statistics',
'alias' => 'node_comment_statistics',
'on' => 'node_comment_statistics.nid = i.sid',
),
'score' => '2.0 - 2.0 / (1.0 + node_comment_statistics.comment_count * CAST(:scale AS DECIMAL))',
'arguments' => array(
':scale' => variable_get('node_cron_comments_scale', 0),
),
),
);
}
function comment_rdf_mapping() {
return array(
array(
'type' => 'comment',
'bundle' => RDF_DEFAULT_BUNDLE,
'mapping' => array(
'rdftype' => array(
'sioc:Post',
'sioct:Comment',
),
'title' => array(
'predicates' => array(
'dc:title',
),
),
'created' => array(
'predicates' => array(
'dc:date',
'dc:created',
),
'datatype' => 'xsd:dateTime',
'callback' => 'date_iso8601',
),
'changed' => array(
'predicates' => array(
'dc:modified',
),
'datatype' => 'xsd:dateTime',
'callback' => 'date_iso8601',
),
'comment_body' => array(
'predicates' => array(
'content:encoded',
),
),
'pid' => array(
'predicates' => array(
'sioc:reply_of',
),
'type' => 'rel',
),
'uid' => array(
'predicates' => array(
'sioc:has_creator',
),
'type' => 'rel',
),
'name' => array(
'predicates' => array(
'foaf:name',
),
),
),
),
);
}
function comment_file_download_access($field, $entity_type, $entity) {
if ($entity_type == 'comment') {
if (user_access('access comments') && $entity->status == COMMENT_PUBLISHED || user_access('administer comments')) {
$node = node_load($entity->nid);
return node_access('view', $node);
}
return FALSE;
}
}