diff --git a/modules/comment/comment.install b/modules/comment/comment.install index 0213808..a189729 100644 --- a/modules/comment/comment.install +++ b/modules/comment/comment.install @@ -17,15 +17,15 @@ function comment_uninstall() { $node_types = array_keys(node_type_get_types()); foreach ($node_types as $node_type) { field_attach_delete_bundle('comment', 'comment_node_' . $node_type); - variable_del('comment_' . $node_type); - variable_del('comment_anonymous_' . $node_type); - variable_del('comment_controls_' . $node_type); - variable_del('comment_default_mode_' . $node_type); - variable_del('comment_default_order_' . $node_type); - variable_del('comment_default_per_page_' . $node_type); - variable_del('comment_form_location_' . $node_type); - variable_del('comment_preview_' . $node_type); - variable_del('comment_subject_field_' . $node_type); + variable_del('comment_node_' . $node_type); + variable_del('comment_anonymous_node_' . $node_type); + variable_del('comment_controls_node_' . $node_type); + variable_del('comment_default_mode_node_' . $node_type); + variable_del('comment_default_order_node_' . $node_type); + variable_del('comment_default_per_page_node_' . $node_type); + variable_del('comment_form_location_node_' . $node_type); + variable_del('comment_preview_node_' . $node_type); + variable_del('comment_subject_field_node_' . $node_type); } }  @@ -195,10 +195,17 @@ function comment_schema() { ), );  - $schema['node_comment_statistics'] = array( + $schema['comment_entity_statistics'] = array( 'description' => 'Maintains statistics of node and comments posts to show "new" and "updated" flags.', 'fields' => array( - 'nid' => array( + 'entity_type' => array( + 'type' => 'varchar', + 'length' => 128, + 'not null' => TRUE, + 'default' => '', + 'description' => 'The entity type', + ), + 'entity_id' => array( 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, @@ -237,9 +244,10 @@ function comment_schema() { 'description' => 'The total number of comments on this node.', ), ), - 'primary key' => array('nid'), + 'primary key' => array('entity_id'), 'indexes' => array( - 'node_comment_timestamp' => array('last_comment_timestamp'), + 'entity_type' => array('entity_type'), + 'entity_comment_timestamp' => array('last_comment_timestamp'), 'comment_count' => array('comment_count'), 'last_comment_uid' => array('last_comment_uid'), ), @@ -259,3 +267,53 @@ function comment_schema() {  return $schema; } + +/** + * Rename comment/node variable to comment/entity. + */ +function comment_update_8000() { + foreach (node_type_get_types() as $node_type) { + $old_keys[] = 'comment_'; + $old_keys[] = 'comment_default_mode_'; + $old_keys[] = 'comment_default_per_page_'; + $old_keys[] = 'comment_anonymous_'; + $old_keys[] = 'comment_subject_field_'; + $old_keys[] = 'comment_form_location_'; + $old_keys[] = 'comment_preview_'; + foreach ($old_keys as $old_key) { + $new_key = "{$old_key}_node_{$node_type->type}"; + $old_key = "{$old_key}_{$node_type->type}"; + $variable = variable_get($old_key); + variable_set($new_key, $variable); + variable_del($old_key); + } + } +} + +/** + * Update table {node_comment_statistics}. + */ +function comment_update_8001() { + # Rename {node_comment_statistics} to {comment_entity_statistics} + db_rename_table('node_comment_statistics', 'comment_entity_statistics'); + + # Add field entity_type + $comment_schema = comment_schema(); + $entity_column = $comment_schema['comment_entity_statistics']['fields']['entity_type']; + db_add_field('comment_entity_statistics', 'entity_type', $entity_column); + + # Set entity_type to 'node' + db_update('comment_entity_statistics') + ->fields(array('entity_type' => 'node')) + ->execute(); + + # Rename nid to entity_id + $entity_id_column = $comment_schema['comment_entity_statistics']['fields']['entity_id']; + db_change_field('comment_entity_statistics', 'nid', 'entity_id', $entity_id_column); +} + +/** + * Rename variable names + */ +function ___comment_update_8002() { +} diff --git a/modules/comment/comment.module b/modules/comment/comment.module index ae9278c..cfeff4f 100644 --- a/modules/comment/comment.module +++ b/modules/comment/comment.module @@ -57,17 +57,17 @@ define('COMMENT_FORM_BELOW', 1); /** * Comments for this node are hidden. */ -define('COMMENT_NODE_HIDDEN', 0); +define('COMMENT_ENTITY_HIDDEN', 0);  /** * Comments for this node are closed. */ -define('COMMENT_NODE_CLOSED', 1); +define('COMMENT_ENTITY_CLOSED', 1);  /** * Comments for this node are open. */ -define('COMMENT_NODE_OPEN', 2); +define('COMMENT_ENTITY_OPEN', 2);  /** * Implements hook_help(). @@ -609,143 +609,158 @@ function theme_comment_block() { }  /** - * Implements hook_node_view(). + * @TODO: Implements hook_entity_view(). */ -function comment_node_view($node, $view_mode) { - $links = array(); +function comment_entity_view($entity, $entity_type, $view_mode, $langcode) { + // Entity does not support comment, we do nothing + if (!isset($entity->comment)) { + return; + }  - if ($node->comment != COMMENT_NODE_HIDDEN) { - if ($view_mode == 'rss') { - // Add a comments RSS element which is a URL to the comments of this node. - $node->rss_elements[] = array( - 'key' => 'comments', - 'value' => url('node/' . $node->nid, array('fragment' => 'comments', 'absolute' => TRUE)) - ); - } - elseif ($view_mode == 'teaser') { - // Teaser view: display the number of comments that have been posted, - // or a link to add new comments if the user has permission, the node - // is open to new comments, and there currently are none. - 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', + // Comment is hidden, we do nothing + if ($entity->comment == COMMENT_ENTITY_HIDDEN) { + return; + } + + $entity_info = entity_get_info($entity_type); + $id_key = $entity_info['entity keys']['id']; + $bundle_key = $entity_info['entity keys']['bundle']; + + if ($view_mode === 'rss') { # TODO +// // Add a comments RSS element which is a URL to the comments of this node. +// $node->rss_elements[] = array( +// 'key' => 'comments', +// 'value' => url('node/' . $node->nid, array('fragment' => 'comments', 'absolute' => TRUE)) +// ); + } + elseif ($view_mode === 'teaser') { + // Teaser view: display the number of comments that have been posted, + // or a link to add new comments if the user has permission, the node + // is open to new comments, and there currently are none. + if (user_access('access comments')) { + if (!empty($entity->comment_count)) { + $links['comment-comments'] = array( + 'title' => format_plural($entity->comment_count, '1 comment', '@count comments'), + 'href' => $entity_type . '/' . $entity->{$id_key}, # @TODO: Check this + 'attributes' => array('title' => t('Jump to the first comment of this posting.')), + 'fragment' => 'comments', + 'html' => TRUE, + ); + // Show a link to the first new comment. + if ($new = comment_num_new($entity->{$id_key})) { + $links['comment-new-comments'] = array( + 'title' => format_plural($new, '1 new comment', '@count new comments'), + 'href' => $entity_type . '/' . $entity->{$id_key}, # @TODO: Check this + 'query' => comment_new_page_count($entity->comment_count, $new, $entity), + 'attributes' => array('title' => t('Jump to the first new comment of this posting.')), + 'fragment' => 'new', 'html' => TRUE, ); - // Show a link to the first new comment. - 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')) { + } + if ($entity->comment == COMMENT_ENTITY_OPEN) { + if (user_access('post comments')) { + $links['comment-add'] = array( + 'title' => t('Add new comment'), + 'href' => "comment/reply/{$entity_type}/{$entity->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('entity' => $entity, 'entity_type' => $entity_type)), + 'html' => TRUE, + ); + } + } + } + elseif ($view_mode != 'search_index' && $view_mode != 'search_result') { + // Node in other view modes: add a "post comment" link if the user is + // allowed to post comments and if this node is allowing new comments. + // But we don't want this link if we're building the node for search + // indexing or constructing a search result excerpt. + if ($entity->comment == COMMENT_ENTITY_OPEN) { + if (user_access('post comments')) { + $comment_form_location = variable_get("comment_form_location_{$entity_type}_" . $entity->{$bundle_key}, COMMENT_FORM_BELOW); +  + // Show the "post comment" link if the form is on another page, or + // if there are existing comments that the link will skip past. + if ($comment_form_location == COMMENT_FORM_SEPARATE_PAGE || (!empty($entity->comment_count) && user_access('access 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.')), + 'attributes' => array('title' => t('Share your thoughts and opinions related to this posting.')), + 'href' => $entity_type . '/' . $entity->{$id_key}, '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') { - // Node in other view modes: add a "post comment" link if the user is - // allowed to post comments and if this node is allowing new comments. - // But we don't want this link if we're building the node for search - // indexing or constructing a search result excerpt. - if ($node->comment == COMMENT_NODE_OPEN) { - $comment_form_location = variable_get('comment_form_location_' . $node->type, COMMENT_FORM_BELOW); - if (user_access('post comments')) { - // Show the "post comment" link if the form is on another page, or - // if there are existing comments that the link will skip past. - 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"; - } + if ($comment_form_location == COMMENT_FORM_SEPARATE_PAGE) { + $links['comment-add']['href'] = "comment/reply/{$entity_type}/" . $entity->{$id_key}; } } - else { - $links['comment-forbidden'] = array( - 'title' => theme('comment_post_forbidden', array('node' => $node)), - 'html' => TRUE, - ); - } + } + else { + $links['comment-forbidden'] = array( + 'title' => theme('comment_post_forbidden', array('entity' => $entity, 'entity_type' => $entity_type)), + 'html' => TRUE, + ); } } + }  - $node->content['links']['comment'] = array( - '#theme' => 'links__node__comment', - '#links' => $links, - '#attributes' => array('class' => array('links', 'inline')), - ); + $entity->content['links']['comment'] = array( + '#theme' => 'links__node__comment', + '#links' => $links, + '#attributes' => array('class' => array('links', 'inline')), + );  - // Only append comments when we are building a node on its own node detail - // page. We compare $node and $page_node to ensure that comments are not - // appended to other nodes shown on the page, for example a node_reference - // displayed in 'full' view mode within another node. - if ($node->comment && $view_mode == 'full' && node_is_page($node) && empty($node->in_preview)) { - $node->content['comments'] = comment_node_page_additions($node); - } + // Only append comments when we are building a node on its own node detail + // page. We compare $node and $page_node to ensure that comments are not + // appended to other nodes shown on the page, for example a node_reference + // displayed in 'full' view mode within another node. + if ($entity->comment && $view_mode == 'full' && empty($entity->in_preview)) { # @TODO: && node_is_page($entity) + $entity->content['comments'] = comment_entity_page_additions($entity, $entity_type); } }  /** * Build the comment-related elements for node detail pages. * - * @param $node + * @param $entity * A node object. */ -function comment_node_page_additions($node) { +function comment_entity_page_additions($entity, $entity_type) { $additions = array();  + $entity_info = entity_get_info($entity_type); + $id_key = $entity_info['entity keys']['id']; + $bundle_key = $entity_info['entity keys']['bundle']; + // Only attempt to render comments if the node has visible comments. // Unpublished comments are not included in $node->comment_count, so show // comments unconditionally if the user is an administrator. - 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)) { + if (($entity->comment_count && user_access('access comments')) || user_access('administer comments')) { + $mode = variable_get("comment_default_mode_{$entity_type}_" . $entity->{$bundle_key}, COMMENT_MODE_THREADED); + $comments_per_page = variable_get("comment_default_per_page_{$entity_type}_" . $entity->{$bundle_key}, 50); + if ($cids = comment_get_thread($entity, $mode, $comments_per_page)) { $comments = comment_load_multiple($cids); comment_prepare_thread($comments); - $build = comment_view_multiple($comments, $node); + $build = comment_view_multiple($comments, $entity); $build['pager']['#theme'] = 'pager'; $additions['comments'] = $build; } }  // Append comment form if needed. - 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)); + if (user_access('post comments') && $entity->comment == COMMENT_ENTITY_OPEN && (variable_get("comment_form_location_{$entity_type}_". $entity->{$bundle_key}, COMMENT_FORM_BELOW) == COMMENT_FORM_BELOW)) { + $build = drupal_get_form("comment_entity_{$entity_type}_". $entity->{$bundle_key} ."_form", (object) array('entity_type' => $entity_type, 'entity_id' => $entity->nid)); $additions['comment_form'] = $build; }  if ($additions) { $additions += array( - '#theme' => 'comment_wrapper__node_' . $node->type, - '#node' => $node, + '#theme' => 'comment_wrapper__node_' . $entity->type, + '#entity' => $entity, 'comments' => array(), 'comment_form' => array(), ); @@ -1028,7 +1043,7 @@ function comment_build_content($comment, $node, $view_mode = 'full', $langcode = */ function comment_links($comment, $node) { $links = array(); - if ($node->comment == COMMENT_NODE_OPEN) { + if ($node->comment == COMMENT_ENTITY_OPEN) { if (user_access('administer comments') && user_access('post comments')) { $links['comment-delete'] = array( 'title' => t('delete'), @@ -1133,29 +1148,29 @@ function comment_form_node_type_form_alter(&$form, $form_state) { $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), + '#default_value' => variable_get('comment_node_' . $form['#node_type']->type, COMMENT_ENTITY_OPEN), '#options' => array( - COMMENT_NODE_OPEN => t('Open'), - COMMENT_NODE_CLOSED => t('Closed'), - COMMENT_NODE_HIDDEN => t('Hidden'), + COMMENT_ENTITY_OPEN => t('Open'), + COMMENT_ENTITY_CLOSED => t('Closed'), + COMMENT_ENTITY_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), + '#default_value' => variable_get('comment_default_mode_node_' . $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), + '#default_value' => variable_get('comment_default_per_page_node_' . $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), + '#default_value' => variable_get('comment_anonymous_node_' . $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'), @@ -1166,17 +1181,17 @@ function comment_form_node_type_form_alter(&$form, $form_state) { $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), + '#default_value' => variable_get('comment_subject_field_node_' . $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), + '#default_value' => variable_get('comment_form_location_node_' . $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), + '#default_value' => variable_get('comment_preview_node_' . $form['#node_type']->type, DRUPAL_OPTIONAL), '#options' => array( DRUPAL_DISABLED => t('Disabled'), DRUPAL_OPTIONAL => t('Optional'), @@ -1207,7 +1222,7 @@ function comment_form_node_form_alter(&$form, $form_state) { '#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; + $comment_settings = ($node->comment == COMMENT_ENTITY_HIDDEN && empty($comment_count)) ? COMMENT_ENTITY_CLOSED : $node->comment; $form['comment_settings']['comment'] = array( '#type' => 'radios', '#title' => t('Comments'), @@ -1215,60 +1230,68 @@ function comment_form_node_form_alter(&$form, $form_state) { '#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_ENTITY_OPEN => t('Open'), + COMMENT_ENTITY_CLOSED => t('Closed'), + COMMENT_ENTITY_HIDDEN => t('Hidden'), ), - COMMENT_NODE_OPEN => array( + COMMENT_ENTITY_OPEN => array( '#description' => t('Users with the "Post comments" permission can post comments.'), ), - COMMENT_NODE_CLOSED => array( + COMMENT_ENTITY_CLOSED => array( '#description' => t('Users cannot post comments, but existing comments will be displayed.'), ), - COMMENT_NODE_HIDDEN => array( + COMMENT_ENTITY_HIDDEN => array( '#description' => t('Comments are hidden from view.'), ), ); // If the node doesn't have any comments, the "hidden" option makes no // sense, so don't even bother presenting it to the user. if (empty($comment_count)) { - unset($form['comment_settings']['comment']['#options'][COMMENT_NODE_HIDDEN]); - unset($form['comment_settings']['comment'][COMMENT_NODE_HIDDEN]); - $form['comment_settings']['comment'][COMMENT_NODE_CLOSED]['#description'] = t('Users cannot post comments.'); + unset($form['comment_settings']['comment']['#options'][COMMENT_ENTITY_HIDDEN]); + unset($form['comment_settings']['comment'][COMMENT_ENTITY_HIDDEN]); + $form['comment_settings']['comment'][COMMENT_ENTITY_CLOSED]['#description'] = t('Users cannot post comments.'); } }  /** - * Implements hook_node_load(). + * Implements hook_entity_load(). */ -function comment_node_load($nodes, $types) { - $comments_enabled = array(); +function comment_entity_load($entities, $entity_type) { + $entity_info = entity_get_info($entity_type);  - // Check if comments are enabled for each node. If comments are disabled, - // assign values without hitting the database. - foreach ($nodes as $node) { + // Entity does not support comment, we do nothing. + if (empty($entity_info['comment'])) { + return; + } + + # dsm($entity_info); return; + $id_field = $entity_info['entity keys']['id']; + + $comments_enabled = array(); + foreach ($entities as $entity) { // Store whether comments are enabled for this node. - if ($node->comment != COMMENT_NODE_HIDDEN) { - $comments_enabled[] = $node->nid; + if ($entity->comment != COMMENT_ENTITY_HIDDEN) { + $comments_enabled[] = $entity->{$id_field}; } else { - $node->cid = 0; - $node->last_comment_timestamp = $node->created; - $node->last_comment_name = ''; - $node->last_comment_uid = $node->uid; - $node->comment_count = 0; + $entity->cid = 0; + $entity->last_comment_timestamp = isset($entity->created) ? $entity->created : NULL; + $entity->last_comment_name = ''; + $entity->last_comment_uid = $entity->uid; + $entity->last_comment_uid = isset($entity->uid) ? $entity->uid : 0; + $entity->comment_count = 0; } }  // For nodes with comments enabled, fetch information from the database. 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)); + $result = db_query('SELECT cid, entity_id, last_comment_timestamp, last_comment_name, last_comment_uid, comment_count FROM {comment_entity_statistics} WHERE entity_type = :entity_type AND entity_id IN (:comments_enabled)', array(':entity_type' => $entity_type, ':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; + $entities[$record->entity_id]->cid = $record->cid; + $entities[$record->entity_id]->last_comment_timestamp = $record->last_comment_timestamp; + $entities[$record->entity_id]->last_comment_name = $record->last_comment_name; + $entities[$record->entity_id]->last_comment_uid = $record->last_comment_uid; + $entities[$record->entity_id]->comment_count = $record->comment_count; } } } @@ -1278,7 +1301,7 @@ function comment_node_load($nodes, $types) { */ function comment_node_prepare($node) { if (!isset($node->comment)) { - $node->comment = variable_get("comment_$node->type", COMMENT_NODE_OPEN); + $node->comment = variable_get("comment_$node->type", COMMENT_ENTITY_OPEN); } }  @@ -1367,11 +1390,11 @@ function comment_update_index() { */ function comment_node_search_result($node) { // Do not make a string if comments are hidden. - if (user_access('access comments') && $node->comment != COMMENT_NODE_HIDDEN) { + if (user_access('access comments') && $node->comment != COMMENT_ENTITY_HIDDEN) { $comments = db_query('SELECT comment_count FROM {node_comment_statistics} WHERE nid = :nid', array('nid' => $node->nid))->fetchField(); // Do not make a string if comments are closed and there are currently // zero comments. - if ($node->comment != COMMENT_NODE_CLOSED || $comments > 0) { + if ($node->comment != COMMENT_ENTITY_CLOSED || $comments > 0) { return array('comment' => format_plural($comments, '1 comment', '@count comments')); } } @@ -1440,6 +1463,8 @@ function comment_access($op, $comment) { * @see comment_int_to_alphadecimal() */ function comment_save($comment) { + kpr($comment); + exit; global $user;  $transaction = db_transaction(); @@ -1481,7 +1506,7 @@ function comment_save($comment) { db_ignore_slave();  // Update the {node_comment_statistics} table prior to executing hooks. - _comment_update_node_statistics($comment->nid); + _comment_update_entity_statistics($comment->nid);  field_attach_update('comment', $comment); // Allow modules to respond to the updating of a comment. @@ -1562,7 +1587,7 @@ function comment_save($comment) { db_ignore_slave();  // Update the {node_comment_statistics} table prior to executing hooks. - _comment_update_node_statistics($comment->nid); + _comment_update_entity_statistics($comment->nid);  field_attach_insert('comment', $comment);  @@ -1616,7 +1641,7 @@ function comment_delete_multiple($cids) { // Delete the comment's replies. $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); + _comment_update_entity_statistics($comment->nid); } } catch (Exception $e) { @@ -1810,9 +1835,15 @@ function comment_edit_page($comment) { */ function comment_forms() { $forms = array(); - foreach (node_type_get_types() as $type) { - $forms["comment_node_{$type->type}_form"]['callback'] = 'comment_form'; + + foreach (entity_get_info() as $entity_type => $entity_info) { + if (!empty($entity_info['comment'])) { + foreach ($entity_info['bundles'] as $bundle_type => $bundle) { + $forms["comment_entity_{$entity_type}_{$bundle_type}_form"]['callback'] = 'comment_form'; + } + } } + return $forms; }  @@ -1853,14 +1884,18 @@ function comment_form($form, &$form_state, $comment) { $comment = $form_state['comment']; }  - $node = node_load($comment->nid); - $form['#node'] = $node; + $entity_info = entity_get_info($comment->entity_type); + $id_key = $entity_info['entity keys']['id']; + $bundle_key = $entity_info['bundle keys']['bundle']; + $entity = entity_load($comment->entity_type, array($comment->entity_id)); + $entity = reset($entity); + $form['#entity'] = $entity;  - // Use #comment-form as unique jump target, regardless of node type. + // Use #comment-form as unique jump target, regardless of entity/bundle. $form['#id'] = drupal_html_id('comment_form'); - $form['#theme'] = array('comment_form__node_' . $node->type, 'comment_form'); + $form['#theme'] = array("comment_form__entity_{$comment->entity_type}_" . $entity->{$bundle_key}, 'comment_form');  - $anonymous_contact = variable_get('comment_anonymous_' . $node->type, COMMENT_ANONYMOUS_MAYNOT_CONTACT); + $anonymous_contact = variable_get("comment_anonymous_{$comment->entity_type}_" . $entity->{$bundle_key}, COMMENT_ANONYMOUS_MAYNOT_CONTACT); $is_admin = (!empty($comment->cid) && user_access('administer comments'));  if (!$user->uid && $anonymous_contact != COMMENT_ANONYMOUS_MAYNOT_CONTACT) { @@ -1871,7 +1906,7 @@ function comment_form($form, &$form_state, $comment) { // If not replying to a comment, use our dedicated page callback for new // comments on nodes. if (empty($comment->cid) && empty($comment->pid)) { - $form['#action'] = url('comment/reply/' . $comment->nid); + $form['#action'] = url("comment/reply/{$comment->entity_type}/" . $entity->{$id_key}); }  if (isset($form_state['comment_preview'])) { @@ -1991,7 +2026,7 @@ function comment_form($form, &$form_state, $comment) { '#title' => t('Subject'), '#maxlength' => 64, '#default_value' => $comment->subject, - '#access' => variable_get('comment_subject_field_' . $node->type, 1) == 1, + '#access' => variable_get("comment_subject_field_{$comment->entity_type}_" . $entity->{$bundle_key}, 1) == 1, '#weight' => -1, );  @@ -2002,10 +2037,12 @@ function comment_form($form, &$form_state, $comment) { );  // Add internal comment properties. - foreach (array('cid', 'pid', 'nid', 'language', 'uid') as $key) { + foreach (array('cid', 'pid', 'entity_type', 'entity_id', 'language', 'uid') as $key) { $form[$key] = array('#type' => 'value', '#value' => $comment->$key); } - $form['node_type'] = array('#type' => 'value', '#value' => 'comment_node_' . $node->type); + + $form['entity_type'] = array('#type' => 'value', '#value' => $comment->entity_type); + $form['bundle_type'] = array('#type' => 'value', '#value' => $entity->{$bundle_key});  // Only show the save button if comment previews are optional or if we are // already previewing the submission. @@ -2013,19 +2050,19 @@ function comment_form($form, &$form_state, $comment) { $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']), + '#access' => ($comment->cid && user_access('administer comments')) || variable_get('comment_preview_' . $entity->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), + '#access' => (variable_get('comment_preview_' . $entity->type, DRUPAL_OPTIONAL) != DRUPAL_DISABLED), '#weight' => 20, '#submit' => array('comment_form_build_preview'), );  // Attach fields. - $comment->node_type = 'comment_node_' . $node->type; + $comment->node_type = 'comment_node_' . $entity->type; field_attach_form('comment', $comment, $form, $form_state);  return $form; @@ -2213,7 +2250,7 @@ function comment_form_submit_build_comment($form, &$form_state) { 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_access('post comments') && (user_access('administer comments') || $node->comment == COMMENT_ENTITY_OPEN)) { // Save the anonymous user information to a cookie for reuse. if (user_is_anonymous()) { user_cookie_save(array_intersect_key($form_state['values'], array_flip(array('name', 'mail', 'homepage')))); @@ -2371,8 +2408,8 @@ function theme_comment_post_forbidden($variables) { */ function template_preprocess_comment_wrapper(&$variables) { // Provide contextual information. - $variables['node'] = $variables['content']['#node']; - $variables['display_mode'] = variable_get('comment_default_mode_' . $variables['node']->type, COMMENT_MODE_THREADED); + $variables['entity'] = $variables['content']['#entity']; + $variables['display_mode'] = variable_get('comment_default_mode_' . $variables['entity']->type, COMMENT_MODE_THREADED); // The comment form is optional and may not exist. $variables['content'] += array('comment_form' => array()); } @@ -2399,7 +2436,7 @@ function _comment_per_page() { }  /** - * Updates the comment statistics for a given node. This should be called any + * Updates the comment statistics for a given entity. This should be called any * time a comment is added, deleted, or updated. * * The following fields are contained in the node_comment_statistics table. @@ -2408,25 +2445,27 @@ function _comment_per_page() { * - last_comment_uid: the uid of the poster for the last comment for this node or the node authors uid if no comments exists for the node. * - comment_count: the total number of approved/published comments on this node. */ -function _comment_update_node_statistics($nid) { +function _comment_update_entity_statistics($entity_type, $entiy_id) { // Allow bulk updates and inserts to temporarily disable the // maintenance of the {node_comment_statistics} table. - if (!variable_get('comment_maintain_node_statistics', TRUE)) { + if (!variable_get("comment_maintain_{$entity_type}_statistics", TRUE)) { return; }  - $count = db_query('SELECT COUNT(cid) FROM {comment} WHERE nid = :nid AND status = :status', array( - ':nid' => $nid, + $count = db_query('SELECT COUNT(cid) FROM {comment} WHERE entity_type = :entity_type AND entiy_id = :entiy_id AND status = :status', array( + ':entity_type' => $entity_type, + ':entiy_id' => $entiy_id, ':status' => COMMENT_PUBLISHED, ))->fetchField();  if ($count > 0) { // Comments exist. - $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, + $last_reply = db_query_range('SELECT cid, name, changed, uid FROM {comment} WHERE entity_type = :entity_type AND entiy_id = :entiy_id AND status = :status ORDER BY cid DESC', 0, 1, array( + ':entity_type' => $entity_type, + ':entiy_id' => $entiy_id, ':status' => COMMENT_PUBLISHED, ))->fetchObject(); - db_update('node_comment_statistics') + db_update('comment_entity_statistics') ->fields(array( 'cid' => $last_reply->cid, 'comment_count' => $count, @@ -2434,21 +2473,32 @@ function _comment_update_node_statistics($nid) { 'last_comment_name' => $last_reply->uid ? '' : $last_reply->name, 'last_comment_uid' => $last_reply->uid, )) - ->condition('nid', $nid) + ->condition('entity_type', $entity_type) + ->condition('entiy_id', $entiy_id) ->execute(); } else { // Comments do not exist. - $node = db_query('SELECT uid, created FROM {node} WHERE nid = :nid', array(':nid' => $nid))->fetchObject(); - db_update('node_comment_statistics') + $entity_info = entity_get_info($entity_type); + + # Get entity uid, created + $entity = db_select($entity_info['base table'], 'entity') + ->fields('entity', array('uid', 'created')) # @TODO: How are we sure entity has uid and created columns? + ->condition('entity_type', $entity_type) + ->condition('entity_id', $entity_id) + ->execute() + ->fetchObject(); + + db_update('comment_entity_statistics') ->fields(array( 'cid' => 0, 'comment_count' => 0, - 'last_comment_timestamp' => $node->created, + 'last_comment_timestamp' => $entity->created, 'last_comment_name' => '', - 'last_comment_uid' => $node->uid, + 'last_comment_uid' => $entity->uid, )) - ->condition('nid', $nid) + ->condition('entity_type', $entity_type) + ->condition('entity_id', $entity_id) ->execute(); } } @@ -2717,3 +2767,32 @@ function comment_file_download_access($field, $entity_type, $entity) { return FALSE; } } + +/** + * Implements hook_schema_alter(). + * Create comment field to entity base and revision tables. + */ +function comment_schema_alter(&$schema) { + foreach (entity_get_info() as $entity_type => $entity_info) { + if (!empty($entity_info['comment'])) { + foreach (array('base table', 'revision table') as $i) { + if (isset($entity_info[$i])) { + $table_name = $entity_info[$i]; + if (isset($schema[$table_name]) && !isset($schema[$table_name]['fields']['comment'])) { + $schema[$table_name]['fields']['comment'] = array( + 'description' => 'Whether comments are allowed on this node: 0 = no, 1 = closed (read only), 2 = open (read/write).', + 'type' => 'int', + 'not null' => TRUE, + 'default' => 0, + ); + + try { + db_add_field($table_name, 'comment', $schema[$table_name]['fields']['comment']); + } + catch (Exception $e) {} + } + } + } + } + } +} diff --git a/modules/comment/comment.pages.inc b/modules/comment/comment.pages.inc index 7e88bff..851bbe0 100644 --- a/modules/comment/comment.pages.inc +++ b/modules/comment/comment.pages.inc @@ -81,7 +81,7 @@ function comment_reply($node, $pid = NULL) { }  // Should we show the reply box? - if ($node->comment != COMMENT_NODE_OPEN) { + if ($node->comment != COMMENT_ENTITY_OPEN) { drupal_set_message(t("This discussion is closed: you can't post new comments."), 'error'); drupal_goto("node/$node->nid"); } diff --git a/modules/comment/comment.test b/modules/comment/comment.test index 2e96ba3..2a7896e 100644 --- a/modules/comment/comment.test +++ b/modules/comment/comment.test @@ -615,7 +615,7 @@ class CommentInterfaceTest extends CommentHelperCase { * USER_REGISTER_VISITORS. * - contact: COMMENT_ANONYMOUS_MAY_CONTACT or * COMMENT_ANONYMOUS_MAYNOT_CONTACT. - * - comments: COMMENT_NODE_OPEN, COMMENT_NODE_CLOSED, or + * - comments: COMMENT_ENTITY_OPEN, COMMENT_NODE_CLOSED, or * COMMENT_NODE_HIDDEN. * - User permissions: * These are granted or revoked for the user, according to the @@ -637,7 +637,7 @@ class CommentInterfaceTest extends CommentHelperCase { 'form' => COMMENT_FORM_BELOW, 'user_register' => USER_REGISTER_VISITORS, 'contact' => COMMENT_ANONYMOUS_MAY_CONTACT, - 'comments' => COMMENT_NODE_OPEN, + 'comments' => COMMENT_ENTITY_OPEN, 'access comments' => 0, 'post comments' => 0, // Enabled by default, because it's irrelevant for this test. @@ -715,9 +715,9 @@ class CommentInterfaceTest extends CommentHelperCase { COMMENT_ANONYMOUS_MUST_CONTACT => 'required', ); $t_comments = array( - COMMENT_NODE_OPEN => 'open', - COMMENT_NODE_CLOSED => 'closed', - COMMENT_NODE_HIDDEN => 'hidden', + COMMENT_ENTITY_OPEN => 'open', + COMMENT_ENTITY_CLOSED => 'closed', + COMMENT_ENTITY_HIDDEN => 'hidden', ); $verbose = $info; $verbose['form'] = $t_form[$info['form']]; diff --git a/modules/node/node.install b/modules/node/node.install index 3f732a4..48cf50a 100644 --- a/modules/node/node.install +++ b/modules/node/node.install @@ -70,12 +70,6 @@ function node_schema() { 'not null' => TRUE, 'default' => 0, ), - 'comment' => array( - 'description' => 'Whether comments are allowed on this node: 0 = no, 1 = closed (read only), 2 = open (read/write).', - 'type' => 'int', - 'not null' => TRUE, - 'default' => 0, - ), 'promote' => array( 'description' => 'Boolean indicating whether the node should be displayed on the front page.', 'type' => 'int', @@ -234,12 +228,6 @@ function node_schema() { 'not null' => TRUE, 'default' => 1, ), - 'comment' => array( - 'description' => 'Whether comments are allowed on this node (at the time of this revision): 0 = no, 1 = closed (read only), 2 = open (read/write).', - 'type' => 'int', - 'not null' => TRUE, - 'default' => 0, - ), 'promote' => array( 'description' => 'Boolean indicating whether the node (at the time of this revision) should be displayed on the front page.', 'type' => 'int', diff --git a/modules/node/node.module b/modules/node/node.module index 0c3cfb7..45b5ce0 100644 --- a/modules/node/node.module +++ b/modules/node/node.module @@ -172,6 +172,7 @@ function node_entity_info() { 'revision table' => 'node_revision', 'uri callback' => 'node_uri', 'fieldable' => TRUE, + 'comment' => TRUE, 'entity keys' => array( 'id' => 'nid', 'revision' => 'vid', diff --git a/themes/bartik/templates/comment-wrapper.tpl.php b/themes/bartik/templates/comment-wrapper.tpl.php index 864dc41..1a58a9a 100644 --- a/themes/bartik/templates/comment-wrapper.tpl.php +++ b/themes/bartik/templates/comment-wrapper.tpl.php @@ -36,7 +36,7 @@ */ ?>
> - type != 'forum'): ?> + type != 'forum'): ?>