function content_storage in Content Construction Kit (CCK) 6.3
Same name and namespace in other branches
- 6 content.module \content_storage()
- 6.2 content.module \content_storage()
Handle storage ops for _content_field_invoke_default().
1 call to content_storage()
- _content_field_invoke_default in ./
content.module - Invoke content.module's version of a field hook.
File
- ./
content.module, line 986 - Allows administrators to associate custom fields to content types.
Code
function content_storage($op, $node) {
// Don't try this before content module's update is run to add
// the active and module columns.
if (variable_get('content_schema_version', -1) < 6007) {
return FALSE;
}
$type_name = $node->type;
$type = content_types($type_name);
switch ($op) {
case 'load':
// OPTIMIZE: load all non multiple fields in a single JOIN query ?
// warning: 61-join limit in MySQL ?
$additions = array();
// For each table used by this content type,
foreach ($type['tables'] as $table) {
$schema = drupal_get_schema($table);
// The per-type table might not have any fields actually stored in it.
if (!$schema['content fields']) {
continue;
}
$query = 'SELECT * FROM {' . $table . '} WHERE vid = %d';
// If we're loading a table for a multiple field,
// we fetch all rows (values) ordered by delta,
// else we only fetch one row.
$result = isset($schema['fields']['delta']) ? db_query($query . ' ORDER BY delta', $node->vid) : db_query_range($query, $node->vid, 0, 1);
// For each table row, populate the fields.
while ($row = db_fetch_array($result)) {
// For each field stored in the table, add the field item.
foreach ($schema['content fields'] as $field_name) {
$item = array();
$field = content_fields($field_name, $type_name);
$db_info = content_database_info($field);
// For each column declared by the field, populate the item.
foreach ($db_info['columns'] as $column => $attributes) {
$item[$column] = $row[$attributes['column']];
}
// Add the item to the field values for the node.
if (!isset($additions[$field_name])) {
$additions[$field_name] = array();
}
// Preserve deltas when loading items from database.
if (isset($row['delta'])) {
// Make sure multiple value fields have consecutive deltas.
if ($row['delta'] > 0 && !isset($additions[$field_name][$row['delta'] - 1])) {
$empty = array();
foreach (array_keys($db_info['columns']) as $column) {
$empty[$column] = NULL;
}
$next_delta = !empty($additions[$field_name]) ? max(array_keys($additions[$field_name])) + 1 : 0;
for ($delta = $next_delta; $delta < $row['delta']; $delta++) {
if (!isset($additions[$field_name][$delta])) {
$additions[$field_name][$delta] = $empty;
}
}
}
$additions[$field_name][$row['delta']] = $item;
}
else {
$additions[$field_name][] = $item;
}
}
}
}
return $additions;
case 'insert':
case 'update':
foreach ($type['tables'] as $table) {
$schema = drupal_get_schema($table);
$record = array();
foreach ($schema['content fields'] as $field_name) {
if (isset($node->{$field_name})) {
$field = content_fields($field_name, $type_name);
// Multiple fields need specific handling, we'll deal with them later on.
if ($field['multiple']) {
continue;
}
$db_info = content_database_info($field);
foreach ($db_info['columns'] as $column => $attributes) {
$record[$attributes['column']] = $node->{$field_name}[0][$column];
}
}
}
// $record might be empty because
// - the table stores a multiple field :
// we do nothing, this is handled later on
// - this is the per-type table and no field is actually stored in it :
// we still store the nid and vid
if (count($record) || empty($schema['content fields'])) {
$record['nid'] = $node->nid;
$record['vid'] = $node->vid;
// Can't rely on the insert/update op of the node to decide if this
// is an insert or an update, a node or revision may have existed
// before any fields were created, so there may not be an entry here.
// TODO - should we auto create an entry for all existing nodes when
// fields are added to content types -- either a NULL value
// or the default value? May need to offer the user an option of
// how to handle that.
if (db_result(db_query("SELECT COUNT(*) FROM {" . $table . "} WHERE vid = %d", $node->vid))) {
content_write_record($table, $record, array(
'vid',
));
}
else {
content_write_record($table, $record);
}
}
}
// Handle multiple fields.
foreach ($type['fields'] as $field) {
if ($field['multiple'] && isset($node->{$field}['field_name'])) {
$db_info = content_database_info($field);
// Delete and insert, rather than update, in case a value was added.
if ($op == 'update') {
db_query('DELETE FROM {' . $db_info['table'] . '} WHERE vid = %d', $node->vid);
}
// Collect records for non-empty items.
$function = $field['module'] . '_content_is_empty';
$records = array();
foreach ($node->{$field}['field_name'] as $delta => $item) {
if (!$function($item, $field)) {
$record = array();
foreach ($db_info['columns'] as $column => $attributes) {
$record[$attributes['column']] = $item[$column];
}
$record['nid'] = $node->nid;
$record['vid'] = $node->vid;
$record['delta'] = $delta;
$records[] = $record;
}
}
// If there was no non-empty item, insert delta 0 with NULL values.
if (empty($records)) {
$record = array();
foreach ($db_info['columns'] as $column => $attributes) {
$record[$attributes['column']] = NULL;
}
$record['nid'] = $node->nid;
$record['vid'] = $node->vid;
$record['delta'] = 0;
$records[] = $record;
}
// Insert the collected records for this field into database.
foreach ($records as $record) {
content_write_record($db_info['table'], $record);
}
}
}
break;
case 'delete':
foreach ($type['tables'] as $table) {
db_query('DELETE FROM {' . $table . '} WHERE nid = %d', $node->nid);
}
break;
case 'delete revision':
foreach ($type['tables'] as $table) {
db_query('DELETE FROM {' . $table . '} WHERE vid = %d', $node->vid);
}
break;
}
}