diff --git a/core/modules/field/field.api.php b/core/modules/field/field.api.php index 4b71248..63c388d 100644 --- a/core/modules/field/field.api.php +++ b/core/modules/field/field.api.php @@ -274,6 +274,32 @@ function hook_field_schema($field) { } /** + * Allow modules to alter the schema for a field. + * + * @param $schema + * The schema definition as returned by hook_field_schema(). + * @param $field + * The field definition. + * + * @see field_retrieve_schema() + */ +function hook_field_schema_alter(&$schema, $field) { + if ($field['type'] == 'image') { + // Alter the length of a field. + $schema['columns']['alt']['length'] = 2048; + // Add an addtional column of data. + $schema['columns']['additional_column'] = array( + 'description' => "Addtional column added to image field table.", + 'type' => 'varchar', + 'length' => 128, + 'not null' => FALSE, + ); + // Add an additional index. + $schema['indexes']['fid_addtional_column'] = array('fid', 'additional_column'); + } +} + +/** * Define custom load behavior for this module's field types. * * Unlike most other field hooks, this hook operates on multiple entities. The diff --git a/core/modules/field/field.crud.inc b/core/modules/field/field.crud.inc index ff39f22..bc2d6fb 100644 --- a/core/modules/field/field.crud.inc +++ b/core/modules/field/field.crud.inc @@ -20,6 +20,24 @@ */ /** + * Retrieves the schema for a field. + * + * @param $field + * The field array to get the schema definition against. + * @return + * The field schema definition array. + */ +function field_retrieve_schema($field) { + module_load_install($field['module']); + $schema = (array) module_invoke($field['module'], 'field_schema', $field); + $schema += array('columns' => array(), 'indexes' => array(), 'foreign keys' => array()); + // Give other modules a chance to alter this definition. + // @see hook_field_schema_alter() + drupal_alter('field_schema', $schema, $field); + return $schema; +} + +/** * Creates a field. * * This function does not bind the field to any bundle; use @@ -129,9 +147,7 @@ function field_create_field($field) { $field['storage']['module'] = $storage_type['module']; $field['storage']['active'] = 1; // Collect storage information. - module_load_install($field['module']); - $schema = (array) module_invoke($field['module'], 'field_schema', $field); - $schema += array('columns' => array(), 'indexes' => array(), 'foreign keys' => array()); + $schema = field_retrieve_schema($field); // 'columns' are hardcoded in the field type. $field['columns'] = $schema['columns']; // 'foreign keys' are hardcoded in the field type. @@ -241,9 +257,7 @@ function field_update_field($field) { // Collect the new storage information, since what is in // $prior_field may no longer be right. - module_load_install($field['module']); - $schema = (array) module_invoke($field['module'], 'field_schema', $field); - $schema += array('columns' => array(), 'indexes' => array()); + $schema = field_retrieve_schema($field); // 'columns' are hardcoded in the field type. $field['columns'] = $schema['columns']; // 'indexes' can be both hardcoded in the field type, and specified in the @@ -368,9 +382,7 @@ function field_read_fields($params = array(), $include_additional = array()) { module_invoke_all('field_read_field', $field); // Populate storage information. - module_load_install($field['module']); - $schema = (array) module_invoke($field['module'], 'field_schema', $field); - $schema += array('columns' => array(), 'indexes' => array()); + $schema = field_retrieve_schema($field); $field['columns'] = $schema['columns']; $field_name = $field['field_name']; diff --git a/core/modules/field/tests/field.test b/core/modules/field/tests/field.test index 214eab4..9df3fb8 100644 --- a/core/modules/field/tests/field.test +++ b/core/modules/field/tests/field.test @@ -2379,6 +2379,52 @@ class FieldCrudTestCase extends FieldTestCase { } } +class FieldSchemaAlterTestCase extends FieldTestCase { + public static function getInfo() { + return array( + 'name' => 'Field schema alteration tests', + 'description' => 'Alter the schema for a given type of field.', + 'group' => 'Field API', + ); + } + + function setUp() { + parent::setUp('image', 'field_test'); + } + + /** + * Test that new image field gets an altered alt column and a new column. + */ + function testImageFieldSchemaAlter() { + $image_field = array( + 'field_name' => drupal_strtolower($this->randomName()), + 'type' => 'image', + 'settings' => array(), + 'cardinality' => 1, + ); + field_create_field($image_field); + $image_field_name = $image_field['field_name']; + $image_field_instance_settings = array( + 'field_name' => $image_field_name, + 'entity_type' => 'node', + 'bundle' => 'article', + 'required' => TRUE, + 'settings' => array(), + 'widget' => array( + 'type' => 'image_image', + 'settings' => array(), + ), + 'deleted' => 0, + ); + $image_field_instance = field_create_instance($image_field_instance_settings); + + $table_name = _field_sql_storage_tablename($image_field_instance); + $schema = drupal_get_schema($table_name, TRUE); + $this->assertTrue(db_field_exists($table_name, $image_field_name .'_additional_column')); + $this->assertEqual(2048, $schema['fields'][$image_field_name .'_alt']['length']); + } +} + class FieldInstanceCrudTestCase extends FieldTestCase { protected $field; diff --git a/core/modules/field/tests/field_test.module b/core/modules/field/tests/field_test.module index a43a03a..17269d6 100644 --- a/core/modules/field/tests/field_test.module +++ b/core/modules/field/tests/field_test.module @@ -285,3 +285,20 @@ function field_test_field_widget_form_alter(&$element, &$form_state, $context) { break; } } + +/** + * Implements hook_field_schema_alter(). + */ +function field_test_field_schema_alter(&$schema, $field) { + if ($field['type'] == 'image') { + // Alter the length of a field. + $schema['columns']['alt']['length'] = 2048; + // Add an addtional column of data. + $schema['columns']['additional_column'] = array( + 'description' => "Addtional column added to image field table.", + 'type' => 'varchar', + 'length' => 128, + 'not null' => FALSE, + ); + } +}