Commit 57090c33 authored by Dries's avatar Dries

- Patch #367013 by bjaspan, yched: clean ups for field_update_field().

parent 4d99a966
......@@ -1315,7 +1315,7 @@ function hook_field_create_instance($instance) {
* @param $has_data
* Whether any data already exists for this field.
* @return
* Throws a FieldException to prevent the update from occuring.
* Throws a FieldUpdateForbiddenException to prevent the update from occuring.
*/
function hook_field_update_field_forbid($field, $prior_field, $has_data) {
// A 'list' field stores integer keys mapped to display values. If
......@@ -1328,7 +1328,7 @@ function hook_field_update_field_forbid($field, $prior_field, $has_data) {
// If any data exist for those keys, forbid the update.
$count = field_attach_query($prior_field['id'], array('value', $lost_keys, 'IN'), 1);
if ($count > 0) {
throw new FieldException("Cannot update a list field not to include keys with existing data");
throw new FieldUpdateForbiddenException("Cannot update a list field not to include keys with existing data");
}
}
}
......
......@@ -1109,19 +1109,6 @@ function field_attach_query_revisions($field_id, $conditions, $count, &$cursor =
return field_attach_query($field_id, $conditions, $count, $cursor, FIELD_LOAD_REVISION);
}
/**
* Determine whether a field has any data.
*
* @param $field
* A field structure.
* @return
* TRUE if the field has data for any object; FALSE otherwise.
*/
function field_attach_field_has_data($field) {
$results = field_attach_query($field['id'], array(), 1);
return !empty($results);
}
/**
* Generate and return a structured content array tree suitable for
* drupal_render() for all of the fields on an object. The format of
......
......@@ -410,7 +410,7 @@ function field_update_field($field) {
);
$field['indexes'] += $schema['indexes'];
$has_data = field_attach_field_has_data($field);
$has_data = field_has_data($field);
// See if any module forbids the update by throwing an exception.
foreach (module_implements('field_update_forbid') as $module) {
......
......@@ -130,6 +130,11 @@
*/
class FieldException extends Exception {}
/**
* Exception class thrown by hook_field_update_forbid().
*/
class FieldUpdateForbiddenException extends FieldException {}
/**
* Implement hook_flush_caches.
*/
......@@ -610,6 +615,19 @@ function field_view_field($obj_type, $object, $field, $instance, $build_mode = '
return $output;
}
/**
* Determine whether a field has any data.
*
* @param $field
* A field structure.
* @return
* TRUE if the field has data for any object; FALSE otherwise.
*/
function field_has_data($field) {
$results = field_attach_query($field['id'], array(), 1);
return !empty($results);
}
/**
* Determine whether the user has access to a given field.
*
......
......@@ -1873,30 +1873,6 @@ class FieldCrudTestCase extends FieldTestCase {
$this->assertEqual($entity->decimal53[FIELD_LANGUAGE_NONE][2]['value'], '1.236', t('4 decimal places are rounded to 3'));
}
/**
* Test updating a field with data.
*/
function testUpdateFieldSchemaWithData() {
// Create a decimal 5.2 field and add some data.
$field = array('field_name' => 'decimal52', 'type' => 'number_decimal', 'settings' => array('precision' => 5, 'scale' => 2));
$field = field_create_field($field);
$instance = array('field_name' => 'decimal52', 'bundle' => FIELD_TEST_BUNDLE);
$instance = field_create_instance($instance);
$entity = field_test_create_stub_entity(0, 0, $instance['bundle']);
$entity->decimal52[FIELD_LANGUAGE_NONE][0]['value'] = '1.235';
field_attach_insert('test_entity', $entity);
// Attempt to update the field in a way that would work without data.
$field['settings']['scale'] = 3;
try {
field_update_field($field);
$this->fail(t('Cannot update field schema with data.'));
}
catch (FieldException $e) {
$this->pass(t('Cannot update field schema with data.'));
}
}
/**
* Test field type modules forbidding an update.
*/
......
......@@ -223,7 +223,7 @@ function field_sql_storage_field_storage_create_field($field) {
*/
function field_sql_storage_field_update_forbid($field, $prior_field, $has_data) {
if ($has_data && $field['columns'] != $prior_field['columns']) {
throw new FieldException("field_sql_storage cannot change the schema for an existing field with data.");
throw new FieldUpdateForbiddenException("field_sql_storage cannot change the schema for an existing field with data.");
}
}
......
......@@ -295,6 +295,29 @@ class FieldSqlStorageTestCase extends DrupalWebTestCase {
$this->assertEqual($count, 1, 'NULL field translation is wiped.');
}
/**
* Test trying to update a field with data.
*/
function testUpdateFieldSchemaWithData() {
// Create a decimal 5.2 field and add some data.
$field = array('field_name' => 'decimal52', 'type' => 'number_decimal', 'settings' => array('precision' => 5, 'scale' => 2));
$field = field_create_field($field);
$instance = array('field_name' => 'decimal52', 'bundle' => FIELD_TEST_BUNDLE);
$instance = field_create_instance($instance);
$entity = field_test_create_stub_entity(0, 0, $instance['bundle']);
$entity->decimal52[FIELD_LANGUAGE_NONE][0]['value'] = '1.235';
field_attach_insert('test_entity', $entity);
// Attempt to update the field in a way that would work without data.
$field['settings']['scale'] = 3;
try {
field_update_field($field);
$this->fail(t('Cannot update field schema with data.'));
}
catch (FieldException $e) {
$this->pass(t('Cannot update field schema with data.'));
}
}
/**
* Test adding and removing indexes while data is present.
......
......@@ -1115,7 +1115,7 @@ function field_ui_field_edit_form($form, &$form_state, $obj_type, $bundle, $inst
$description .= $info['description'] . '</p>';
$form['#prefix'] = '<div class="description">' . $description . '</div>';
$has_data = field_attach_field_has_data($field);
$has_data = field_has_data($field);
if ($has_data) {
$description = '<p>' . t('These settings apply to the %field field everywhere it is used. Because the field already has data, some settings can no longer be changed.', array('%field' => $instance['label'])) . '</p>';
}
......@@ -1144,7 +1144,7 @@ function field_ui_field_edit_form($form, &$form_state, $obj_type, $bundle, $inst
'#description' => $description,
);
// Add additional field settings from the field module. The field module is
// Add additional field type settings. The field type module is
// responsible for not returning settings that cannot be changed if
// the field already has data.
$additions = module_invoke($field['module'], 'field_settings_form', $field, $instance, $has_data);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment