- Patch #504666 by catch, yched, et al: make comments fieldable. Oh my. Bye bye comments as nodes?

merge-requests/26/head
Dries Buytaert 2009-07-31 19:44:21 +00:00
parent 04d7eb4acb
commit a8a15bcd90
11 changed files with 199 additions and 84 deletions

View File

@ -95,7 +95,7 @@ Drupal 7.0, xxxx-xx-xx (development version)
on as contributed themes (http://drupal.org/project/bluemarine,
http://drupal.org/project/chameleon and http://drupal.org/project/pushbutton).
* Added Stark theme to make analyzing Drupal's default HTML and CSS easier.
* Added Slate theme as the default administration interface theme.
* Added Seven theme as the default administration interface theme.
- File handling:
* Files are now first class Drupal objects with file_load(), file_save(),
and file_validate() functions and corresponding hooks.
@ -120,7 +120,8 @@ Drupal 7.0, xxxx-xx-xx (development version)
* Modules can declare RDF namespaces which are serialized in the <html> tag
for RDFa support.
- Field API:
* Custom data fields may be attached to nodes and users, and taxonomy terms.
* Custom data fields may be attached to nodes, users, comments and taxonomy
terms.
* Node bodies and teasers are now Field API fields instead of
being a hard-coded property of node objects.
* In addition, any other object type may register with Field API

View File

@ -244,12 +244,12 @@ class NewDefaultThemeBlocks extends DrupalWebTestCase {
$this->drupalLogin($admin_user);
// Ensure no other theme's blocks are in the block table yet.
$count = db_query_range("SELECT 1 FROM {block} WHERE theme != 'garland'", 0, 1)->fetchField();
$this->assertFalse($count, t('Only Garland has blocks.'));
$count = db_query_range("SELECT 1 FROM {block} WHERE theme NOT IN ('garland', 'seven')", 0, 1)->fetchField();
$this->assertFalse($count, t('Only Garland and Seven have blocks.'));
// Populate list of all blocks for matching against new theme.
$blocks = array();
$result = db_query('SELECT * FROM {block}');
$result = db_query("SELECT * FROM {block} WHERE theme = 'garland'");
foreach ($result as $block) {
// $block->theme and $block->bid will not match, so remove them.
unset($block->theme, $block->bid);

View File

@ -128,7 +128,6 @@ class BlogTestCase extends DrupalWebTestCase {
if ($response2 == 200) {
$this->assertTitle(t('Blog | Drupal'), t('Blog help node was displayed'));
$this->assertText(t('Blog'), t('Blog help node was displayed'));
$this->assertText(t('Home ' . $crumb . ' Administer ' . $crumb . ' Help'), t('Breadcrumbs were displayed'));
}
// Verify the blog block was displayed.
@ -147,7 +146,6 @@ class BlogTestCase extends DrupalWebTestCase {
$this->assertResponse($response);
if ($response == 200) {
$this->assertTitle('Edit Blog entry ' . $node->title . ' | Drupal', t('Blog edit node was displayed'));
$this->assertText(t('Home ' . $crumb . ' @title', array('@title' => $node->title)), t('Breadcrumbs were displayed'));
}
if ($response == 200) {

View File

@ -196,14 +196,11 @@ function comment_multiple_delete_confirm(&$form_state) {
*/
function comment_multiple_delete_confirm_submit($form, &$form_state) {
if ($form_state['values']['confirm']) {
foreach ($form_state['values']['comments'] as $cid => $value) {
$comment = comment_load($cid);
// Perform the actual comment deletion.
_comment_delete_thread($comment);
_comment_update_node_statistics($comment->nid);
}
comment_delete_multiple(array_keys($form_state['values']['comments']));
cache_clear_all();
drupal_set_message(t('The comments have been deleted.'));
$count = count($form_state['values']['comments']);
watchdog('content', 'Deleted @count comments.', array('@count' => $count));
drupal_set_message(t('Deleted @count comments.', array('@count' => $count)));
}
$form_state['redirect'] = 'admin/content/comment';
}
@ -214,7 +211,7 @@ function comment_multiple_delete_confirm_submit($form, &$form_state) {
* @param $cid
* The comment to be deleted.
*/
function comment_delete($cid = NULL) {
function comment_delete_page($cid = NULL) {
$comment = db_query('SELECT c.*, u.name AS registered_name, u.uid FROM {comment} c INNER JOIN {users} u ON u.uid = c.uid WHERE c.cid = :cid', array(':cid' => $cid))->fetch();
$comment->name = $comment->uid ? $comment->registered_name : $comment->name;
$output = '';
@ -252,41 +249,13 @@ function comment_confirm_delete(&$form_state, $comment) {
* Process comment_confirm_delete form submissions.
*/
function comment_confirm_delete_submit($form, &$form_state) {
drupal_set_message(t('The comment and all its replies have been deleted.'));
$comment = $form['#comment'];
// Delete the comment and its replies.
_comment_delete_thread($comment);
_comment_update_node_statistics($comment->nid);
comment_delete($comment->cid);
drupal_set_message(t('The comment and all its replies have been deleted.'));
watchdog('content', t('Deleted comment @cid and its replies.', array('@cid' => $comment->cid)));
// Clear the cache so an anonymous user sees that his comment was deleted.
cache_clear_all();
$form_state['redirect'] = "node/$comment->nid";
}
/**
* Perform the actual deletion of a comment and all its replies.
*
* @param $comment
* An associative array describing the comment to be deleted.
*/
function _comment_delete_thread($comment) {
if (!is_object($comment) || !is_numeric($comment->cid)) {
watchdog('content', 'Cannot delete non-existent comment.', array(), WATCHDOG_WARNING);
return;
}
// Delete the comment.
db_delete('comment')
->condition('cid', $comment->cid)
->execute();
watchdog('content', 'Comment: deleted %subject.', array('%subject' => $comment->subject));
module_invoke_all('comment_delete', $comment);
// Delete the comment's replies.
$result = db_query('SELECT c.*, u.name AS registered_name, u.uid FROM {comment} c INNER JOIN {users} u ON u.uid = c.uid WHERE pid = :cid', array(':cid' => $comment->cid));
foreach ($result as $comment) {
$comment->name = $comment->uid ? $comment->registered_name : $comment->name;
_comment_delete_thread($comment);
}
}

View File

@ -296,3 +296,15 @@ function comment_schema() {
return $schema;
}
/**
* Create comment Field API bundles.
*/
function comment_update_7005() {
$ret = array();
foreach (node_type_get_types() as $info) {
field_attach_create_bundle('comment_node_' . $info->type);
}
return $ret;
}

View File

@ -148,7 +148,7 @@ function comment_menu() {
);
$items['comment/delete'] = array(
'title' => 'Delete comment',
'page callback' => 'comment_delete',
'page callback' => 'comment_delete_page',
'access arguments' => array('administer comments'),
'type' => MENU_CALLBACK,
);
@ -186,22 +186,59 @@ function comment_menu() {
return $items;
}
/**
* Implement hook_fieldable_info().
*/
function comment_fieldable_info() {
$return = array(
'comment' => array(
'label' => t('Comment'),
'object keys' => array(
'id' => 'cid',
'bundle' => 'node_type',
),
'bundle keys' => array(
'bundle' => 'type',
),
'bundles' => array(),
),
);
foreach (node_type_get_names() as $type => $name) {
$return['comment']['bundles']['comment_node_' . $type] = array(
'label' => $name,
);
}
return $return;
}
/**
* Implement hook_node_type().
*/
function comment_node_type($op, $info) {
$settings = array(
'comment',
'comment_default_mode',
'comment_default_per_page',
'comment_anonymous',
'comment_subject_field',
'comment_preview',
'comment_form_location',
);
switch ($op) {
case 'insert':
field_attach_create_bundle('comment_node_' . $info->type);
break;
case 'update':
if (!empty($info->old_type) && $info->type != $info->old_type) {
field_attach_rename_bundle('comment_node_' . $info->old_type, 'comment_node_' . $info->type);
}
break;
case 'delete':
field_attach_delete_bundle('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);
}
@ -782,6 +819,8 @@ function comment_build_content($comment, $build_mode = 'full') {
'#markup' => check_markup($comment->comment, $comment->format, '', FALSE),
);
$comment->content += field_attach_view('comment', $comment, $build_mode);
if (empty($comment->in_preview)) {
$comment->content['links']['comment'] = array(
'#theme' => 'links',
@ -1009,9 +1048,8 @@ function comment_node_insert($node) {
* Implement hook_node_delete().
*/
function comment_node_delete($node) {
db_delete('comment')
->condition('nid', $node->nid)
->execute();
$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();
@ -1082,13 +1120,8 @@ function comment_user_cancel($edit, $account, $method) {
case 'user_cancel_delete':
module_load_include('inc', 'comment', 'comment.admin');
$result = db_query('SELECT c.cid FROM {comment} c WHERE uid = :uid', array(':uid' => $account->uid))->fetchCol();
foreach ($result as $cid) {
$comment = comment_load($cid);
// Delete the comment and its replies.
_comment_delete_thread($comment);
_comment_update_node_statistics($comment->nid);
}
$cids = db_query('SELECT c.cid FROM {comment} c WHERE uid = :uid', array(':uid' => $account->uid))->fetchCol();
comment_delete_multiple($cids);
break;
}
}
@ -1136,6 +1169,14 @@ function comment_save($comment) {
$comment->$key = $default;
}
}
// Make sure we have a bundle name.
if (!isset($comment->node_type)) {
$node = node_load($comment->nid);
$comment->node_type = 'comment_node_' . $node->type;
}
field_attach_presave('comment', $comment);
if ($comment->cid) {
// Update the comment in the database.
db_update('comment')
@ -1152,6 +1193,7 @@ function comment_save($comment) {
))
->condition('cid', $comment->cid)
->execute();
field_attach_update('comment', $comment);
// Allow modules to respond to the updating of a comment.
module_invoke_all('comment_update', $comment);
// Add an entry to the watchdog log.
@ -1229,6 +1271,8 @@ function comment_save($comment) {
// saved node to be propagated to the slave.
db_ignore_slave();
field_attach_insert('comment', $comment);
// Tell the other modules a new comment has been submitted.
module_invoke_all('comment_insert', $comment);
// Add an entry to the watchdog log.
@ -1243,6 +1287,42 @@ function comment_save($comment) {
}
}
/**
* Delete a comment and all its replies.
*
* @param $cid
* The comment to delete.
*/
function comment_delete($cid) {
comment_delete_multiple(array($cid));
}
/**
* Delete comments and all their replies.
*
* @param $cids
* The comment to delete.
*/
function comment_delete_multiple($cids) {
$comments = comment_load_multiple($cids);
if ($comments) {
// Delete the comments.
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);
// 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);
}
}
}
/**
* Implement hook_link().
*/
@ -1366,7 +1446,9 @@ function comment_load_multiple($cids = array(), $conditions = array()) {
if ($cids || $conditions) {
$query = db_select('comment', 'c');
$query->innerJoin('users', 'u', 'c.uid = u.uid');
$query->innerJoin('node', 'n', 'c.nid = n.nid');
$query->addField('u', 'name', 'registered_name');
$query->addField('n', 'type', 'node_type');
$query
->fields('c', array('cid', 'nid', 'pid', 'comment', 'subject', 'format', 'timestamp', 'name', 'mail', 'homepage', 'status', 'thread'))
->fields('u', array( 'uid', 'signature', 'picture', 'data', 'status'));
@ -1390,11 +1472,14 @@ function comment_load_multiple($cids = array(), $conditions = array()) {
$comment = drupal_unpack($comment);
$comment->name = $comment->uid ? $comment->registered_name : $comment->name;
$comment->new = node_mark($comment->nid, $comment->timestamp);
$comment->node_type = 'comment_node_' . $comment->node_type;
$comments[$key] = $comment;
}
// Invoke hook_comment_load().
if (!empty($comments)) {
// Attach fields.
field_attach_load('comment', $comments);
// Invoke hook_comment_load().
module_invoke_all('comment_load', $comments);
}
return $comments;
@ -1752,6 +1837,10 @@ function comment_form(&$form_state, $edit = array()) {
'#type' => 'value',
'#value' => !empty($edit['uid']) ? $edit['uid'] : 0,
);
$form['node_type'] = array(
'#type' => 'value',
'#value' => 'comment_node_' . $node->type,
);
// Only show the save button if comment previews are optional or if we are
// already previewing the submission. However, if there are form errors,
@ -1776,6 +1865,11 @@ function comment_form(&$form_state, $edit = array()) {
$form['#action'] = url('comment/reply/' . $edit['nid']);
}
$comment = (object) $edit;
$comment->node_type = 'comment_node_' . $node->type;
$form['#builder_function'] = 'comment_form_submit_build_comment';
field_attach_form('comment', $comment, $form, $form_state);
return $form;
}
@ -1829,12 +1923,11 @@ function comment_preview($comment) {
}
if ($comment->pid) {
$parent_comment = db_query('SELECT c.*, u.uid, u.name AS registered_name, u.signature, u.picture, u.data FROM {comment} c INNER JOIN {users} u ON c.uid = u.uid WHERE c.cid = :cid AND c.status = :status', array(
':cid' => $comment->pid,
':status' => COMMENT_PUBLISHED,
))->fetchObject();
$build = comment_build($parent_comment);
$build = array();
if ($comments = comment_load_multiple(array($comment->pid), array('status' => COMMENT_PUBLISHED))) {
$parent_comment = $comments[$comment->pid];
$build = comment_build($parent_comment);
}
}
else {
$build = node_build($node);
@ -1851,6 +1944,9 @@ function comment_preview($comment) {
*/
function comment_form_validate($form, &$form_state) {
global $user;
$comment = (object) $form_state['values'];
field_attach_form_validate('comment', $comment, $form, $form_state);
if ($user->uid === 0) {
foreach (array('name', 'homepage', 'mail') as $field) {
// Set cookie for 365 days.
@ -1949,6 +2045,8 @@ function comment_submit($comment) {
function comment_form_submit_build_comment($form, &$form_state) {
$comment = comment_submit($form_state['values']);
field_attach_submit('comment', $comment, $form, $form_state);
$form_state['comment'] = (array)$comment;
$form_state['rebuild'] = TRUE;
return $comment;

View File

@ -73,6 +73,8 @@ function comment_reply($node, $pid = NULL) {
}
// Display the parent comment
$comment = drupal_unpack($comment);
$comment->node_type = 'comment_node_' . $node->type;
field_attach_load('comment', array($comment->cid => $comment));
$comment->name = $comment->uid ? $comment->registered_name : $comment->name;
$build['comment_parent'] = comment_build($comment);
}

View File

@ -207,7 +207,7 @@ class CommentHelperCase extends DrupalWebTestCase {
if ($operation == 'delete') {
$this->drupalPost(NULL, array(), t('Delete comments'));
$this->assertText(t('The comments have been deleted.'), t('Operation "' . $operation . '" was performed on comment.'));
$this->assertRaw(t('Deleted @count comments.', array('@count' => 1)), t('Operation "' . $operation . '" was performed on comment.'));
}
else {
$this->assertText(t('The update has been performed.'), t('Operation "' . $operation . '" was performed on comment.'));

View File

@ -288,7 +288,6 @@ class ForumTestCase extends DrupalWebTestCase {
if ($response2 == 200) {
$this->assertTitle(t('Forum | Drupal'), t('Forum help title was displayed'));
$this->assertText(t('Forum'), t('Forum help node was displayed'));
$this->assertText(t('Home ' . $crumb . ' Administer ' . $crumb . ' Help'), t('Breadcrumbs were displayed'));
}
// Verify the forum blocks were displayed.
@ -316,7 +315,6 @@ class ForumTestCase extends DrupalWebTestCase {
$this->assertResponse($response);
if ($response == 200) {
$this->assertTitle('Edit Forum topic ' . $node->title . ' | Drupal', t('Forum edit node was displayed'));
$this->assertText(t('Home ' . $crumb . ' @title', array('@title' => $node->title)), t('Breadcrumbs were displayed'));
}
if ($response == 200) {

View File

@ -64,8 +64,6 @@ class HelpTestCase extends DrupalWebTestCase {
// continue;
// }
$this->assertTitle($name . ' | Drupal', t('[' . $module . '] Title was displayed'));
$this->assertRaw('<h2>' . t($name) . '</h2>', t('[' . $module . '] Heading was displayed'));
$this->assertText(t('Home ' . $crumb . ' Administer ' . $crumb . ' Help'), t('[' . $module . '] Breadcrumbs were displayed'));
}
}
}

View File

@ -84,6 +84,36 @@ function default_profile_site_setup(&$install_state) {
'pages' => '',
'cache' => -1,
),
array(
'module' => 'system',
'delta' => 'main',
'theme' => 'seven',
'status' => 1,
'weight' => 0,
'region' => 'content',
'pages' => '',
'cache' => -1,
),
array(
'module' => 'system',
'delta' => 'help',
'theme' => 'seven',
'status' => 1,
'weight' => 0,
'region' => 'help',
'pages' => '',
'cache' => -1,
),
array(
'module' => 'user',
'delta' => 'login',
'theme' => 'seven',
'status' => 1,
'weight' => 10,
'region' => 'content',
'pages' => '',
'cache' => -1,
),
);
$query = db_insert('block')->fields(array('module', 'delta', 'theme', 'status', 'weight', 'region', 'pages', 'cache'));
foreach ($values as $record) {
@ -188,6 +218,15 @@ function default_profile_site_setup(&$install_state) {
// Save some default links.
$link = array('link_path' => 'admin/structure/menu-customize/main-menu/add', 'link_title' => 'Add a main menu link', 'menu_name' => 'main-menu');
menu_link_save($link);
// Enable the admin theme.
db_update('system')
->fields(array('status' => 1))
->condition('type', 'theme')
->condition('name', 'seven')
->execute();
variable_set('admin_theme', 'seven');
variable_set('node_admin_theme', '1');
}
/**