Newer
Older
Yves Chedemois
committed
function content_requirements($phase) {
$requirements = array();
// Ensure translations don't break at install time
$t = get_t();
if (module_exists('views') && (!function_exists('views_api_version') || views_api_version() < 2.0)) {
$requirements['cck_views'] = array(
'title' => $t('CCK - No Views integration'),
'description' => $t("CCK fields integration with Views module is not compatible with the version of Views you are running.<br/>CCK data won't appear in your existing views.<br/> You might want to upgrade to a more recent version of Views module."),
'severity' => REQUIREMENT_WARNING,
);
}
return $requirements;
}
Karen Stevenson
committed
/**
* 'Safe' version of content_types() to use in updates and installs.
*
* Can't safely use content_fields() or content_types() in an update to get
* a fields array, especially without knowing what field modules are enabled,
* or the current state of the database and cache, so create a fields array
* from database info that is limited to fields from modules that are
* currently enabled.
*/
function content_types_install() {
Yves Chedemois
committed
drupal_load('module', 'content');
module_load_include('inc', 'content', '/includes/content.crud');
$module_field_types = $module_widgets = array();
Karen Stevenson
committed
foreach (module_list() as $module) {
if ($field_type = module_invoke($module, 'field_info')) {
$module_field_types[$module] = $field_type;
}
if ($widget_type = module_invoke($module, 'widget_info')) {
$module_widgets[$module] = $widget_type;
}
}
$fields = array();
$db_result = db_query("SELECT * FROM {". content_instance_tablename() ."} nfi ".
Karen Stevenson
committed
" LEFT JOIN {". content_field_tablename() ."} nf ON nf.field_name = nfi.field_name");
Karen Stevenson
committed
while ($row = db_fetch_array($db_result)) {
$field = array_merge($row, unserialize($row['global_settings']));
unset($field['global_settings']);
Karen Stevenson
committed
// There may be module data available for currently disabled modules,
// or missing module data for currently enabled modules, so start over
// to get only field info for enabled modules.
unset($field['module']);
unset($field['widget_module']);
// 'columns' is a reserved word in MySQL4, so our column is named 'db_columns'.
Karen Stevenson
committed
$field['columns'] = isset($field['db_columns']) ? $field['db_columns'] : array();
unset($field['db_columns']);
Karen Stevenson
committed
foreach ($module_field_types as $module => $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'])) {
Karen Stevenson
committed
$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);
Karen Stevenson
committed
$field = content_field_instance_expand($field);
Karen Stevenson
committed
$fields[$field['type_name']][$field['field_name']] = $field;
}
}
return $fields;
}
/**
* Implementation of hook_install().
*/
Karen Stevenson
committed
variable_set('content_schema_version', 6002);
Karen Stevenson
committed
drupal_install_schema('content');
}
/**
* Implementation of hook_uninstall().
*/
function content_uninstall() {
drupal_uninstall_schema('content');
// The variable is used during the uninstall process,
// so we removed it at the very end.
variable_del('content_schema_version');
* Implementation of hook_enable().
Karen Stevenson
committed
// 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() {
Karen Stevenson
committed
// 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' => ''),
Yves Chedemois
committed
'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),
Karen Stevenson
committed
'active' => array('type' => 'int', 'size' => 'tiny', 'not null' => TRUE, 'default' => 0),
Yves Chedemois
committed
'locked' => 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' => ''),
Yves Chedemois
committed
'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' => ''),
Karen Stevenson
committed
'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');
Karen Stevenson
committed
// 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
Karen Stevenson
committed
// since no fields have been created yet, so just return with this much
// of the schema.
Karen Stevenson
committed
if (!db_table_exists('content_node_field') || !db_table_exists('content_node_field_instance')) {
Karen Stevenson
committed
return $schema;
}
drupal_load('module', 'content');
// 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.
Karen Stevenson
committed
// content_table_schema() and content_database_info() have no
Karen Stevenson
committed
$db_result = db_query("SELECT * FROM {". content_instance_tablename() ."} nfi ".
Karen Stevenson
committed
" 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);
Yves Chedemois
committed
// We always add a 'per content type' table for each content type that
// has fields.
Karen Stevenson
committed
if (!isset($schema[$content_table])) {
$schema[$content_table] = content_table_schema();
}
Yves Chedemois
committed
$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.
Yves Chedemois
committed
if (!isset($schema[$field_table])) {
$schema[$field_table] = $base_schema;
}
else {
// Per-type storage: merge the information for the field
Yves Chedemois
committed
// 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();
Yves Chedemois
committed
drupal_load('module', 'content');
Karen Stevenson
committed
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', 'size' => 'medium', 'not null' => TRUE, 'initial' => ''));
Karen Stevenson
committed
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' => ''));
Karen Stevenson
committed
db_add_field($ret, content_instance_tablename(), 'widget_active', array('type' => 'int', 'size' => 'tiny', 'not null' => TRUE, 'default' => 0));
Karen Stevenson
committed
// This will update the table for any modules enabled at this time.
Karen Stevenson
committed
content_associate_fields($module);
Karen Stevenson
committed
// 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;
Karen Stevenson
committed
}
/**
* 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'.
Karen Stevenson
committed
function content_update_6001() {
$ret = array();
Yves Chedemois
committed
drupal_load('module', 'content');
if (db_table_exists('content_node_field')) {
return $ret;
Karen Stevenson
committed
}
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);
Karen Stevenson
committed
return $ret;
}
/**
Karen Stevenson
committed
* 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() {
Yves Chedemois
committed
drupal_load('module', 'content');
$db_types = content_types_install();
$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);
}
}
}
Karen Stevenson
committed
variable_set('content_schema_version', 6002);
content_clear_type_cache(TRUE);
Yves Chedemois
committed
}
/**
* 'db_columns' column 1st got introduced as 'columns', which is forbidden in MySQL 4.
* This update function will only be useful for early D6 testers...
Yves Chedemois
committed
*/
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;
Yves Chedemois
committed
}
/**
* Index the 'nid' column on data tables to optimize node deletion.
* Large tables might deserve a multipass update.
*/
function content_update_6004(&$sandbox) {
$ret = array();
// Do nothing if the indexes were already created by D5's content_update_1009.
if (variable_get('content_update_1009', FALSE)) {
return $ret;
}
Yves Chedemois
committed
// Gather list of tables.
if (!isset($sandbox['tables'])) {
drupal_load('module', 'content');
Yves Chedemois
committed
$sandbox['tables'] = array();
$result = db_query('SELECT * FROM {'. content_instance_tablename() .'} nfi '.
' LEFT JOIN {'. content_field_tablename() .'} nf ON nf.field_name = nfi.field_name');
while ($field = db_fetch_array($result)) {
if ($field['db_storage'] == CONTENT_DB_STORAGE_PER_FIELD) {
$table = _content_tablename($field['field_name'], CONTENT_DB_STORAGE_PER_FIELD);
}
else {
$table = _content_tablename($field['type_name'], CONTENT_DB_STORAGE_PER_CONTENT_TYPE);
}
$sandbox['tables'][$table] = $table;
}
$sandbox['count'] = count($sandbox['tables']);
}
// One pass : add index on one table.
if ($table = array_shift($sandbox['tables'])) {
db_add_index($ret, $table, 'nid', array('nid'));
}
if ($sandbox['count']) {
$ret['#finished'] = 1 - count($sandbox['tables']) / $sandbox['count'];
}
Yves Chedemois
committed
return $ret;
}
Yves Chedemois
committed
/**
* Add 'locked' property for fields.
*/
function content_update_6005() {
$ret = array();
Yves Chedemois
committed
drupal_load('module', 'content');
Yves Chedemois
committed
db_add_field($ret, content_field_tablename(), 'locked', array('type' => 'int', 'size' => 'tiny', 'not null' => TRUE, 'default' => 0));
return $ret;
}
/**
* Make sure the 'locked' column is NOT NULL (error in previous content_update_6005().
*/
function content_update_6006() {
$ret = array();
drupal_load('module', 'content');
db_change_field($ret, content_field_tablename(), 'locked', 'locked', array('type' => 'int', 'size' => 'tiny', 'not null' => TRUE, 'default' => 0));
Yves Chedemois
committed
return $ret;
}