home | career | drupal | java | mac | mysql | perl | php | scala | uml | unix

Drupal example source code file (content.crud.inc)

This example Drupal source code file (content.crud.inc) is included in the DevDaily.com "Drupal Source Code Warehouse" project. The intent of this project is to help you "Learn Drupal by Example".

PHP - Drupal tags/keywords

array, database, empty, field, foreach, function, if, instance, module, php, return, setting, sql, unset

The content.crud.inc Drupal example source code

<?php
// $Id: content.crud.inc,v 1.76.2.17 2009/07/14 22:17:05 yched Exp $

/**
 * @file
 * Create/Read/Update/Delete functions for CCK-defined object types.
 *
 * The content module field API will allow $field arguments to
 * be input either in the field => widget nested array that is used
 * by the content module, or in flattened $form_values arrays, by
 * converting flattened arrays to the nested format.
 *
 * A hook_content_fieldapi() is available for each field instance action,
 * and each hook receives the nested field => widget array as an argument.
 *
 * The hook_content_fieldapi() $ops include:
 *
 *   - create instance
 *   - read instance
 *   - update instance
 *   - delete instance
 *
 * Another function, content_module_delete($module) will clean up
 * after a module that has been deleted by removing all data and
 * settings information that was created by that module.
 */

/**
 * Create an array of default values for a field type.
 */
function content_field_default_values($field_type) {
  $field_types = _content_field_types();
  $module = $field_types[$field_type]['module'];

  $field = array(
    'module' => $module,
    'type' => $field_type,
    'active' => 0,
  );

  if (module_exists($module)) {
    $field['active'] = 1;
  }

  $field['columns'] = (array) module_invoke($module, 'field_settings', 'database columns', $field);
  // Ensure columns always default to NULL values.
  foreach ($field['columns'] as $column_name => $column) {
    $field['columns'][$column_name]['not null'] = FALSE;
  }

  $field['required'] = 0;
  $field['multiple'] = 0;
  $field['db_storage'] = CONTENT_DB_STORAGE_PER_CONTENT_TYPE;

  // Make sure field settings all have an index in the array.
  $setting_names = (array) module_invoke($module, 'field_settings', 'save', $field);
  drupal_alter('field_settings', $setting_names, 'save', $field);
  foreach ($setting_names as $setting) {
    $field[$setting] = NULL;
  }
  return $field;
}

/**
 * Create an array of default values for a field instance.
 */
function content_instance_default_values($field_name, $type_name, $widget_type) {
  $widget_types = _content_widget_types();
  $module = $widget_types[$widget_type]['module'];

  $widget = array(
    'field_name' => $field_name,
    'type_name' => $type_name,
    'weight' => 0,
    'label' => $field_name,
    'description' => '',
    'widget_type' => $widget_type,
    'widget_module' => $module,
    'display_settings' => array(),
    'widget_settings' => array(),
  );

  if (module_exists($module)) {
    $widget['widget_active'] = 1;
  }

  $settings_names = array_merge(array('label'), array_keys(content_build_modes()));
  $widget['display_settings'] = array();
  foreach ($settings_names as $name) {
    $widget['display_settings'][$name]['format'] = ($name == 'label') ? 'above' : 'default';
    $widget['display_settings'][$name]['exclude'] = 0;
  }

  // Make sure widget settings all have an index in the array.
  $settings_names = (array) module_invoke($module, 'widget_settings', 'save', $widget);
  drupal_alter('widget_settings', $settings_names, 'save', $widget);
  $widget['widget_settings'] = array();
  foreach ($settings_names as $name) {
    $widget['widget_settings'][$name] = NULL;
  }
  return $widget;
}

/**
 * Expand field info to create field => widget info.
 */
function content_field_instance_expand($field) {
  if (isset($field['widget'])) {
    return $field;
  }
  $field['widget'] = !empty($field['widget_settings']) ? $field['widget_settings'] : array();
  $field['widget']['label'] = !empty($field['label']) ? $field['label'] : $field['field_name'];
  $field['widget']['weight'] = !empty($field['weight']) ? $field['weight'] : 0;
  $field['widget']['description'] = !empty($field['description']) ? $field['description'] : '';

  if (!empty($field['widget_type'])) {
    $field['widget']['type'] = $field['widget_type'];
    $widget_types = _content_widget_types();
    $field['widget']['module'] = isset($widget_types[$field['widget_type']]['module']) ? $widget_types[$field['widget_type']]['module'] : $field['widget_module'];
  }
  elseif (!empty($field['widget_module'])) {
    $field['widget']['module'] = $field['widget_module'];
  }

  unset($field['widget_type']);
  unset($field['weight']);
  unset($field['label']);
  unset($field['description']);
  unset($field['widget_module']);
  unset($field['widget_settings']);

  // If content.module is handling the default value,
  // initialize $widget_settings with default values,
  if (isset($field['default_value']) && isset($field['default_value_php']) &&
      content_callback('widget', 'default value', $field) == CONTENT_CALLBACK_DEFAULT) {
    $field['widget']['default_value'] = !empty($field['default_value']) ? $field['default_value']  : NULL;
    $field['widget']['default_value_php'] = !empty($field['default_value_php']) ? $field['default_value_php'] : NULL;
    unset($field['default_value']);
    unset($field['default_value_php']);
  }
  return $field;
}

/**
 * Collapse field info from field => widget to flattened form values.
 */
function content_field_instance_collapse($field) {
  if (!isset($field['widget'])) {
    return $field;
  }
  $field['widget_settings'] = !empty($field['widget']) ? $field['widget'] : array();
  $field['widget_type'] = !empty($field['widget']['type']) ? $field['widget']['type'] : '';
  $field['weight'] = !empty($field['widget']['weight']) ? $field['widget']['weight'] : 0;
  $field['label'] = !empty($field['widget']['label']) ? $field['widget']['label'] : $field['field_name'];
  $field['description'] = !empty($field['widget']['description']) ? $field['widget']['description'] : '';
  $field['type_name'] = !empty($field['type_name']) ? $field['type_name'] : '';

  if (!empty($field['widget']['module'])) {
    $widget_module = $field['widget']['module'];
  }
  elseif (!empty($field['widget']['type'])) {
    $widget_types = _content_widget_types();
    $widget_module = $widget_types[$field['widget']['type']]['module'];
  }
  else {
    $widget_module = '';
  }
  $field['widget_module'] = $widget_module;
  unset($field['widget_settings']['type']);
  unset($field['widget_settings']['weight']);
  unset($field['widget_settings']['label']);
  unset($field['widget_settings']['description']);
  unset($field['widget_settings']['module']);
  unset($field['widget']);
  return $field;
}

/**
 * Create a new field instance.
 *
 * @param $field
 *   An array of properties to create the field with, input either in
 *   the field => widget format used by the content module or as an
 *   array of form values.
 *
 *   Required values:
 *   - field_name, the name of the field to be created
 *   - type_name, the content type of the instance to be created
 *
 *   If there is no prior instance to create this from, we also need:
 *   - type, the type of field to create
 *   - widget_type, the type of widget to use
 * @param $rebuild
 *   TRUE to clear content type caches and rebuild menu (default).
 *   FALSE allows the caller to process several fields at a time quickly, but then
 *   the caller is reponsible to clear content type caches and rebuild menu as soon
 *   as all fields have been processed. For example:
 *   @code
 *     // Create several fields at a time.
 *     foreach ($fields as $field) {
 *       content_field_instance_create($field, FALSE);
 *     }
 *     // Clear caches and rebuild menu.
 *     content_clear_type_cache(TRUE);
 *     menu_rebuild();
 *   @endcode
 * @see content_clear_type_cache()
 * @see menu_rebuild()
 */
function content_field_instance_create($field, $rebuild = TRUE) {
  include_once('./'. drupal_get_path('module', 'content') .'/includes/content.admin.inc');

  $form_values = $field;
  $field = content_field_instance_expand($field);

  // If there are prior instances, fill out missing values from the prior values,
  // otherwise get missing values from default values.
  $prior_instances = content_field_instance_read(array('field_name' => $field['field_name']));
  if (!empty($prior_instances) && is_array($prior_instances)) {
    $prev_field = content_field_instance_expand($prior_instances[0]);

    // Weight, label, and description may have been forced into the $field
    // by content_field_instance_expand(). If there is a previous instance to
    // get these values from and there was no value supplied originally, use
    // the previous value.
    $field['widget']['weight'] = isset($form_values['weight']) ? $form_values['weight'] : $prev_field['widget']['weight'];
    $field['widget']['label']  = isset($form_values['label']) ? $form_values['label'] : $prev_field['widget']['label'];
    $field['widget']['description'] = isset($form_values['description']) ? $form_values['description'] : $prev_field['widget']['description'];
  }
  else {
    $prev_field = array('widget' => array());
  }

  // If we have a field type, we can build default values for this field type.
  $default_values = array('widget' => array());
  if (isset($field['type'])) {
    $default_values = content_field_default_values($field['type']);
    $default_instance_values = content_instance_default_values($field['field_name'], $field['type_name'], $field['widget']['type']);
    $default_values = content_field_instance_expand(array_merge($default_values, $default_instance_values));
  }

  // Merge default values, previous values, and current values to create
  // a complete field array.
  $widget = array_merge($default_values['widget'], $prev_field['widget'], $field['widget']);
  $field = array_merge($default_values, $prev_field, $field);
  $field['widget'] = $widget;

  // Make sure we know what module to invoke for field info.
  if (empty($field['module']) && !empty($field['type'])) {
    $field_types = _content_field_types();
    $field['module'] = $field_types[$field['type']]['module'];
  }

  // The storage type may need to be updated.
  $field['db_storage'] = content_storage_type($field);

  // Get a fresh copy of the column information whenever a field is created.
  $field['columns'] = (array) module_invoke($field['module'], 'field_settings', 'database columns', $field);

  if (empty($prev_field['widget']) || $prior_instances < 1) {
    // If this is the first instance, create the field.
    $field['db_storage'] = $field['multiple'] > 0 ? CONTENT_DB_STORAGE_PER_FIELD : CONTENT_DB_STORAGE_PER_CONTENT_TYPE;
    _content_field_write($field, 'create');
  }
  elseif (!empty($prev_field['widget']) && $prev_field['db_storage'] == CONTENT_DB_STORAGE_PER_CONTENT_TYPE && count($prior_instances) > 0) {
    // If the database storage has changed, update the field and previous instances.
    $field['db_storage'] = CONTENT_DB_STORAGE_PER_FIELD;

    foreach ($prior_instances as $instance) {
      $new_instance = $instance;
      $new_instance['db_storage'] = CONTENT_DB_STORAGE_PER_FIELD;

      // Invoke hook_content_fieldapi().
      module_invoke_all('content_fieldapi', 'update instance', $new_instance);

      content_alter_schema($instance, $new_instance);
    }
  }

  // Invoke hook_content_fieldapi().
  module_invoke_all('content_fieldapi', 'create instance', $field);

  // Update the field and the instance with the latest values.
  _content_field_write($field, 'update');
  _content_field_instance_write($field, 'create');

  content_alter_schema(array(), $field);

  if ($rebuild) {
    content_clear_type_cache(TRUE);
    menu_rebuild();
  }

  return $field;
}

/**
 * Update an existing field instance.
 *
 * @param $field
 *   An array of properties to update the field with, input either in
 *   the field => widget format used by the content module or as an
 *   array of form values.
 * @param $rebuild
 *   TRUE to clear content type caches and rebuild menu (default).
 *   FALSE allows the caller to process several fields at a time quickly, but then
 *   the caller is reponsible to clear content type caches and rebuild menu as soon
 *   as all fields have been processed. For example:
 *   @code
 *     // Update several fields at a time.
 *     foreach ($fields as $field) {
 *       content_field_instance_update($field, FALSE);
 *     }
 *     // Clear caches and rebuild menu.
 *     content_clear_type_cache(TRUE);
 *     menu_rebuild();
 *   @endcode
 * @see content_clear_type_cache()
 * @see menu_rebuild()
 */
function content_field_instance_update($field, $rebuild = TRUE) {
  include_once('./'. drupal_get_path('module', 'content') .'/includes/content.admin.inc');

  // Ensure the field description is in the 'expanded' form.
  $field = content_field_instance_expand($field);

  // Get the previous value from the table.
  $previous = content_field_instance_read(array('field_name' => $field['field_name'], 'type_name' => $field['type_name']));
  $prev_field = array_pop($previous);

  // Create a complete field array by merging the previous and current values,
  // letting the current values overwrite the previous ones.
  $widget = array_merge($prev_field['widget'], $field['widget']);
  $field = array_merge($prev_field, $field);
  $field['widget'] = $widget;

  // Make sure we know what module to invoke for field info.
  if (empty($field['module']) && !empty($field['type'])) {
    $field_types = _content_field_types();
    $field['module'] = $field_types[$field['type']]['module'];
  }

  // The storage type may need to be updated.
  $field['db_storage'] = content_storage_type($field);

  // Changes in field values may affect columns, or column
  // information may have changed, get a fresh copy.
  $field['columns'] = (array) module_invoke($field['module'], 'field_settings', 'database columns', $field);

  // If the database storage has changed, update the field and previous instances.
  $prior_instances = content_field_instance_read(array('field_name' => $field['field_name']));

  if ($prev_field['db_storage'] == CONTENT_DB_STORAGE_PER_CONTENT_TYPE && count($prior_instances) > 1) {
    // Update the field's data storage.
    $field['db_storage'] = CONTENT_DB_STORAGE_PER_FIELD;

    // Update the schema for prior instances to adapt to the change in db storage.
    foreach ($prior_instances as $instance) {
      if ($instance['type_name'] != $field['type_name']) {
        $new_instance = $instance;
        $new_instance['db_storage'] = CONTENT_DB_STORAGE_PER_FIELD;

        // Invoke hook_content_fieldapi().
        module_invoke_all('content_fieldapi', 'update instance', $new_instance);

        content_alter_schema($instance, $new_instance);
      }
    }
  }

  // Invoke hook_content_fieldapi().
  module_invoke_all('content_fieldapi', 'update instance', $field);

  // Update the field and the instance with the latest values.
  _content_field_write($field, 'update');
  _content_field_instance_write($field, 'update');

  content_alter_schema($prev_field, $field);

  if ($rebuild) {
    content_clear_type_cache(TRUE);

    // The label is in the menu tree, so we need a menu rebuild
    // if the label changes.
    if ($prev_field['widget']['label'] != $field['widget']['label']) {
      menu_rebuild();
    }
  }

  return $field;
}

/**
 * Write a field record.
 *
 * @param $field
 *   The field array to process.
 */
function _content_field_write($field, $op = 'update') {
  // Rearrange the data to create the global_settings array.
  $field['global_settings'] = array();
  $setting_names = (array) module_invoke($field['module'], 'field_settings', 'save', $field);
  drupal_alter('field_settings', $setting_names, 'save', $field);

  foreach ($setting_names as $setting) {
    // Unlike _content_field_instance_write() and 'widget_settings', 'global_settings'
    // is never preexisting, so we take no particular precautions here.
    $field['global_settings'][$setting] = isset($field[$setting]) ? $field[$setting] : '';
    unset($field[$setting]);
  }
  // 'columns' is a reserved word in MySQL4, so our column is named 'db_columns'.
  $field['db_columns'] = $field['columns'];

  switch ($op) {
    case 'create':
      drupal_write_record(content_field_tablename(), $field);
      break;
    case 'update':
      drupal_write_record(content_field_tablename(), $field, 'field_name');
      break;
  }
  unset($field['db_columns']);
  return $field;
}

/**
 * Write a field instance record.
 *
 * @param $field
 *   The field array to process.
 */
function _content_field_instance_write($field, $op = 'update') {
  // Collapse the field => widget format, so that the values to be saved by
  // drupal_write_record are on top-level.
  $field = content_field_instance_collapse($field);

  // Rearrange the data to create the widget_settings array.
  $setting_names = (array) module_invoke($field['widget_module'], 'widget_settings', 'save', $field);
  drupal_alter('widget_settings', $setting_names, 'save', $field);
  foreach ($setting_names as $setting) {
    // In some cases (when the updated $field was originally read from
    // the db, as opposed to gathered from the values of a form), the values
    // are already in the right place, we take care to not wipe them.
    if (isset($field[$setting])) {
      $field['widget_settings'][$setting] = $field[$setting];
      unset($field[$setting]);
    }
  }

  switch ($op) {
    case 'create':
      drupal_write_record(content_instance_tablename(), $field);
      break;
    case 'update':
      drupal_write_record(content_instance_tablename(), $field, array('field_name', 'type_name'));
      break;
  }
  return $field;
}

/**
 * Load a field instance.
 *
 * @param $param
 *   An array of properties to use in selecting a field instance. Valid keys:
 *   - 'type_name' - The name of the content type in which the instance exists.
 *   - 'field_name' - The name of the field whose instance is to be loaded.
 *   if NULL, all instances will be returned.
 * @param $include_inactive
 *   TRUE will return field instances that are 'inactive', because their field
 *   module or widget module is currently disabled.
 * @return
 *   The field arrays.
 */
function content_field_instance_read($param = NULL, $include_inactive = FALSE) {
  $cond = array();
  $args = array();
  if (is_array($param)) {
    // Turn the conditions into a query.
    foreach ($param as $key => $value) {
      $cond[] = 'nfi.'. db_escape_string($key) ." = '%s'";
      $args[] = $value;
    }
  }
  if (!$include_inactive) {
    $cond[] = 'nf.active = 1';
    $cond[] = 'nfi.widget_active = 1';
  }
  $where = $cond ? ' WHERE '. implode(' AND ', $cond) : '';

  $db_result = db_query("SELECT * FROM {". content_instance_tablename() ."} nfi ".
    " JOIN {". content_field_tablename() ."} nf ON nfi.field_name = nf.field_name ".
    "$where ORDER BY nfi.weight ASC, nfi.label ASC", $args);

  $fields = array();
  while ($instance = db_fetch_array($db_result)) {
    // Unserialize arrays.
    foreach (array('widget_settings', 'display_settings', 'global_settings', 'db_columns') as $key) {
      $instance[$key] = (!empty($instance[$key])) ? (array) unserialize($instance[$key]) : array();
    }
    // 'columns' is a reserved word in MySQL4, so our column is named 'db_columns'.
    $instance['columns'] = $instance['db_columns'];
    unset($instance['db_columns']);

    // Unfold 'global_settings'.
    foreach ($instance['global_settings'] as $key => $value) {
      $instance[$key] = $value;
    }
    unset($instance['global_settings']);

    // Put the field in the $field => 'widget' structure that is used
    // all around content.module.
    $field = content_field_instance_expand($instance);

    // Invoke hook_content_fieldapi().
    module_invoke_all('content_fieldapi', 'read instance', $field);
    $fields[] = $field;
  }
  return $fields;
}

/**
 * Delete an existing field instance.
 *
 * @param $field_name
 *   The field name to delete.
 * @param $type_name
 *   The content type where the field instance is going to be deleted.
 * @param $rebuild
 *   TRUE to clear content type caches and rebuild menu (default).
 *   FALSE allows the caller to process several fields at a time quickly, but then
 *   the caller is reponsible to clear content type caches and rebuild menu as soon
 *   as all fields have been processed. For example:
 *   @code
 *     // Delete several fields at a time.
 *     foreach ($fields as $field) {
 *       content_field_instance_delete($field['field_name'], $type_name, FALSE);
 *     }
 *     // Clear caches and rebuild menu.
 *     content_clear_type_cache(TRUE);
 *     menu_rebuild();
 *   @endcode
 * @see content_clear_type_cache()
 * @see menu_rebuild()
 */
function content_field_instance_delete($field_name, $type_name, $rebuild = TRUE) {
  include_once('./'. drupal_get_path('module', 'content') .'/includes/content.admin.inc');

  // Get the previous field value.
  $field = array_pop(content_field_instance_read(array('field_name' => $field_name, 'type_name' => $type_name)));

  // Invoke hook_content_fieldapi().
  module_invoke_all('content_fieldapi', 'delete instance', $field);

  db_query("DELETE FROM {". content_instance_tablename() .
    "} WHERE field_name = '%s' AND type_name = '%s'", $field['field_name'], $field['type_name']);

  // If no instances remain, delete the field entirely.
  $instances = content_field_instance_read(array('field_name' => $field_name));
  if (sizeof($instances) < 1) {
    db_query("DELETE FROM {". content_field_tablename() ."} WHERE field_name = '%s'", $field['field_name']);
    content_alter_schema($field, array());
  }
  // If only one instance remains, we may need to change the database
  // representation for this field.
  elseif (sizeof($instances) == 1 && !($field['multiple'])) {
    // Multiple-valued fields are always stored per-field-type.
    $instance = $instances[0];
    $new_instance = $instance;
    $new_instance['db_storage'] = CONTENT_DB_STORAGE_PER_CONTENT_TYPE;
    _content_field_write($new_instance, 'update');

    content_alter_schema($instance, $new_instance);
  }

  // If the deleted instance was the last field for the content type,
  // we drop the per-type table. We also consider possibly inactive fields.
  if (!content_field_instance_read(array('type_name' => $field['type_name']), TRUE)) {
    $base_tablename = _content_tablename($field['type_name'], CONTENT_DB_STORAGE_PER_CONTENT_TYPE);
    if (db_table_exists($base_tablename)) {
      db_drop_table($ret, $base_tablename);
    }
  }

  if ($rebuild) {
    content_clear_type_cache(TRUE);
    menu_rebuild();
  }

  return $field;
}

/**
 * Delete all data related to a module.
 *
 * @param string $module
 */
function content_module_delete($module) {
  // Delete the field data.
  // If content module has been uninstalled first, all tables
  // have already been dropped, and running that code will raise errors.
  if (db_table_exists(content_instance_tablename())) {
    $results = db_query("SELECT field_name, type_name FROM {". content_instance_tablename() ."} WHERE widget_module = '%s'", $module);
    while ($field = db_fetch_array($results)) {
      content_field_instance_delete($field['field_name'], $field['type_name'], FALSE);
    }
    // Force the caches and static arrays to update to the new info.
    content_clear_type_cache(TRUE);
    menu_rebuild();
  }
}

/**
 * Make changes needed when a content type is created.
 *
 * @param $info
 *   value supplied by hook_node_type()
 *
 * node_get_types() is still missing the new type at this point due to
 * a static caching bug. We ask it to rebuild its cache so that
 * content_clear_type_cache() can do its job properly.
 */
function content_type_create($info) {
  node_get_types(NULL, NULL, TRUE);
  content_clear_type_cache(TRUE);
}

/**
 * Make changes needed when an existing content type is updated.
 *
 * @param $info
 *   value supplied by hook_node_type()
 */
function content_type_update($info) {
  if (!empty($info->old_type) && $info->old_type != $info->type) {
    // Rename the content type in all fields that use changed content type.
    db_query("UPDATE {". content_instance_tablename() ."} SET type_name='%s' WHERE type_name='%s'", array($info->type, $info->old_type));

    // Rename the content fields table to match new content type name.
    $old_type = content_types($info->old_type);
    $old_name = _content_tablename($old_type['type'], CONTENT_DB_STORAGE_PER_CONTENT_TYPE);
    $new_name = _content_tablename($info->type, CONTENT_DB_STORAGE_PER_CONTENT_TYPE);
    if (db_table_exists($old_name)) {
      $ret = array();
      db_rename_table($ret, $old_name, $new_name);
      watchdog('content', 'Content fields table %old_name has been renamed to %new_name and field instances have been updated.', array(
        '%old_name' => $old_name, '%new_name' => $new_name));
    }

    // Rename the variable storing weights for non-CCK fields.
    if ($extra = variable_get('content_extra_weights_'. $info->old_type, array())) {
      variable_set('content_extra_weights_'. $info->type, $extra);
      variable_del('content_extra_weights_'. $info->old_type);
    }
  }

  // Reset all content type info.
  // Menu needs to be rebuilt as well, but node types need to be rebuilt first.
  // node_type_form_submit() takes care of this.
  content_clear_type_cache(TRUE);
}

/**
 * Make changes needed when a content type is deleted.
 *
 * @param $info
 *   value supplied by hook_node_type()
 *
 * TODO should we skip doing this entirely since core leaves the
 * nodes in the database as orphans and wait until the nodes are
 * deleted to respond?
 *
 */
function content_type_delete($info) {
  // Don't delete data for content-types defined by disabled modules.
  if (!empty($info->disabled)) {
    return;
  }

  // TODO : What about inactive fields ?
  // Currently, content_field_instance_delete doesn't work on those...
  $fields = content_field_instance_read(array('type_name' => $info->type));
  foreach ($fields as $field) {
    content_field_instance_delete($field['field_name'], $info->type, FALSE);
  }
  $table = _content_tablename($info->type, CONTENT_DB_STORAGE_PER_CONTENT_TYPE);
  if (db_table_exists($table)) {
    $ret = array();
    db_drop_table($ret, $table);
    watchdog('content', 'The content fields table %name has been deleted.', array('%name' => $table));
  }
  // Menu needs to be rebuilt as well, but node types need to be rebuilt first.
  // node_type_form_submit() takes care of this.
  content_clear_type_cache(TRUE);
}

Other Drupal examples (source code examples)

Here is a short list of links related to this Drupal content.crud.inc source code file:

new blog posts

"Drupal" is a registered trademark of Dries Buytaert.

my drupal tutorials and examples  

Copyright 1998-2016 Alvin Alexander, alvinalexander.com
All Rights Reserved.

Beginning in 2016, a portion of the proceeds from pages under the '/drupal-code-examples/' URI will be donated to charity.