diff options
author | Dries Buytaert <dries@buytaert.net> | 2009-09-26 15:57:39 +0000 |
---|---|---|
committer | Dries Buytaert <dries@buytaert.net> | 2009-09-26 15:57:39 +0000 |
commit | db09a6178ba423fe2ce85317afaca5c58a5b6887 (patch) | |
tree | 7a23bc57bfb65197a9ac1416d8c989b506e5e05d /modules/field/field.crud.inc | |
parent | dba2ebb118a25ff6ed9bcc6a59cc42c20d55ad66 (diff) | |
download | brdo-db09a6178ba423fe2ce85317afaca5c58a5b6887.tar.gz brdo-db09a6178ba423fe2ce85317afaca5c58a5b6887.tar.bz2 |
- Patch #367013 by bjaspan, KarenS | yched, Dries: add support for field updates.
Diffstat (limited to 'modules/field/field.crud.inc')
-rw-r--r-- | modules/field/field.crud.inc | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/modules/field/field.crud.inc b/modules/field/field.crud.inc index 7f316c4db..210dad136 100644 --- a/modules/field/field.crud.inc +++ b/modules/field/field.crud.inc @@ -312,6 +312,89 @@ function field_create_field($field) { return $field; } +/* + * Update a field. + * + * Any module may forbid any update for any reason. For example, the + * field's storage module might forbid an update if it would change + * the storage schema while data for the field exists. A field type + * module might forbid an update if it would change existing data's + * semantics, or if there are external dependencies on field settings + * that cannot be updated. + * + * @param $field + * A field structure. $field['field_name'] must provided; it + * identifies the field that will be updated to match this + * structure. Any other properties of the field that are not + * specified in $field will be left unchanged, so it is not + * necessary to pass in a fully populated $field structure. + * @return + * Throws a FieldException if the update cannot be performed. + * @see field_create_field() + */ +function field_update_field($field) { + // Check that the specified field exists. + $prior_field = field_read_field($field['field_name']); + if (empty($prior_field)) { + throw new FieldException('Attempt to update a non-existent field.'); + } + + // Use the prior field values for anything not specifically set by the new + // field to be sure that all values are set. + $field += $prior_field; + $field['settings'] += $prior_field['settings']; + + // Field type cannot be changed. + if ($field['type'] != $prior_field['type']) { + throw new FieldException("Cannot change an existing field's type."); + } + + // Collect the new storage information, since what is in + // $prior_field may no longer be right. + $schema = (array) module_invoke($field['module'], 'field_schema', $field); + $schema += array('columns' => array(), 'indexes' => array()); + // 'columns' are hardcoded in the field type. + $field['columns'] = $schema['columns']; + // 'indexes' can be both hardcoded in the field type, and specified in the + // incoming $field definition. + $field += array( + 'indexes' => array(), + ); + $field['indexes'] += $schema['indexes']; + + $has_data = field_attach_field_has_data($field); + + // See if any module forbids the update by throwing an exception. + foreach (module_implements('field_update_forbid') as $module) { + $function = $module . '_field_update_forbid'; + $function($field, $prior_field, $has_data); + } + + // Tell the storage engine to update the field. Do this before + // saving the new definition since it still might fail. + module_invoke(variable_get('field_storage_module', 'field_sql_storage'), 'field_storage_update_field', $field, $prior_field, $has_data); + + // Save the new field definition. @todo: refactor with + // field_create_field. + + // The serialized 'data' column contains everything from $field that does not + // have its own column and is not automatically populated when the field is + // read. + $data = $field; + unset($data['columns'], $data['field_name'], $data['type'], $data['locked'], $data['module'], $data['cardinality'], $data['active'], $data['deleted']); + $field['data'] = $data; + + // Store the field and create the id. + $primary_key = array('id'); + drupal_write_record('field_config', $field, $primary_key); + + // Clear caches + field_cache_clear(TRUE); + + // Invoke external hooks after the cache is cleared for API consistency. + module_invoke_all('field_update_field', $field, $prior_field, $has_data); +} + /** * Read a single field record directly from the database. Generally, * you should use the field_info_field() instead. |