View source
<?php
define('CONTENT_DB_STORAGE_PER_FIELD', 0);
define('CONTENT_DB_STORAGE_PER_CONTENT_TYPE', 1);
define('CONTENT_CONTEXTS_SIMPLE', 0);
define('CONTENT_CONTEXTS_ADVANCED', 1);
define('CONTENT_CONTEXTS_ALL', 2);
define('CONTENT_CALLBACK_NONE', 0x1);
define('CONTENT_CALLBACK_DEFAULT', 0x2);
define('CONTENT_CALLBACK_CUSTOM', 0x4);
define('CONTENT_HANDLE_CORE', 0x1);
define('CONTENT_HANDLE_MODULE', 0x2);
function content_help($path, $arg) {
switch ($path) {
case 'admin/help#content':
$output = '<p>' . t('The content module, a required component of the Content Construction Kit (CCK), allows administrators to associate custom fields with content types. In Drupal, content types are used to define the characteristics of a post, including the title and description of the fields displayed on its add and edit pages. Using the content module (and the other helper modules included in CCK), custom fields beyond the default "Title" and "Body" may be added. CCK features are accessible through tabs on the <a href="@content-types">content types administration page</a>. (See the <a href="@node-help">node module help page</a> for more information about content types.)', array(
'@content-types' => url('admin/content/types'),
'@node-help' => url('admin/help/node'),
)) . '</p>';
$output .= '<p>' . t('When adding a custom field to a content type, you determine its type (whether it will contain text, numbers, or references to other objects) and how it will be displayed (either as a text field or area, a select box, checkbox, radio button, or autocompleting field). A field may have multiple values (i.e., a "person" may have multiple e-mail addresses) or a single value (i.e., an "employee" has a single employee identification number). As you add and edit fields, CCK automatically adjusts the structure of the database as necessary. CCK also provides a number of other features, including intelligent caching for your custom data, an import and export facility for content type definitions, and integration with other contributed modules.') . '</p>';
$output .= '<p>' . t('Custom field types are provided by a set of optional modules included with CCK (each module provides a different type). The <a href="@modules">modules page</a> allows you to enable or disable CCK components. A default installation of CCK includes:', array(
'@modules' => url('admin/build/modules'),
)) . '</p>';
$output .= '<ul>';
$output .= '<li>' . t('<em>number</em>, which adds numeric field types, in integer, decimal or floating point form. You may define a set of allowed inputs, or specify an allowable range of values. A variety of common formats for displaying numeric data are available.') . '</li>';
$output .= '<li>' . t("<em>text</em>, which adds text field types. A text field may contain plain text only, or optionally, may use Drupal's input format filters to securely manage rich text input. Text input fields may be either a single line (text field), multiple lines (text area), or for greater input control, a select box, checkbox, or radio buttons. If desired, CCK can validate the input to a set of allowed values.") . '</li>';
$output .= '<li>' . t('<em>nodereference</em>, which creates custom references between Drupal nodes. By adding a <em>nodereference</em> field and two different content types, for instance, you can easily create complex parent/child relationships between data (multiple "employee" nodes may contain a <em>nodereference</em> field linking to an "employer" node).') . '</li>';
$output .= '<li>' . t('<em>userreference</em>, which creates custom references to your sites\' user accounts. By adding a <em>userreference</em> field, you can create complex relationships between your site\'s users and posts. To track user involvement in a post beyond Drupal\'s standard <em>Authored by</em> field, for instance, add a <em>userreference</em> field named "Edited by" to a content type to store a link to an editor\'s user account page.') . '</li>';
$output .= '<li>' . t('<em>fieldgroup</em>, which creates collapsible fieldsets to hold a group of related fields. A fieldset may either be open or closed by default. The order of your fieldsets, and the order of fields within a fieldset, is managed via a drag-and-drop interface provided by content module.') . '</li>';
$output .= '</ul>';
$output .= '<p>' . t('For more information, see the online handbook entry for <a href="@handbook-cck">CCK</a> or the <a href="@project-cck">CCK project page</a>.', array(
'@handbook-cck' => 'http://drupal.org/handbook/modules/cck',
'@project-cck' => 'http://drupal.org/project/cck',
)) . '</p>';
return $output;
}
if (preg_match('!^admin/content/node-type/.*/display!', $path)) {
if (preg_match('!^admin/content/node-type/.*/display$!', $path)) {
return t("Configure how this content type's fields and field labels should be displayed when it's viewed in teaser and full-page mode.");
}
else {
return t("Configure how this content type's fields should be displayed when it's rendered in the following contexts.");
}
}
if (preg_match('!^admin/content/node-type/.*/fields$!', $path)) {
return t('Control the order of fields in the input form.');
}
}
function content_devel_caches() {
return array(
content_cache_tablename(),
);
}
function content_flush_caches() {
return array(
content_cache_tablename(),
);
}
function content_init() {
drupal_add_css(drupal_get_path('module', 'content') . '/theme/content.css');
if (module_exists('views')) {
module_load_include('inc', 'content', 'includes/content.views');
}
if (module_exists('token') && !function_exists('content_token_values')) {
module_load_include('inc', 'content', 'includes/content.token');
}
if (module_exists('diff') && !function_exists('content_diff')) {
module_load_include('inc', 'content', 'includes/content.diff');
}
if (content_menu_needs_rebuild()) {
content_clear_type_cache(TRUE);
menu_rebuild();
content_menu_needs_rebuild(FALSE);
}
}
function content_menu_needs_rebuild($rebuild = NULL) {
if (!isset($rebuild)) {
return isset($_SESSION['content_menu_needs_rebuild']);
}
elseif ($rebuild) {
$_SESSION['content_menu_needs_rebuild'] = TRUE;
}
else {
unset($_SESSION['content_menu_needs_rebuild']);
}
}
function content_menu() {
$items = array();
$items['admin/content/types/fields'] = array(
'title' => 'Fields',
'page callback' => '_content_admin_type_fields',
'access arguments' => array(
'administer content types',
),
'file' => 'includes/content.admin.inc',
'type' => MENU_LOCAL_TASK,
);
$items['content/js_add_more'] = array(
'page callback' => 'content_add_more_js',
'access arguments' => array(
'access content',
),
'file' => 'includes/content.node_form.inc',
'type' => MENU_CALLBACK,
);
if (!defined('MAINTENANCE_MODE')) {
foreach (node_get_types() as $type) {
$type_name = $type->type;
$content_type = content_types($type_name);
$type_url_str = $content_type['url_str'];
$items['admin/content/node-type/' . $type_url_str . '/fields'] = array(
'title' => 'Manage fields',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'content_admin_field_overview_form',
$type_name,
),
'access arguments' => array(
'administer content types',
),
'file' => 'includes/content.admin.inc',
'type' => MENU_LOCAL_TASK,
'weight' => 1,
);
$items['admin/content/node-type/' . $type_url_str . '/display'] = array(
'title' => 'Display fields',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'content_admin_display_overview_form',
$type_name,
),
'access arguments' => array(
'administer content types',
),
'file' => 'includes/content.admin.inc',
'type' => MENU_LOCAL_TASK,
'weight' => 2,
);
$items['admin/content/node-type/' . $type_url_str . '/display/general'] = array(
'title' => 'General',
'page arguments' => array(
'content_admin_display_overview_form',
$type_name,
),
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => 0,
);
$items['admin/content/node-type/' . $type_url_str . '/display/advanced'] = array(
'title' => 'Advanced',
'page arguments' => array(
'content_admin_display_overview_form',
$type_name,
(string) CONTENT_CONTEXTS_ADVANCED,
),
'access arguments' => array(
'administer content types',
),
'type' => MENU_LOCAL_TASK,
'weight' => 1,
);
$items['admin/content/node-type/' . $type_url_str . '/add_field'] = array(
'title' => 'Add field',
'page callback' => '_content_admin_field_add',
'page arguments' => array(
$type_name,
),
'access arguments' => array(
'administer content types',
),
'file' => 'includes/content.admin.inc',
'type' => MENU_LOCAL_TASK,
'weight' => 3,
);
foreach ($content_type['fields'] as $field) {
$field_name = $field['field_name'];
$items['admin/content/node-type/' . $type_url_str . '/fields/' . $field_name] = array(
'title' => $field['widget']['label'],
'page callback' => 'drupal_get_form',
'page arguments' => array(
'_content_admin_field',
$type_name,
$field_name,
),
'access arguments' => array(
'administer content types',
),
'file' => 'includes/content.admin.inc',
'type' => MENU_LOCAL_TASK,
);
$items['admin/content/node-type/' . $type_url_str . '/fields/' . $field_name . '/remove'] = array(
'title' => 'Remove field',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'_content_admin_field_remove',
$type_name,
$field_name,
),
'access arguments' => array(
'administer content types',
),
'file' => 'includes/content.admin.inc',
'type' => MENU_CALLBACK,
);
}
}
}
return $items;
}
function content_theme() {
$path = drupal_get_path('module', 'content') . '/theme';
return array(
'content_field_view' => array(
'template' => 'field',
'arguments' => array(
'element' => NULL,
),
'path' => $path,
),
'content_admin_field_overview_form' => array(
'arguments' => array(
'form' => NULL,
),
),
'content_admin_display_overview_form' => array(
'arguments' => array(
'form' => NULL,
),
),
'content_admin_field_add_new_field_widget_type' => array(
'arguments' => array(
'form' => NULL,
),
),
'content_view_multiple_field' => array(
'arguments' => array(
'items' => NULL,
'field' => NULL,
'data' => NULL,
),
),
'content_multiple_values' => array(
'arguments' => array(
'element' => NULL,
),
),
);
}
function content_load($node) {
$cid = 'content:' . $node->nid . ':' . $node->vid;
if ($cached = cache_get($cid, content_cache_tablename())) {
return $cached->data;
}
else {
$default_additions = _content_field_invoke_default('load', $node);
if ($default_additions) {
foreach ($default_additions as $key => $value) {
$node->{$key} = $value;
}
}
$additions = _content_field_invoke('load', $node);
if ($additions) {
foreach ($additions as $key => $value) {
$node->{$key} = $value;
$default_additions[$key] = $value;
}
}
cache_set($cid, $default_additions, content_cache_tablename());
return $default_additions;
}
}
function content_validate(&$node) {
_content_field_invoke('validate', $node);
_content_field_invoke_default('validate', $node);
}
function content_presave(&$node) {
_content_field_invoke('presave', $node);
_content_field_invoke_default('presave', $node);
}
function content_insert(&$node) {
_content_field_invoke('insert', $node);
_content_field_invoke_default('insert', $node);
}
function content_update(&$node) {
_content_field_invoke('update', $node);
_content_field_invoke_default('update', $node);
cache_clear_all('content:' . $node->nid . ':' . $node->vid, content_cache_tablename());
}
function content_delete(&$node) {
$type = content_types($node->type);
if (!empty($type['fields'])) {
_content_field_invoke('delete', $node);
_content_field_invoke_default('delete', $node);
}
$table = _content_tablename($type['type'], CONTENT_DB_STORAGE_PER_CONTENT_TYPE);
if (db_table_exists($table)) {
db_query('DELETE FROM {' . $table . '} WHERE nid = %d', $node->nid);
}
cache_clear_all('content:' . $node->nid, content_cache_tablename(), TRUE);
}
function content_delete_revision(&$node) {
$type = content_types($node->type);
if (!empty($type['fields'])) {
_content_field_invoke('delete revision', $node);
_content_field_invoke_default('delete revision', $node);
}
$table = _content_tablename($type['type'], CONTENT_DB_STORAGE_PER_CONTENT_TYPE);
if (db_table_exists($table)) {
db_query('DELETE FROM {' . $table . '} WHERE vid = %d', $node->vid);
}
cache_clear_all('content:' . $node->nid . ':' . $node->vid, content_cache_tablename());
}
function content_view(&$node, $teaser = FALSE, $page = FALSE) {
_content_field_invoke('sanitize', $node, $teaser, $page);
$additions = _content_field_invoke_default('view', $node, $teaser, $page);
$node->content = array_merge((array) $node->content, $additions);
$type = content_types($node->type);
foreach ($type['extra'] as $key => $value) {
if (isset($value['view']) && isset($node->content[$value['view']])) {
$node->content[$value['view']]['#weight'] = $value['weight'];
}
elseif (isset($node->content[$key])) {
$node->content[$key]['#weight'] = $value['weight'];
}
}
}
function content_alter(&$node, $teaser = FALSE, $page = FALSE) {
_content_field_invoke_default('alter', $node, $teaser, $page);
}
function content_prepare_translation(&$node) {
$additions = _content_field_invoke_default('prepare translation', $node);
$node = (object) array_merge((array) $node, $additions);
}
function content_nodeapi(&$node, $op, $teaser, $page) {
switch ($op) {
case 'load':
return content_load($node);
case 'validate':
content_validate($node);
break;
case 'presave':
content_presave($node);
break;
case 'insert':
content_insert($node);
break;
case 'update':
content_update($node);
break;
case 'delete':
content_delete($node);
break;
case 'delete revision':
content_delete_revision($node);
break;
case 'view':
content_view($node, $teaser, $page);
break;
case 'alter':
content_alter($node, $teaser, $page);
break;
case 'prepare translation':
content_prepare_translation($node);
break;
}
}
function content_form_alter(&$form, $form_state, $form_id) {
if (isset($form['type']) && isset($form['#node']) && $form['type']['#value'] . '_node_form' == $form_id) {
module_load_include('inc', 'content', 'includes/content.node_form');
$form = array_merge($form, content_form($form, $form_state));
$type = content_types($form['type']['#value']);
foreach ($type['extra'] as $key => $value) {
if (isset($form[$key])) {
$form[$key]['#weight'] = $value['weight'];
if ($key == 'title' && isset($form['menu'])) {
$form['menu']['#weight'] = $value['weight'] + 0.1;
}
}
}
}
}
function theme_content_multiple_values($element) {
$field_name = $element['#field_name'];
$field = content_fields($field_name);
$output = '';
if ($field['multiple'] >= 1) {
$table_id = $element['#field_name'] . '_values';
$order_class = $element['#field_name'] . '-delta-order';
$required = !empty($element['#required']) ? '<span class="form-required" title="' . t('This field is required.') . '">*</span>' : '';
$header = array(
array(
'data' => t('!title: !required', array(
'!title' => filter_xss_admin($element['#title']),
'!required' => $required,
)),
'colspan' => 2,
),
t('Order'),
);
$rows = array();
foreach (element_children($element) as $key) {
if ($key !== $element['#field_name'] . '_add_more') {
$element[$key]['_weight']['#attributes']['class'] = $order_class;
$delta_element = drupal_render($element[$key]['_weight']);
$cells = array(
array(
'data' => '',
'class' => 'content-multiple-drag',
),
drupal_render($element[$key]),
array(
'data' => $delta_element,
'class' => 'delta-order',
),
);
$rows[] = array(
'data' => $cells,
'class' => 'draggable',
);
}
}
$output .= theme('table', $header, $rows, array(
'id' => $table_id,
'class' => 'content-multiple-table',
));
$output .= $element['#description'] ? '<div class="description">' . $element['#description'] . '</div>' : '';
$output .= drupal_render($element[$element['#field_name'] . '_add_more']);
drupal_add_tabledrag($table_id, 'order', 'sibling', $order_class);
$field_name_css = str_replace('_', '-', $field_name);
drupal_add_js('if (Drupal.jsEnabled) { $(document).ready(function() { $("#edit-' . $field_name_css . '-' . $field_name_css . '-add-more").val("' . t('Add another item') . '"); }); }', 'inline');
}
else {
foreach (element_children($element) as $key) {
$output .= drupal_render($element[$key]);
}
}
return $output;
}
function content_notify($op, $module) {
switch ($op) {
case 'install':
content_clear_type_cache();
break;
case 'uninstall':
module_load_include('inc', 'content', 'includes/content.crud');
content_module_delete($module);
content_clear_type_cache(TRUE);
break;
case 'enable':
content_associate_fields($module);
content_clear_type_cache();
break;
case 'disable':
content_clear_type_cache(TRUE);
break;
}
}
function content_associate_fields($module) {
$module_fields = module_invoke($module, 'field_info');
if ($module_fields) {
foreach ($module_fields as $name => $field_info) {
watchdog('content', 'Updating field type %type with module %module.', array(
'%type' => $name,
'%module' => $module,
));
db_query("UPDATE {" . content_field_tablename() . "} SET module = '%s', active = %d WHERE type = '%s'", $module, 1, $name);
}
}
$module_widgets = module_invoke($module, 'widget_info');
if ($module_widgets) {
foreach ($module_widgets as $name => $widget_info) {
watchdog('content', 'Updating widget type %type with module %module.', array(
'%type' => $name,
'%module' => $module,
));
db_query("UPDATE {" . content_instance_tablename() . "} SET widget_module = '%s', widget_active = %d WHERE widget_type = '%s'", $module, 1, $name);
}
}
$fields_set = array();
module_load_include('install', 'content');
$types = content_types_install();
foreach ($types as $type_name => $fields) {
foreach ($fields as $field) {
if ($field['module'] == $module && !in_array($field['field_name'], $fields_set)) {
$columns = module_invoke($field['module'], 'field_settings', 'database columns', $field);
db_query("UPDATE {" . content_field_tablename() . "} SET db_columns = '%s' WHERE field_name = '%s'", serialize($columns), $field['field_name']);
$fields_set[] = $field['field_name'];
}
}
}
}
function content_field($op, &$node, $field, &$items, $teaser, $page) {
switch ($op) {
case 'validate':
break;
case 'presave':
if (empty($items) && !isset($node->nid)) {
foreach (array_keys($field['columns']) as $column) {
$items[0][$column] = NULL;
}
$node->{$field}['field_name'] = $items;
}
unset($items[$field['field_name'] . '_add_more']);
if (content_handle('widget', 'multiple values', $field) == CONTENT_HANDLE_CORE) {
$items = content_set_empty($field, $items);
$items = _content_sort_items($field, $items);
}
break;
case 'view':
$element = array();
if ($node->build_mode == NODE_BUILD_NORMAL) {
$context = $teaser ? 'teaser' : 'full';
}
else {
$context = $node->build_mode;
}
if ($context == NODE_BUILD_SEARCH_INDEX) {
$field['display_settings']['label']['format'] = 'hidden';
}
$field_types = _content_field_types();
$formatters = $field_types[$field['type']]['formatters'];
$formatter_name = isset($field['display_settings'][$context]['format']) ? $field['display_settings'][$context]['format'] : 'default';
if (!isset($formatters[$formatter_name]) && $formatter_name != 'hidden') {
$formatter_name = 'default';
}
if (isset($formatters[$formatter_name])) {
$formatter = $formatters[$formatter_name];
$theme = $formatter['module'] . '_formatter_' . $formatter_name;
$single = content_handle('formatter', 'multiple values', $formatter) == CONTENT_HANDLE_CORE;
$element = array(
'#type' => 'content_field_view',
'#title' => $field['widget']['label'],
'#weight' => $field['widget']['weight'],
'#field_name' => $field['field_name'],
'#access' => $formatter_name != 'hidden',
'#node' => $node,
'#teaser' => $teaser,
'#page' => $page,
'#single' => $single,
'items' => array(),
);
foreach ($items as $delta => $item) {
$element['items'][$delta] = array(
'#item' => $item,
'#weight' => $delta,
);
}
$format_info = array(
'#theme' => $theme,
'#field_name' => $field['field_name'],
'#type_name' => $node->type,
'#formatter' => $formatter_name,
);
if ($single) {
foreach ($items as $delta => $item) {
$element['items'][$delta] += $format_info;
}
}
else {
$element['items'] += $format_info;
}
}
return array(
$field['field_name'] => $element,
);
case 'alter':
if (isset($node->content[$field['field_name']])) {
$element = $node->content[$field['field_name']];
if ($element['#single']) {
foreach (element_children($element['items']) as $delta) {
$items[$delta]['view'] = isset($element['items'][$delta]['#children']) ? $element['items'][$delta]['#children'] : '';
}
}
else {
$items[0]['view'] = $element['items']['#children'];
}
}
else {
$items[0]['view'] = '';
}
break;
case 'prepare translation':
$addition = array();
if (isset($node->translation_source->{$field}['field_name'])) {
$addition[$field['field_name']] = $node->translation_source->{$field}['field_name'];
}
return $addition;
}
}
function content_set_empty($field, $items) {
$function = $field['module'] . '_content_is_empty';
$max_delta = $field['multiple'] > 1 ? $field['multiple'] : 0;
foreach ((array) $items as $delta => $item) {
if ($function($item, $field)) {
if ($delta <= $max_delta) {
foreach (array_keys($field['columns']) as $column) {
$items[$delta][$column] = NULL;
}
}
else {
unset($items[$delta]);
}
}
}
return $items;
}
function _content_sort_items($field, $items) {
if ($field['multiple'] >= 1 && isset($items[0]['_weight'])) {
usort($items, '_content_sort_items_helper');
foreach ($items as $delta => $item) {
unset($items[$delta]['_weight']);
}
}
return $items;
}
function _content_sort_items_helper($a, $b) {
$a_weight = is_array($a) && isset($a['_weight']) ? $a['_weight'] : 0;
$b_weight = is_array($b) && isset($b['_weight']) ? $b['_weight'] : 0;
if ($a_weight == $b_weight) {
return 0;
}
return $a_weight < $b_weight ? -1 : 1;
}
function content_storage($op, $node) {
$type_name = $node->type;
$type = content_types($type_name);
switch ($op) {
case 'load':
$additions = array();
foreach ($type['tables'] as $table) {
$schema = drupal_get_schema($table);
$query = 'SELECT * FROM {' . $table . '} WHERE vid = %d';
$result = isset($schema['fields']['delta']) ? db_query($query . ' ORDER BY delta', $node->vid) : db_query_range($query, $node->vid, 0, 1);
while ($row = db_fetch_array($result)) {
foreach ($schema['content fields'] as $field_name) {
$item = array();
$field = content_fields($field_name, $type_name);
$db_info = content_database_info($field);
foreach ($db_info['columns'] as $column => $attributes) {
$item[$column] = $row[$attributes['column']];
}
if (!isset($additions[$field_name])) {
$additions[$field_name] = array();
}
$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);
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];
}
}
}
if (count($record)) {
$record['nid'] = $node->nid;
$record['vid'] = $node->vid;
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);
}
}
}
foreach ($type['fields'] as $field) {
if ($field['multiple'] && isset($node->{$field}['field_name'])) {
$db_info = content_database_info($field);
if ($op == 'update') {
db_query('DELETE FROM {' . $db_info['table'] . '} WHERE vid = %d', $node->vid);
}
foreach ($node->{$field}['field_name'] as $delta => $item) {
$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;
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;
}
}
function content_write_record($table, &$object, $update = array()) {
if (is_string($update)) {
$update = array(
$update,
);
}
if (is_array($object)) {
$object = (object) $object;
$array = TRUE;
}
else {
$array = FALSE;
}
$schema = drupal_get_schema($table);
if (empty($schema)) {
return FALSE;
}
$fields = $defs = $values = $serials = $placeholders = array();
foreach ($schema['fields'] as $field => $info) {
if ($info['type'] == 'serial' && count($update)) {
continue;
}
if (!isset($object->{$field}) && !count($update) && isset($info['default'])) {
$object->{$field} = $info['default'];
}
if ($info['type'] == 'serial') {
$serials[] = $field;
unset($object->{$field});
}
if (isset($object->{$field}) || array_key_exists($field, $object)) {
$fields[] = $field;
if (isset($object->{$field})) {
$placeholders[] = db_type_placeholder($info['type']);
if (empty($info['serialize'])) {
$values[] = $object->{$field};
}
else {
$values[] = serialize($object->{$field});
}
}
else {
$placeholders[] = 'NULL';
}
}
}
$query = '';
if (!count($update)) {
$query = "INSERT INTO {" . $table . "} (" . implode(', ', $fields) . ') VALUES (' . implode(', ', $placeholders) . ')';
$return = SAVED_NEW;
}
else {
$query = '';
foreach ($fields as $id => $field) {
if ($query) {
$query .= ', ';
}
$query .= $field . ' = ' . $placeholders[$id];
}
foreach ($update as $key) {
$conditions[] = "{$key} = " . db_type_placeholder($schema['fields'][$key]['type']);
$values[] = $object->{$key};
}
$query = "UPDATE {" . $table . "} SET {$query} WHERE " . implode(' AND ', $conditions);
$return = SAVED_UPDATED;
}
if (db_query($query, $values)) {
if ($serials) {
foreach ($serials as $field) {
$object->{$field} = db_last_insert_id($table, $field);
}
}
if ($array) {
$object = (array) $object;
}
return $return;
}
return FALSE;
}
function _content_field_invoke($op, &$node, $teaser = NULL, $page = NULL) {
$type_name = is_string($node) ? $node : (is_array($node) ? $node['type'] : $node->type);
$type = content_types($type_name);
$field_types = _content_field_types();
$return = array();
foreach ($type['fields'] as $field) {
$items = isset($node->{$field}['field_name']) ? $node->{$field}['field_name'] : array();
unset($items[$field['field_name'] . '_add_more']);
$module = $field_types[$field['type']]['module'];
$function = $module . '_field';
if (function_exists($function)) {
$result = $function($op, $node, $field, $items, $teaser, $page);
if (is_array($result)) {
$return = array_merge($return, $result);
}
else {
if (isset($result)) {
$return[] = $result;
}
}
}
if (isset($node->{$field}['field_name']) || count($items)) {
$node->{$field}['field_name'] = $items;
}
}
return $return;
}
function _content_field_invoke_default($op, &$node, $teaser = NULL, $page = NULL) {
$type_name = is_string($node) ? $node : (is_array($node) ? $node['type'] : $node->type);
$type = content_types($type_name);
$field_types = _content_field_types();
$return = array();
if (in_array($op, array(
'load',
'insert',
'update',
'delete',
'delete revision',
))) {
return content_storage($op, $node);
}
else {
foreach ($type['fields'] as $field) {
$items = isset($node->{$field}['field_name']) ? $node->{$field}['field_name'] : array();
$result = content_field($op, $node, $field, $items, $teaser, $page);
if (is_array($result)) {
$return = array_merge($return, $result);
}
else {
if (isset($result)) {
$return[] = $result;
}
}
if (isset($node->{$field}['field_name'])) {
$node->{$field}['field_name'] = $items;
}
}
}
return $return;
}
function content_types($type_name = NULL) {
$type_name = !empty($type_name) ? str_replace('-', '_', $type_name) : NULL;
$info = _content_type_info();
if (isset($info['content types'])) {
if (!isset($type_name)) {
return $info['content types'];
}
if (isset($info['content types'][$type_name])) {
return $info['content types'][$type_name];
}
}
}
function content_fields($field_name = NULL, $content_type_name = NULL) {
$info = _content_type_info();
if (isset($info['fields'])) {
if (!isset($field_name)) {
return $info['fields'];
}
if (isset($info['fields'][$field_name])) {
if (!isset($content_type_name)) {
return $info['fields'][$field_name];
}
if (isset($info['content types'][$content_type_name]['fields'][$field_name])) {
return $info['content types'][$content_type_name]['fields'][$field_name];
}
}
}
}
function _content_field_types() {
$info = _content_type_info();
return isset($info['field types']) ? $info['field types'] : array();
}
function _content_widget_types() {
$info = _content_type_info();
return isset($info['widget types']) ? $info['widget types'] : array();
}
function _content_type_info($reset = FALSE) {
static $info;
if ($reset || !isset($info)) {
if (!db_table_exists(content_field_tablename()) || !db_table_exists(content_instance_tablename())) {
return array();
}
if ($cached = cache_get('content_type_info', content_cache_tablename())) {
$info = $cached->data;
}
else {
$info = array(
'field types' => array(),
'widget types' => array(),
'fields' => array(),
'content types' => array(),
);
foreach (module_list() as $module) {
$module_field_types = module_invoke($module, 'field_info');
if ($module_field_types) {
foreach ($module_field_types as $name => $field_info) {
$db_name = substr($name, 0, 32);
$info['field types'][$db_name] = $field_info;
$info['field types'][$db_name]['module'] = $module;
$info['field types'][$db_name]['formatters'] = array();
}
}
}
foreach (module_list() as $module) {
if ($module_widgets = module_invoke($module, 'widget_info')) {
foreach ($module_widgets as $name => $widget_info) {
$db_name = substr($name, 0, 32);
$info['widget types'][$db_name] = $widget_info;
$info['widget types'][$db_name]['module'] = $module;
$info['widget types'][$db_name]['field types'] = array();
foreach ($widget_info['field types'] as $field_type) {
$field_type_db_name = substr($field_type, 0, 32);
if (isset($info['field types'][$field_type_db_name])) {
$info['widget types'][$db_name]['field types'][] = $field_type_db_name;
}
}
}
}
if ($module_formatters = module_invoke($module, 'field_formatter_info')) {
foreach ($module_formatters as $name => $formatter_info) {
foreach ($formatter_info['field types'] as $field_type) {
$db_name = substr($field_type, 0, 32);
if (isset($info['field types'][$db_name])) {
$info['field types'][$db_name]['formatters'][$name] = $formatter_info;
$info['field types'][$db_name]['formatters'][$name]['module'] = $module;
}
}
}
}
}
module_load_include('inc', 'content', 'includes/content.crud');
foreach (node_get_types() as $type_name => $data) {
$type = (array) $data;
$type['url_str'] = str_replace('_', '-', $type['type']);
$type['fields'] = array();
$type['tables'] = array();
$fields = content_field_instance_read(array(
'type_name' => $type_name,
));
foreach ($fields as $field) {
$type['fields'][$field['field_name']] = $field;
$db_info = content_database_info($field);
$type['tables'][$db_info['table']] = $db_info['table'];
$info['fields'][$field['field_name']] = $field;
}
$extra = module_invoke_all('content_extra_fields', $type_name);
drupal_alter('content_extra_fields', $extra, $type_name);
foreach (variable_get('content_extra_weights_' . $type_name, array()) as $key => $value) {
if (isset($extra[$key])) {
$extra[$key]['weight'] = $value;
}
}
$type['extra'] = $extra;
$info['content types'][$type_name] = $type;
}
cache_set('content_type_info', $info, content_cache_tablename());
}
}
return $info;
}
function content_node_type($op, $info) {
switch ($op) {
case 'insert':
module_load_include('inc', 'content', 'includes/content.crud');
content_type_create($info);
break;
case 'update':
module_load_include('inc', 'content', 'includes/content.crud');
content_type_update($info);
break;
case 'delete':
module_load_include('inc', 'content', 'includes/content.crud');
content_type_delete($info);
break;
}
}
function content_clear_type_cache($rebuild_schema = FALSE) {
cache_clear_all('*', content_cache_tablename(), TRUE);
_content_type_info(TRUE);
if ($rebuild_schema) {
$schema = drupal_get_schema(NULL, TRUE);
}
}
function content_database_info($field) {
$db_info = array();
if ($field['db_storage'] == CONTENT_DB_STORAGE_PER_FIELD) {
$db_info['table'] = _content_tablename($field['field_name'], CONTENT_DB_STORAGE_PER_FIELD);
}
else {
$db_info['table'] = _content_tablename($field['type_name'], CONTENT_DB_STORAGE_PER_CONTENT_TYPE);
}
$db_info['columns'] = (array) $field['columns'];
foreach ($db_info['columns'] as $column_name => $attributes) {
$db_info['columns'][$column_name]['column'] = $field['field_name'] . '_' . $column_name;
}
return $db_info;
}
function content_storage_type($field) {
if ($field['multiple'] > 0) {
return CONTENT_DB_STORAGE_PER_FIELD;
}
else {
module_load_include('inc', 'content', 'includes/content.crud');
$instances = content_field_instance_read(array(
'field_name' => $field['field_name'],
));
if (count($instances) > 1) {
return CONTENT_DB_STORAGE_PER_FIELD;
}
}
return CONTENT_DB_STORAGE_PER_CONTENT_TYPE;
}
function content_transpose_array_rows_cols($array) {
$result = array();
if (is_array($array)) {
foreach ($array as $key1 => $value1) {
if (is_array($value1)) {
foreach ($value1 as $key2 => $value2) {
if (!isset($result[$key2])) {
$result[$key2] = array();
}
$result[$key2][$key1] = $value2;
}
}
}
}
return $result;
}
function content_allowed_values($field) {
static $allowed_values;
if (isset($allowed_values[$field['field_name']])) {
return $allowed_values[$field['field_name']];
}
$allowed_values[$field['field_name']] = array();
if (isset($field['allowed_values_php'])) {
ob_start();
$result = eval($field['allowed_values_php']);
if (is_array($result)) {
$allowed_values[$field['field_name']] = $result;
}
ob_end_clean();
}
if (empty($allowed_values[$field['field_name']]) && isset($field['allowed_values'])) {
$list = explode("\n", $field['allowed_values']);
$list = array_map('trim', $list);
$list = array_filter($list, 'strlen');
foreach ($list as $opt) {
if (strpos($opt, '|') !== FALSE) {
list($key, $value) = explode('|', $opt);
$allowed_values[$field['field_name']][$key] = $value ? $value : $key;
}
else {
$allowed_values[$field['field_name']][$opt] = $opt;
}
}
}
return $allowed_values[$field['field_name']];
}
function content_format($field, $item, $formatter = 'default', $node = NULL) {
if (!is_array($field)) {
$field = content_fields($field);
}
$field_types = _content_field_types();
$formatters = $field_types[$field['type']]['formatters'];
if (!isset($formatters[$formatter])) {
$formatter = 'default';
}
$formatter_name = $formatter;
$formatter = $formatters[$formatter_name];
$theme = $formatter['module'] . '_formatter_' . $formatter_name;
$element = array(
'#theme' => $theme,
'#field_name' => $field['field_name'],
'#type_name' => isset($node->type) ? $node->type : '',
'#formatter' => $formatter_name,
);
if (content_handle('formatter', 'multiple values', $formatter) == CONTENT_HANDLE_CORE) {
$items = array(
$item,
);
$function = $field['module'] . '_field';
if (function_exists($function)) {
$function('sanitize', $node, $field, $items, FALSE, FALSE);
}
$element['#item'] = $items[0];
}
else {
$items = $item;
$function = $field['module'] . '_field';
if (function_exists($function)) {
$function('sanitize', $node, $field, $items, FALSE, FALSE);
}
foreach ($items as $delta => $item) {
$element[$delta] = array(
'#item' => $item,
'#weight' => $delta,
);
}
}
return theme($theme, $element);
}
function _content_admin_display_contexts($selector = CONTENT_CONTEXTS_ALL) {
$contexts = array();
if ($selector == CONTENT_CONTEXTS_ALL || $selector == CONTENT_CONTEXTS_SIMPLE) {
$contexts['teaser'] = t('Teaser');
$contexts['full'] = t('Full node');
}
if ($selector == CONTENT_CONTEXTS_ALL || $selector == CONTENT_CONTEXTS_ADVANCED) {
$contexts[NODE_BUILD_RSS] = t('RSS Item');
if (module_exists('search')) {
$contexts[NODE_BUILD_SEARCH_INDEX] = t('Search Index');
$contexts[NODE_BUILD_SEARCH_RESULT] = t('Search Result');
}
}
return $contexts;
}
function _content_tablename($name, $storage, $version = NULL) {
if (is_null($version)) {
$version = variable_get('content_schema_version', 0);
}
if ($version < 1003) {
$version = 0;
}
else {
$version = 1003;
}
$name = str_replace('-', '_', $name);
switch ("{$version}-{$storage}") {
case '0-' . CONTENT_DB_STORAGE_PER_CONTENT_TYPE:
return "node_{$name}";
case '0-' . CONTENT_DB_STORAGE_PER_FIELD:
return "node_data_{$name}";
case '1003-' . CONTENT_DB_STORAGE_PER_CONTENT_TYPE:
return "content_type_{$name}";
case '1003-' . CONTENT_DB_STORAGE_PER_FIELD:
return "content_{$name}";
}
}
function content_field_tablename($version = NULL) {
if (is_null($version)) {
$version = variable_get('content_schema_version', 0);
}
return $version < 6001 ? 'node_field' : 'content_node_field';
}
function content_instance_tablename($version = NULL) {
if (is_null($version)) {
$version = variable_get('content_schema_version', 0);
}
return $version < 6001 ? 'node_field_instance' : 'content_node_field_instance';
}
function content_cache_tablename() {
if (variable_get('content_schema_version', -1) < 6000) {
return 'cache';
}
else {
return 'cache_content';
}
}
function content_table_schema($field = NULL) {
$schema = array(
'fields' => array(
'vid' => array(
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
),
'nid' => array(
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
),
),
'primary key' => array(
'vid',
),
);
if (!empty($field['multiple'])) {
$schema['fields']['delta'] = array(
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
);
$schema['primary key'][] = 'delta';
}
$schema['content fields'] = array();
if (!empty($field['columns'])) {
foreach ($field['columns'] as $column => $attributes) {
$column_name = $field['field_name'] . '_' . $column;
unset($attributes['column']);
unset($attributes['sortable']);
$schema['fields'][$column_name] = $attributes;
}
$schema['content fields'][] = $field['field_name'];
}
return $schema;
}
function content_callback($entity, $op, $field) {
switch ($entity) {
case 'field':
$info = module_invoke($field['module'], "field_info");
return isset($info[$field['type']]['callbacks'][$op]) ? $info[$field['type']]['callbacks'][$op] : CONTENT_CALLBACK_DEFAULT;
case 'widget':
$info = module_invoke($field['widget']['module'], "widget_info");
return isset($info[$field['widget']['type']]['callbacks'][$op]) ? $info[$field['widget']['type']]['callbacks'][$op] : CONTENT_CALLBACK_DEFAULT;
}
}
function content_handle($entity, $op, $object) {
switch ($entity) {
case 'field':
$info = module_invoke($object['module'], "field_info");
return isset($info[$object['type']][$op]) ? $info[$object['type']][$op] : CONTENT_HANDLE_CORE;
case 'widget':
$info = module_invoke($object['widget']['module'], "widget_info");
return isset($info[$object['widget']['type']][$op]) ? $info[$object['widget']['type']][$op] : CONTENT_HANDLE_CORE;
case 'formatter':
return isset($object[$op]) ? $object[$op] : CONTENT_HANDLE_CORE;
}
}
function content_default_value(&$form, &$form_state, $field, $delta) {
$widget_types = _content_widget_types();
$module = $widget_types[$field['widget']['type']]['module'];
$default_value = array();
if (!empty($field['widget']['default_value_php'])) {
ob_start();
$result = eval($field['widget']['default_value_php']);
ob_end_clean();
if (is_array($result)) {
$default_value = $result;
}
}
elseif (!empty($field['widget']['default_value'])) {
$default_value = $field['widget']['default_value'];
}
return (array) $default_value;
}
function content_elements() {
return array(
'content_multiple_values' => array(),
'content_field_view' => array(),
);
}
function template_preprocess_content_field_view(&$variables) {
$element = $variables['element'];
$field = content_fields($element['#field_name'], $element['#node']->type);
$variables['node'] = $element['#node'];
$variables['field'] = $field;
$variables['items'] = array();
if ($element['#single']) {
foreach (element_children($element['items']) as $delta) {
$variables['items'][$delta] = $element['items'][$delta]['#item'];
$variables['items'][$delta]['view'] = isset($element['items'][$delta]['#children']) ? $element['items'][$delta]['#children'] : '';
}
}
else {
foreach (element_children($element['items']) as $delta) {
$variables['items'][$delta] = $element['items'][$delta]['#item'];
}
$variables['items'][0]['view'] = $element['items']['#children'];
}
$variables['teaser'] = $element['#teaser'];
$variables['page'] = $element['#page'];
$field_empty = TRUE;
foreach ($variables['items'] as $delta => $item) {
if (!isset($item['view']) || empty($item['view']) && $item['view'] !== 0) {
$variables['items'][$delta]['empty'] = TRUE;
}
else {
$field_empty = FALSE;
$variables['items'][$delta]['empty'] = FALSE;
}
}
$additions = array(
'field_type' => $field['type'],
'field_name' => $field['field_name'],
'field_type_css' => strtr($field['type'], '_', '-'),
'field_name_css' => strtr($field['field_name'], '_', '-'),
'label' => $field['widget']['label'],
'label_display' => isset($field['display_settings']['label']['format']) ? $field['display_settings']['label']['format'] : 'above',
'field_empty' => $field_empty,
);
$variables = array_merge($variables, $additions);
}
function content_content_fieldapi($op, $field) {
if (module_exists('devel')) {
}
}
function content_content_extra_fields($type_name) {
$type = node_get_types('type', $type_name);
$extra = array();
if ($type->has_title) {
$extra['title'] = array(
'label' => $type->title_label,
'weight' => -5,
);
}
if ($type->has_body) {
$extra['body_field'] = array(
'label' => $type->body_label,
'weight' => 0,
'view' => 'body',
);
}
if (module_exists('locale') && variable_get("language_{$type_name}", 0)) {
$extra['language'] = array(
'label' => t('Language'),
'weight' => 0,
);
}
if (module_exists('taxonomy') && taxonomy_get_vocabularies($type_name)) {
$extra['taxonomy'] = array(
'label' => t('Taxonomy'),
'weight' => -3,
);
}
if (module_exists('upload') && variable_get("upload_{$type_name}", TRUE)) {
$extra['attachments'] = array(
'label' => t('File attachments'),
'weight' => 30,
'view' => 'files',
);
}
return $extra;
}
function content_extra_field_weight($type_name, $pseudo_field_name) {
$type = content_types($type_name);
if (!isset($type['extra'][$pseudo_field_name])) {
content_clear_type_cache();
}
if (isset($type['extra'][$pseudo_field_name])) {
return $type['extra'][$pseudo_field_name]['weight'];
}
}