summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
authorAngie Byron <webchick@24967.no-reply.drupal.org>2010-10-07 00:28:20 +0000
committerAngie Byron <webchick@24967.no-reply.drupal.org>2010-10-07 00:28:20 +0000
commit65b99dc85fde083cca0938634bb15c4e1779c50d (patch)
treee6313de07afaf6962b0cfe4f0c637a3845e6d06b /modules
parent466c8ff543ec24e224d1c03a856d6e89459e4243 (diff)
downloadbrdo-65b99dc85fde083cca0938634bb15c4e1779c50d.tar.gz
brdo-65b99dc85fde083cca0938634bb15c4e1779c50d.tar.bz2
#895014 by Damien Tournoud, chx, catch: Fixed all fields of a node type are lost on module disable.
Diffstat (limited to 'modules')
-rw-r--r--modules/forum/forum.install42
-rw-r--r--modules/node/content_types.inc3
-rw-r--r--modules/node/node.install47
-rw-r--r--modules/node/node.module79
-rw-r--r--modules/node/node.test76
5 files changed, 193 insertions, 54 deletions
diff --git a/modules/forum/forum.install b/modules/forum/forum.install
index bc2a9b1b6..a5dbc3e10 100644
--- a/modules/forum/forum.install
+++ b/modules/forum/forum.install
@@ -71,30 +71,30 @@ function forum_enable() {
);
$term = (object) $edit;
taxonomy_term_save($term);
- }
- // Create the instance on the bundle.
- $instance = array(
- 'field_name' => 'taxonomy_' . $vocabulary->machine_name,
- 'entity_type' => 'node',
- 'label' => $vocabulary->name,
- 'bundle' => 'forum',
- 'required' => TRUE,
- 'widget' => array(
- 'type' => 'options_select',
- ),
- 'display' => array(
- 'default' => array(
- 'type' => 'taxonomy_term_reference_link',
- 'weight' => 10,
+ // Create the instance on the bundle.
+ $instance = array(
+ 'field_name' => 'taxonomy_' . $vocabulary->machine_name,
+ 'entity_type' => 'node',
+ 'label' => $vocabulary->name,
+ 'bundle' => 'forum',
+ 'required' => TRUE,
+ 'widget' => array(
+ 'type' => 'options_select',
),
- 'teaser' => array(
- 'type' => 'taxonomy_term_reference_link',
- 'weight' => 10,
+ 'display' => array(
+ 'default' => array(
+ 'type' => 'taxonomy_term_reference_link',
+ 'weight' => 10,
+ ),
+ 'teaser' => array(
+ 'type' => 'taxonomy_term_reference_link',
+ 'weight' => 10,
+ ),
),
- ),
- );
- field_create_instance($instance);
+ );
+ field_create_instance($instance);
+ }
// Ensure the forum node type is available.
node_types_rebuild();
diff --git a/modules/node/content_types.inc b/modules/node/content_types.inc
index a9d4680cf..23565ce24 100644
--- a/modules/node/content_types.inc
+++ b/modules/node/content_types.inc
@@ -320,6 +320,9 @@ function node_type_form_submit($form, &$form_state) {
$type->custom = $form_state['values']['custom'];
$type->modified = TRUE;
$type->locked = $form_state['values']['locked'];
+ if (isset($form['#node_type']->module)) {
+ $type->module = $form['#node_type']->module;
+ }
if ($op == t('Delete content type')) {
$form_state['redirect'] = 'admin/structure/types/manage/' . str_replace('_', '-', $type->old_type) . '/delete';
diff --git a/modules/node/node.install b/modules/node/node.install
index 5f93db2e8..e50571ab2 100644
--- a/modules/node/node.install
+++ b/modules/node/node.install
@@ -294,6 +294,12 @@ function node_schema() {
'length' => 255,
'not null' => TRUE,
),
+ 'module' => array(
+ 'description' => 'The module defining this node type.',
+ 'type' => 'varchar',
+ 'length' => 255,
+ 'not null' => TRUE,
+ ),
'description' => array(
'description' => 'A brief description of this type.',
'type' => 'text',
@@ -344,6 +350,13 @@ function node_schema() {
'default' => 0,
'size' => 'tiny',
),
+ 'disabled' => array(
+ 'description' => 'A boolean indicating whether the node type is disabled.',
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'default' => 0,
+ 'size' => 'tiny'
+ ),
'orig_type' => array(
'description' => 'The original machine-readable name of this node type. This may be different from the current type name if the locked field is 0.',
'type' => 'varchar',
@@ -438,16 +451,40 @@ function _update_7000_node_get_types() {
*/
/**
- * Fix node type 'module' attribute to avoid name-space conflicts.
+ * Upgrade the node type table and fix node type 'module' attribute to avoid name-space conflicts.
*/
function node_update_7000() {
+ // Rename the module column to base.
+ db_change_field('node_type', 'module', 'base', array('type' => 'varchar', 'length' => 255, 'not null' => TRUE));
+
+ db_add_field('node_type', 'module', array(
+ 'description' => 'The module defining this node type.',
+ 'type' => 'varchar',
+ 'default' => '',
+ 'length' => 255,
+ 'not null' => TRUE,
+ ));
+
+ db_add_field('node_type', 'disabled', array(
+ 'description' => 'A boolean indicating whether the node type is disabled.',
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'default' => 0,
+ 'size' => 'tiny'
+ ));
+
+ $modules = db_select('system', 's')
+ ->fields('s', array('name'))
+ ->condition('type', 'module');
db_update('node_type')
- ->fields(array('module' => 'node_content'))
- ->condition('module', 'node')
+ ->expression('module', 'base')
+ ->condition('base', $modules, 'IN')
->execute();
- // Rename the module column to base.
- db_change_field('node_type', 'module', 'base', array('type' => 'varchar', 'length' => 255, 'not null' => TRUE));
+ db_update('node_type')
+ ->fields(array('base' => 'node_content'))
+ ->condition('base', 'node')
+ ->execute();
}
/**
diff --git a/modules/node/node.module b/modules/node/node.module
index 990a93dd2..6435fa2e5 100644
--- a/modules/node/node.module
+++ b/modules/node/node.module
@@ -461,16 +461,7 @@ function node_type_get_name($node) {
* and obsolete types.
*/
function node_types_rebuild() {
- // Reset and load updated node types.
- drupal_static_reset('_node_types_build');
- foreach (node_type_get_types() as $type => $info) {
- if (!empty($info->is_new)) {
- node_type_save($info);
- }
- if (!empty($info->disabled)) {
- node_type_delete($info->type);
- }
- }
+ _node_types_build(TRUE);
}
/**
@@ -513,6 +504,8 @@ function node_type_save($info) {
'custom' => (int) $type->custom,
'modified' => (int) $type->modified,
'locked' => (int) $type->locked,
+ 'disabled' => (int) $type->disabled,
+ 'module' => $type->module,
);
if ($is_existing) {
@@ -660,6 +653,8 @@ function node_type_update_nodes($old_type, $type) {
* These two information sources are not synchronized during module installation
* until node_types_rebuild() is called.
*
+ * @param $rebuild
+ * TRUE to rebuild node types. Equivalent to calling node_types_rebuild().
* @return
* Associative array with two components:
* - names: Associative array of the names of node types, keyed by the type.
@@ -673,42 +668,66 @@ function node_type_update_nodes($old_type, $type) {
* implementations, but are still in the database. These are indicated in the
* type object by $type->disabled being set to TRUE.
*/
-function _node_types_build() {
- $_node_types = &drupal_static(__FUNCTION__);
- if (is_object($_node_types)) {
- return $_node_types;
+function _node_types_build($rebuild = FALSE) {
+ if (!$rebuild) {
+ $_node_types = &drupal_static(__FUNCTION__);
+ if (is_object($_node_types)) {
+ return $_node_types;
+ }
}
+
$_node_types = (object)array('types' => array(), 'names' => array());
- $info_array = module_invoke_all('node_info');
- foreach ($info_array as $type => $info) {
- $info['type'] = $type;
- $_node_types->types[$type] = node_type_set_defaults($info);
- $_node_types->names[$type] = $info['name'];
+ foreach (module_implements('node_info') as $module) {
+ $info_array = module_invoke($module, 'node_info');
+ foreach ($info_array as $type => $info) {
+ $info['type'] = $type;
+ $_node_types->types[$type] = node_type_set_defaults($info);
+ $_node_types->types[$type]->module = $module;
+ $_node_types->names[$type] = $info['name'];
+ }
}
- $type_result = db_select('node_type', 'nt')
+ $query = db_select('node_type', 'nt')
->addTag('translatable')
->addTag('node_type_access')
->fields('nt')
- ->orderBy('nt.type', 'ASC')
- ->execute();
- foreach ($type_result as $type_object) {
+ ->orderBy('nt.type', 'ASC');
+ if (!$rebuild) {
+ $query->condition('disabled', 0);
+ }
+ foreach ($query->execute() as $type_object) {
+ $type_db = $type_object->type;
+ // Original disabled value.
+ $disabled = $type_object->disabled;
// Check for node types from disabled modules and mark their types for removal.
// Types defined by the node module in the database (rather than by a separate
// module using hook_node_info) have a base value of 'node_content'. The isset()
// check prevents errors on old (pre-Drupal 7) databases.
- if (isset($type_object->base) && $type_object->base != 'node_content' && empty($info_array[$type_object->type])) {
+ if (isset($type_object->base) && $type_object->base != 'node_content' && empty($info_array[$type_db])) {
$type_object->disabled = TRUE;
}
- if (!isset($_node_types->types[$type_object->type]) || $type_object->modified) {
- $_node_types->types[$type_object->type] = $type_object;
- $_node_types->names[$type_object->type] = $type_object->name;
+ if (isset($info_array[$type_db])) {
+ $type_object->disabled = FALSE;
+ }
+ if (!isset($_node_types->types[$type_db]) || $type_object->modified) {
+ $_node_types->types[$type_db] = $type_object;
+ $_node_types->names[$type_db] = $type_object->name;
- if ($type_object->type != $type_object->orig_type) {
+ if ($type_db != $type_object->orig_type) {
unset($_node_types->types[$type_object->orig_type]);
unset($_node_types->names[$type_object->orig_type]);
}
}
+ $_node_types->types[$type_db]->disabled = $type_object->disabled;
+ $_node_types->types[$type_db]->disabled_changed = $disabled != $type_object->disabled;
+ }
+
+ if ($rebuild) {
+ foreach ($_node_types->types as $type => $type_object) {
+ if (!empty($type_object->is_new) || !empty($type_object->disabled_changed)) {
+ node_type_save($type_object);
+ }
+ }
}
asort($_node_types->names);
@@ -742,6 +761,7 @@ function node_type_set_defaults($info = array()) {
$type->custom = 0;
$type->modified = 0;
$type->locked = 1;
+ $type->disabled = 0;
$type->is_new = 1;
$type->has_title = 1;
@@ -757,6 +777,9 @@ function node_type_set_defaults($info = array()) {
if (!$new_type->has_title) {
$new_type->title_label = '';
}
+ if (empty($new_type->module)) {
+ $new_type->module = $new_type->base == 'node_content' ? 'node' : '';
+ }
$new_type->orig_type = isset($info['type']) ? $info['type'] : '';
return $new_type;
diff --git a/modules/node/node.test b/modules/node/node.test
index 109b6735a..59b12f008 100644
--- a/modules/node/node.test
+++ b/modules/node/node.test
@@ -1149,6 +1149,82 @@ class NodeTypeTestCase extends DrupalWebTestCase {
}
/**
+ * Test node type customizations persistence.
+ */
+class NodeTypePersistenceTestCase extends DrupalWebTestCase {
+ public static function getInfo() {
+ return array(
+ 'name' => 'Node type persist',
+ 'description' => 'Ensures that node type customization survives module enabling and disabling.',
+ 'group' => 'Node',
+ );
+ }
+
+ /**
+ * Test node type customizations persist through disable and uninstall.
+ */
+ function testNodeTypeCustomizationPersistence() {
+ $web_user = $this->drupalCreateUser(array('bypass node access', 'administer content types', 'administer modules'));
+ $this->drupalLogin($web_user);
+ $poll_key = 'modules[Core][poll][enable]';
+ $poll_enable = array($poll_key => "1");
+ $poll_disable = array($poll_key => FALSE);
+
+ // Enable poll and verify that the node type is in the DB and is not
+ // disabled.
+ $this->drupalPost('admin/modules', $poll_enable, t('Save configuration'));
+ $disabled = db_query('SELECT disabled FROM {node_type} WHERE type = :type', array(':type' => 'poll'))->fetchField();
+ $this->assertNotIdentical($disabled, FALSE, t('Poll node type found in the database'));
+ $this->assertEqual($disabled, 0, t('Poll node type is not disabled'));
+
+ // Check that poll node type (uncustomized) shows up.
+ $this->drupalGet('node/add');
+ $this->assertText('poll', t('poll type is found on node/add'));
+
+ // Customize poll description.
+ $description = $this->randomName();
+ $edit = array('description' => $description);
+ $this->drupalPost('admin/structure/types/manage/poll', $edit, t('Save content type'));
+
+ // Check that poll node type customization shows up.
+ $this->drupalGet('node/add');
+ $this->assertText($description, t('Customized description found'));
+
+ // Disable poll and check that the node type gets disabled.
+ $this->drupalPost('admin/modules', $poll_disable, t('Save configuration'));
+ $disabled = db_query('SELECT disabled FROM {node_type} WHERE type = :type', array(':type' => 'poll'))->fetchField();
+ $this->assertEqual($disabled, 1, t('Poll node type is disabled'));
+ $this->drupalGet('node/add');
+ $this->assertNoText('poll', t('poll type is not found on node/add'));
+
+ // Reenable poll and check that the customization survived the module
+ // disable.
+ $this->drupalPost('admin/modules', $poll_enable, t('Save configuration'));
+ $disabled = db_query('SELECT disabled FROM {node_type} WHERE type = :type', array(':type' => 'poll'))->fetchField();
+ $this->assertNotIdentical($disabled, FALSE, t('Poll node type found in the database'));
+ $this->assertEqual($disabled, 0, t('Poll node type is not disabled'));
+ $this->drupalGet('node/add');
+ $this->assertText($description, t('Customized description found'));
+
+ // Disable and uninstall poll.
+ $this->drupalPost('admin/modules', $poll_disable, t('Save configuration'));
+ $edit = array('uninstall[poll]' => 'poll');
+ $this->drupalPost('admin/modules/uninstall', $edit, t('Uninstall'));
+ $this->drupalPost(NULL, array(), t('Uninstall'));
+ $disabled = db_query('SELECT disabled FROM {node_type} WHERE type = :type', array(':type' => 'poll'))->fetchField();
+ $this->assertTrue($disabled, t('Poll node type is in the database and is disabled'));
+ $this->drupalGet('node/add');
+ $this->assertNoText('poll', t('poll type is no longer found on node/add'));
+
+ // Reenable poll and check that the customization survived the module
+ // uninstall.
+ $this->drupalPost('admin/modules', $poll_enable, t('Save configuration'));
+ $this->drupalGet('node/add');
+ $this->assertText($description, t('Customized description is found even after uninstall and reenable.'));
+ }
+}
+
+/**
* Rebuild the node_access table.
*/
class NodeAccessRebuildTestCase extends DrupalWebTestCase {