$types) { foreach ($types as $type_name => $type) { if ($field['type'] == $type_name) { $field['module'] = $module; } } } foreach ($module_widgets as $module => $types) { foreach ($types as $type_name => $type) { if ($field['widget_type'] == $type_name) { $field['widget_module'] = $module; } } } if (!empty($field['module']) && !empty($field['widget_module'])) { $field['widget_settings'] = unserialize($field['widget_settings']); $field['display_settings'] = unserialize($field['display_settings']); $field['columns'] = module_invoke($field['module'], 'field_settings', 'database columns', $field); $fields[$field['type_name']][$field['field_name']] = $field; } } return $fields; } /** * Implementation of hook_install(). */ function content_install() { variable_set('content_schema_version', 6002); drupal_install_schema('content'); } /** * Implementation of hook_uninstall(). */ function content_uninstall() { variable_del('content_schema_version'); drupal_uninstall_schema('content'); } /** * Implementation of hook_enable(). */ function content_enable() { // Make sure old data is emptied out of the caches, since it // may no longer be valid since the module was last enabled, // especially if not all the same field modules are enabled // as before. Especially needed during updates. cache_clear_all('*', 'cache_content', TRUE); content_clear_type_cache(TRUE); } /** * Implementation of hook_disable(). */ function content_disable() { // Make sure old data is emptied out of the caches, since it // may no longer be valid when the module is re-enabled. cache_clear_all('*', 'cache_content', TRUE); content_clear_type_cache(TRUE); } /** * Implementation of hook_schema. */ function content_schema() { // Static (meta) tables. $schema['content_node_field'] = array( 'fields' => array( 'field_name' => array('type' => 'varchar', 'length' => 32, 'not null' => TRUE, 'default' => ''), 'type' => array('type' => 'varchar', 'length' => 127, 'not null' => TRUE, 'default' => ''), 'global_settings' => array('type' => 'text', 'size' => 'medium', 'not null' => TRUE, 'serialize' => TRUE), 'required' => array('type' => 'int', 'size' => 'tiny', 'not null' => TRUE, 'default' => 0), 'multiple' => array('type' => 'int', 'size' => 'tiny', 'not null' => TRUE, 'default' => 0), 'db_storage' => array('type' => 'int', 'size' => 'tiny', 'not null' => TRUE, 'default' => 1), 'module' => array('type' => 'varchar', 'length' => 127, 'not null' => TRUE, 'default' => ''), 'db_columns' => array('type' => 'text', 'size' => 'medium', 'not null' => TRUE, 'serialize' => TRUE), 'active' => array('type' => 'int', 'size' => 'tiny', 'not null' => TRUE, 'default' => 0), ), 'primary key' => array('field_name'), ); $schema['content_node_field_instance'] = array( 'fields' => array( 'field_name' => array('type' => 'varchar', 'length' => 32, 'not null' => TRUE, 'default' => ''), 'type_name' => array('type' => 'varchar', 'length' => 32, 'not null' => TRUE, 'default' => ''), 'weight' => array('type' => 'int', 'not null' => TRUE, 'default' => 0), 'label' => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''), 'widget_type' => array('type' => 'varchar', 'length' => 32, 'not null' => TRUE, 'default' => ''), 'widget_settings' => array('type' => 'text', 'size' => 'medium', 'not null' => TRUE, 'serialize' => TRUE), 'display_settings' => array('type' => 'text', 'size' => 'medium', 'not null' => TRUE, 'serialize' => TRUE), 'description' => array('type' => 'text', 'size' => 'medium', 'not null' => TRUE), 'widget_module' => array('type' => 'varchar', 'length' => 127, 'not null' => TRUE, 'default' => ''), 'widget_active' => array('type' => 'int', 'size' => 'tiny', 'not null' => TRUE, 'default' => 0), ), 'primary key' => array('field_name', 'type_name'), ); $schema['cache_content'] = drupal_get_schema_unprocessed('system', 'cache'); // When the module is first installed, the remaining code in the schema // will create errors, since these tables have not yet been created. // We don't need to create data tables on initial installation anyway // since no fields have been created yet, so just return with this much // of the schema. if (!db_table_exists('content_node_field') || !db_table_exists('content_node_field_instance')) { return $schema; } // Dynamic (data) tables. // We can't use many helper functions here, like content_fields() or // content_types() or we risk creating a fatal loop from circular // logic when they call other functions that use this schema, so create // the schema directly from a fresh query of the database. // content_table_schema() and content_database_info() have no // circular logic and are safe to use here. $db_result = db_query("SELECT * FROM {". content_instance_tablename() ."} nfi ". " LEFT JOIN {". content_field_tablename() ."} nf ON nf.field_name = nfi.field_name WHERE nf.active = 1 AND nfi.widget_active = 1"); while ($field = db_fetch_array($db_result)) { // 'columns' is a reserved word in MySQL4, so our db column is named 'db_columns'. $field['columns'] = unserialize($field['db_columns']); unset($field['db_columns']); $content_table = _content_tablename($field['type_name'], CONTENT_DB_STORAGE_PER_CONTENT_TYPE); $field_table = _content_tablename($field['field_name'], CONTENT_DB_STORAGE_PER_FIELD); // We always add a 'per content type' table for each content type that // has fields. if (!isset($schema[$content_table])) { $schema[$content_table] = content_table_schema(); } $base_schema = content_table_schema($field); if ($field['db_storage'] == CONTENT_DB_STORAGE_PER_FIELD) { // Per-field storage : add the 'per field' table if needed. if (!isset($schema[$field_table])) { $schema[$field_table] = $base_schema; } } else { // Per-type storage : merge the information for the field // in the existing table. $schema[$content_table]['fields'] = array_merge($schema[$content_table]['fields'], $base_schema['fields']); $schema[$content_table]['content fields'] = array_merge($schema[$content_table]['content fields'], $base_schema['content fields']); } } return $schema; } function content_update_last_removed() { return 1008; } /** * Add module name to fields table to make it easier to identify the fields to delete when a module * is uninstalled. * * Needed because the value drops out of content_info() when module is disabled, so there * is no other way to find the associated fields. */ function content_update_6000() { $ret = array(); if (db_column_exists(content_field_tablename(), 'active')) { return $ret; } db_add_field($ret, content_field_tablename(), 'module', array('type' => 'varchar', 'length' => 127, 'not null' => TRUE, 'default' => '')); db_add_field($ret, content_field_tablename(), 'db_columns', array('type' => 'text', 'not null' => TRUE, 'default' => '')); db_add_field($ret, content_field_tablename(), 'active', array('type' => 'int', 'size' => 'tiny', 'not null' => TRUE, 'default' => 0)); db_add_field($ret, content_instance_tablename(), 'widget_module', array('type' => 'varchar', 'length' => 127, 'not null' => TRUE, 'default' => '')); db_add_field($ret, content_instance_tablename(), 'widget_active', array('type' => 'int', 'size' => 'tiny', 'not null' => TRUE, 'default' => 0)); // This will update the table for any modules enabled at this time. foreach (module_list() as $module) { content_associate_fields($module); } // Fix the cache_content schema if (db_table_exists('cache_content')) { db_drop_table($ret, 'cache_content'); } db_create_table($ret, 'cache_content', drupal_get_schema_unprocessed('system', 'cache')); variable_set('content_schema_version', 6000); // The cache table had to be used to store data until this update ran, // so clear cache out now that we're switching back to the cache_content table. $ret[] = update_sql('DELETE FROM {cache}'); return $ret; } /** * Rename node_field and node_field_instance tables. * * This is a carryover from when the data tables were renamed, * postponed so we wouldn't create any more havoc than necessary * until a major version change. * * Using 'content_node_field' instead of 'content_field' * to avoid conflicts with field tables that will be prefixed * with 'content_field'. */ function content_update_6001() { $ret = array(); if (db_table_exists('content_node_field')) { return $ret; } db_rename_table($ret, 'node_field', 'content_node_field'); db_rename_table($ret, 'node_field_instance', 'content_node_field_instance'); variable_set('content_schema_version', 6001); content_clear_type_cache(TRUE); return $ret; } /** * Get rid of automatic per content tables for content types that have no fields. * Switching to adding those tables only when needed. */ function content_update_6002() { $ret = array(); $db_types = content_types_install(); $field_types = array(); $result = db_query("SELECT DISTINCT type_name FROM {". content_instance_tablename() ."}"); while ($type = db_fetch_array($result)) { $field_types[] = $type['type_name']; } foreach ($db_types as $content_type => $content_info) { if (!in_array($content_type, $field_types)) { $table = _content_tablename($content_type, CONTENT_DB_STORAGE_PER_CONTENT_TYPE); if (db_table_exists($table)) { db_drop_table($ret, $table); } } } variable_set('content_schema_version', 6002); content_clear_type_cache(TRUE); return $ret; } /** * 'db_columns' column 1st got introduced as 'columns', which is forbidden in MySQL 4. * This update function will only be useful for early testers... */ function content_update_6003() { $ret = array(); if (db_column_exists('content_node_field', 'columns')) { db_change_field($ret, 'content_node_field', 'columns', 'db_columns', array('type' => 'text', 'size' => 'medium', 'not null' => TRUE)); } return $ret; }