From d12eba1705dfa3c6f7da93f81c403b33de8fd8fc Mon Sep 17 00:00:00 2001
From: Dries Buytaert <dries@buytaert.net>
Date: Sat, 18 Dec 2010 01:50:16 +0000
Subject: [PATCH] - Patch #890128 by carlos8f, sumitk: comment body missing if
 comment module enabled after a content type module.

---
 modules/comment/comment.install             | 60 ++++++-------
 modules/comment/comment.module              | 63 ++++++++------
 modules/comment/comment.test                | 93 +++++++++++++++++++++
 modules/simpletest/drupal_web_test_case.php | 14 +++-
 4 files changed, 173 insertions(+), 57 deletions(-)

diff --git a/modules/comment/comment.install b/modules/comment/comment.install
index 23f9f9cf02ea..1ba3a5c6a1ba 100644
--- a/modules/comment/comment.install
+++ b/modules/comment/comment.install
@@ -6,35 +6,6 @@
  * Install, update and uninstall functions for the comment module.
  */
 
-/**
- * Implements hook_install().
- */
-function comment_install() {
-  // Create comment body field.
-  if (!field_info_field('comment_body')) {
-    $field = array(
-      'field_name' => 'comment_body',
-      'type' => 'text_long',
-      'entity_types' => array('comment'),
-    );
-    field_create_field($field);
-  }
-
-  // There is a separate comment bundle for each node type to allow for
-  // per-node-type customization of comment fields. Each one of these bundles
-  // needs a comment body field instance. A comment bundle is needed even for
-  // node types whose comments are disabled by default, because individual nodes
-  // may override that default.
-  // @todo This should be changed to call field_attach_create_bundle() instead,
-  //   and a comment_field_attach_create_bundle() function should be added to
-  //   handle the creation of the comment body field instance.
-  foreach (node_type_get_types() as $type => $info) {
-    if (!isset($info->is_new) && !isset($info->disabled) && !field_info_instance('comment', 'comment_body', 'comment_node_' . $info->type)) {
-      _comment_body_field_instance_create($info);
-    }
-  }
-}
-
 /**
  * Implements hook_uninstall().
  */
@@ -77,6 +48,37 @@ function comment_enable() {
     ->execute();
 }
 
+/**
+ * Implements hook_modules_enabled().
+ *
+ * Creates comment body fields for node types existing before the comment module
+ * is enabled. We use hook_modules_enabled() rather than hook_enable() so we can
+ * react to node types of existing modules, and those of modules being enabled
+ * both before and after comment module in the loop of module_enable().
+ *
+ * There is a separate comment bundle for each node type to allow for
+ * per-node-type customization of comment fields. Each one of these bundles
+ * needs a comment body field instance. A comment bundle is needed even for
+ * node types whose comments are disabled by default, because individual nodes
+ * may override that default.
+ *
+ * @see comment_node_type_insert()
+ */
+function comment_modules_enabled($modules) {
+  // Only react if comment module is one of the modules being enabled.
+  // hook_node_type_insert() is used to create body fields while the comment
+  // module is enabled.
+  if (in_array('comment', $modules)) {
+    // Ensure that the list of node types reflects newly enabled modules.
+    node_types_rebuild();
+
+    // Create comment body fields for each node type, if needed.
+    foreach (node_type_get_types() as $type => $info) {
+      _comment_body_field_create($info);
+    }
+  }
+}
+
 /**
  * Implements hook_update_dependencies().
  */
diff --git a/modules/comment/comment.module b/modules/comment/comment.module
index e78f6ec5caac..fe3584b17fff 100644
--- a/modules/comment/comment.module
+++ b/modules/comment/comment.module
@@ -314,12 +314,15 @@ function comment_count_unpublished() {
 
 /**
  * Implements hook_node_type_insert().
+ *
+ * Creates a comment body field for a node type created while the comment module
+ * is enabled. For node types created before the comment module is enabled,
+ * hook_modules_enabled() serves to create the body fields.
+ *
+ * @see comment_modules_enabled()
  */
 function comment_node_type_insert($info) {
-  field_attach_create_bundle('comment', 'comment_node_' . $info->type);
-  // @todo Create a comment_field_attach_create_bundle() function, and have that
-  //   function create the comment body field instance.
-  _comment_body_field_instance_create($info);
+  _comment_body_field_create($info);
 }
 
 /**
@@ -351,27 +354,39 @@ function comment_node_type_delete($info) {
 }
 
  /**
- * Helper function which creates a comment body field instance for a given node
- * type.
- */
-function _comment_body_field_instance_create($info) {
-  // Attaches the body field by default.
-  $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,
+ * Creates a comment_body field instance for a given node type.
+ */
+function _comment_body_field_create($info) {
+  // Create the field if needed.
+  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);
+  }
+  // Create the instance if needed.
+  if (!field_read_instance('comment', 'comment_body', 'comment_node_' . $info->type, array('include_inactive' => TRUE))) {
+    field_attach_create_bundle('comment', 'comment_node_' . $info->type);
+    // Attaches the body field by default.
+    $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);
+    );
+    field_create_instance($instance);
+  }
 }
 
 /**
diff --git a/modules/comment/comment.test b/modules/comment/comment.test
index 45d6631bd58a..fbef5d7a8944 100644
--- a/modules/comment/comment.test
+++ b/modules/comment/comment.test
@@ -1478,3 +1478,96 @@ class CommentActionsTestCase extends CommentHelperCase {
     db_truncate('watchdog')->execute();
   }
 }
+
+/**
+ * Test fields on comments.
+ */
+class CommentFieldsTest extends CommentHelperCase {
+  public static function getInfo() {
+    return array(
+      'name' => 'Comment fields',
+      'description' => 'Tests fields on comments.',
+      'group' => 'Comment',
+    );
+  }
+
+  /**
+   * Tests that the default 'comment_body' field is correctly added.
+   */
+  function testCommentDefaultFields() {
+    // Do not make assumptions on default node types created by the test
+    // install profile, and create our own.
+    $this->drupalCreateContentType(array('type' => 'test_node_type'));
+
+    // Check that the 'comment_body' field is present on all comment bundles.
+    $instances = field_info_instances('comment');
+    foreach (node_type_get_types() as $type_name => $info) {
+      $this->assertTrue(isset($instances['comment_node_' . $type_name]['comment_body']), t('The comment_body field is present for comments on type @type', array('@type' => $type_name)));
+
+      // Delete the instance along the way.
+      field_delete_instance($instances['comment_node_' . $type_name]['comment_body']);
+    }
+
+    // Check that the 'comment_body' field is deleted.
+    $field = field_info_field('comment_body');
+    $this->assertTrue(empty($field), t('The comment_body field was deleted'));
+
+    // Create a new content type.
+    $type_name = 'test_node_type_2';
+    $this->drupalCreateContentType(array('type' => $type_name));
+
+    // Check that the 'comment_body' field exists and has an instance on the
+    // new comment bundle.
+    $field = field_info_field('comment_body');
+    $this->assertTrue($field, t('The comment_body field exists'));
+    $instances = field_info_instances('comment');
+    $this->assertTrue(isset($instances['comment_node_' . $type_name]['comment_body']), t('The comment_body field is present for comments on type @type', array('@type' => $type_name)));
+  }
+
+  /**
+   * Test that comment module works when enabled after a content module.
+   */
+  function testCommentEnable() {
+    // Create a user to do module administration.
+    $this->admin_user = $this->drupalCreateUser(array('access administration pages', 'administer modules'));
+    $this->drupalLogin($this->admin_user);
+
+    // Disable the comment module.
+    $edit = array();
+    $edit['modules[Core][comment][enable]'] = FALSE;
+    $this->drupalPost('admin/modules', $edit, t('Save configuration'));
+    $this->resetAll();
+    $this->assertFalse(module_exists('comment'), t('Comment module disabled.'));
+
+    // Enable core content type modules (blog, book, and poll).
+    $edit = array();
+    $edit['modules[Core][blog][enable]'] = 'blog';
+    $edit['modules[Core][book][enable]'] = 'book';
+    $edit['modules[Core][poll][enable]'] = 'poll';
+    $this->drupalPost('admin/modules', $edit, t('Save configuration'));
+    $this->resetAll();
+
+    // Now enable the comment module.
+    $edit = array();
+    $edit['modules[Core][comment][enable]'] = 'comment';
+    $this->drupalPost('admin/modules', $edit, t('Save configuration'));
+    $this->resetAll();
+    $this->assertTrue(module_exists('comment'), t('Comment module enabled.'));
+
+    // Create nodes of each type.
+    $blog_node = $this->drupalCreateNode(array('type' => 'blog'));
+    $book_node = $this->drupalCreateNode(array('type' => 'book'));
+    $poll_node = $this->drupalCreateNode(array('type' => 'poll', 'active' => 1, 'runtime' => 0, 'choice' => array(array('chtext' => ''))));
+
+    $this->drupalLogout();
+
+    // Try to post a comment on each node. A failure will be triggered if the
+    // comment body is missing on one of these forms, due to postComment()
+    // asserting that the body is actually posted correctly.
+    $this->web_user = $this->drupalCreateUser(array('access content', 'access comments', 'post comments', 'skip comment approval'));
+    $this->drupalLogin($this->web_user);
+    $this->postComment($blog_node, $this->randomName(), $this->randomName());
+    $this->postComment($book_node, $this->randomName(), $this->randomName());
+    $this->postComment($poll_node, $this->randomName(), $this->randomName());
+  }
+}
diff --git a/modules/simpletest/drupal_web_test_case.php b/modules/simpletest/drupal_web_test_case.php
index e572e43c90fc..e9d5ad43dd0c 100644
--- a/modules/simpletest/drupal_web_test_case.php
+++ b/modules/simpletest/drupal_web_test_case.php
@@ -1326,16 +1326,22 @@ protected function preloadRegistry() {
    * are enabled later.
    */
   protected function resetAll() {
-    // Rebuild caches.
+    // Reset all static variables.
     drupal_static_reset();
+    // Reset the list of enabled modules.
+    module_list(TRUE);
+
+    // Reset cached schema for new database prefix. This must be done before
+    // drupal_flush_all_caches() so rebuilds can make use of the schema of
+    // modules enabled on the cURL side.
+    drupal_get_schema(NULL, TRUE);
+
+    // Perform rebuilds and flush remaining caches.
     drupal_flush_all_caches();
 
     // Reload global $conf array and permissions.
     $this->refreshVariables();
     $this->checkPermissions(array(), TRUE);
-
-    // Reset statically cached schema for new database prefix.
-    drupal_get_schema(NULL, TRUE);
   }
 
   /**
-- 
GitLab