Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save chrisns/3973135 to your computer and use it in GitHub Desktop.
Save chrisns/3973135 to your computer and use it in GitHub Desktop.
diff --git modules/field/field.api.php modules/field/field.api.php
index 5f64117..683d9b6 100644
--- modules/field/field.api.php
+++ modules/field/field.api.php
@@ -259,6 +259,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 modules/field/field.crud.inc modules/field/field.crud.inc
index f9c96c9..7988f58 100644
--- modules/field/field.crud.inc
+++ modules/field/field.crud.inc
@@ -21,6 +21,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
@@ -130,9 +148,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.
@@ -242,9 +258,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
@@ -369,9 +383,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'];
@@ -450,6 +462,7 @@ function field_delete_field($field_name) {
* @throws FieldException
*
* See: @link field Field API data structures @endlink.
+ * @see hook_field_schema_alter()
*/
function field_create_instance($instance) {
$field = field_read_field($instance['field_name']);
diff --git modules/field/tests/field.test modules/field/tests/field.test
index 739ddbe..67df80d 100644
--- modules/field/tests/field.test
+++ modules/field/tests/field.test
@@ -2457,6 +2457,49 @@ class FieldCrudTestCase extends FieldTestCase {
}
}
+/**
+ * Tests that the field schema can be altered with hook_field_schema_alter().
+ */
+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('field_test', 'field_test_schema_alter');
+ }
+
+ /**
+ * Tests a hook_field_schema_alter() implementation.
+ *
+ * @see field_test_schema_alter_field_schema_alter()
+ */
+ function testImageFieldSchemaAlter() {
+ $test_field = array(
+ 'field_name' => drupal_strtolower($this->randomName()),
+ 'type' => 'test_field',
+ );
+ field_create_field($test_field);
+ $test_field_name = $test_field['field_name'];
+ $test_field_instance_settings = array(
+ 'field_name' => $test_field_name,
+ 'entity_type' => 'test_entity',
+ 'bundle' => 'test_bundle',
+ 'deleted' => 0,
+ );
+ $test_field_instance = field_create_instance($test_field_instance_settings);
+
+ $table_name = _field_sql_storage_tablename($test_field_instance);
+ $schema = drupal_get_schema($table_name, TRUE);
+ $this->assertEqual('float', $schema['fields'][$test_field_name .'_value']['type']);
+ $this->assertTrue(db_field_exists($table_name, $test_field_name .'_additional_column'));
+ }
+}
+
class FieldInstanceCrudTestCase extends FieldTestCase {
protected $field;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment