diff options
-rw-r--r-- | modules/comment/comment.install | 2 | ||||
-rw-r--r-- | modules/field/field.crud.inc | 11 | ||||
-rw-r--r-- | modules/field/tests/field.test | 34 | ||||
-rw-r--r-- | modules/field_ui/field_ui.admin.inc | 9 | ||||
-rw-r--r-- | modules/field_ui/field_ui.test | 5 | ||||
-rw-r--r-- | modules/node/node.module | 1 |
6 files changed, 59 insertions, 3 deletions
diff --git a/modules/comment/comment.install b/modules/comment/comment.install index 501252eb0..6865c6b6b 100644 --- a/modules/comment/comment.install +++ b/modules/comment/comment.install @@ -55,6 +55,7 @@ function comment_enable() { $field = array( 'field_name' => 'comment_body', 'type' => 'text_long', + 'object_types' => array('comment'), ); field_create_field($field); } @@ -254,6 +255,7 @@ function comment_update_7012() { $field = array( 'field_name' => 'comment_body', 'type' => 'text_long', + 'object_types' => array('comment'), ); field_create_field($field); diff --git a/modules/field/field.crud.inc b/modules/field/field.crud.inc index 7b502943f..e8a48008b 100644 --- a/modules/field/field.crud.inc +++ b/modules/field/field.crud.inc @@ -45,6 +45,9 @@ * - type (string) * The type of the field, such as 'text' or 'image'. Field types * are defined by modules that implement hook_field_info(). + * - object_types (array) + * The array of entity types that can hold instances of this field. If + * empty or not specified, the field can have instances in any entity type. * - cardinality (integer) * The number of values the field can hold. Legal values are any * positive integer or FIELD_CARDINALITY_UNLIMITED. @@ -265,6 +268,7 @@ function field_create_field($field) { } $field += array( + 'object_types' => array(), 'cardinality' => 1, 'translatable' => FALSE, 'locked' => FALSE, @@ -396,6 +400,9 @@ function field_update_field($field) { if ($field['type'] != $prior_field['type']) { throw new FieldException("Cannot change an existing field's type."); } + if ($field['object_types'] != $prior_field['object_types']) { + throw new FieldException("Cannot change an existing field's object_types property."); + } if ($field['storage']['type'] != $prior_field['storage']['type']) { throw new FieldException("Cannot change an existing field's storage type."); } @@ -611,6 +618,10 @@ function field_create_instance($instance) { if (empty($instance['bundle'])) { throw new FieldException(t('Attempt to create an instance of field @field_name without a bundle.', array('@field_name' => $instance['field_name']))); } + // Check that the field can be attached to this object type. + if (!empty($field['object_types']) && !in_array($instance['object_type'], $field['object_types'])) { + throw new FieldException(t('Attempt to create an instance of field @field_name on forbidden object type @obj_type.', array('@field_name' => $instance['field_name'], '@obj_type' => $instance['object_type']))); + } // Set the field id. $instance['field_id'] = $field['id']; diff --git a/modules/field/tests/field.test b/modules/field/tests/field.test index 3052af9ad..94c94afd7 100644 --- a/modules/field/tests/field.test +++ b/modules/field/tests/field.test @@ -2297,7 +2297,6 @@ class FieldInstanceCrudTestCase extends FieldTestCase { $this->instance_definition = array( 'field_name' => $this->field['field_name'], 'object_type' => 'test_entity', - 'object_type' => 'test_entity', 'bundle' => 'test_bundle', ); } @@ -2355,6 +2354,39 @@ class FieldInstanceCrudTestCase extends FieldTestCase { $this->pass(t('Cannot create an instance of a non-existing field.')); } + // Create a field restricted to a specific entity type. + $field_restricted = array( + 'field_name' => drupal_strtolower($this->randomName()), + 'type' => 'test_field', + 'object_types' => array('test_cacheable_entity'), + ); + field_create_field($field_restricted); + + // Check that an instance can be added to an object type allowed + // by the field. + try { + $instance = $this->instance_definition; + $instance['field_name'] = $field_restricted['field_name']; + $instance['object_type'] = 'test_cacheable_entity'; + field_create_instance($instance); + $this->pass(t('Can create an instance on a object type allowed by the field.')); + } + catch (FieldException $e) { + $this->fail(t('Can create an instance on a object type allowed by the field.')); + } + + // Check that an instance cannot be added to an object type + // forbidden by the field. + try { + $instance = $this->instance_definition; + $instance['field_name'] = $field_restricted['field_name']; + field_create_instance($instance); + $this->fail(t('Cannot create an instance on a object type forbidden by the field.')); + } + catch (FieldException $e) { + $this->pass(t('Cannot create an instance on a object type forbidden by the field.')); + } + // TODO: test other failures. } diff --git a/modules/field_ui/field_ui.admin.inc b/modules/field_ui/field_ui.admin.inc index eb94ed6c7..4104e04cf 100644 --- a/modules/field_ui/field_ui.admin.inc +++ b/modules/field_ui/field_ui.admin.inc @@ -787,8 +787,13 @@ function field_ui_existing_field_options($obj_type, $bundle) { if (!($existing_bundle == $bundle && $existing_obj_type == $obj_type)) { foreach ($instances as $instance) { $field = field_info_field($instance['field_name']); - // Don't show locked fields or fields already in the current bundle. - if (empty($field['locked']) && !field_info_instance($obj_type, $field['field_name'], $bundle)) { + // Don't show + // - locked fields, + // - fields already in the current bundle, + // - field that cannot be added to the object type. + if (empty($field['locked']) + && !field_info_instance($obj_type, $field['field_name'], $bundle) + && (empty($field['object_types']) || in_array($obj_type, $field['object_types']))) { $text = t('@type: @field (@label)', array( '@type' => $field_types[$field['type']]['label'], '@label' => t($instance['label']), '@field' => $instance['field_name'], diff --git a/modules/field_ui/field_ui.test b/modules/field_ui/field_ui.test index f14ed11c0..e3f030782 100644 --- a/modules/field_ui/field_ui.test +++ b/modules/field_ui/field_ui.test @@ -146,6 +146,11 @@ class FieldUITestCase extends DrupalWebTestCase { $this->drupalGet(('admin/structure/types/manage/page/fields')); $this->assertRaw(t('Add existing field'), t('"Add existing field" was found.')); + // Check that the list of options respects object type restrictions on + // fields. The 'comment' field is restricted to the 'comment' object type + // and should not appear in the list. + $this->assertFalse($this->xpath('//select[@id="edit--add-existing-field-field-name"]//option[@value="comment"]'), t('The list of options respects object type restrictions.')); + // Add a new field based on an existing field. $edit = array( '_add_existing_field[label]' => $this->field_label . '_2', diff --git a/modules/node/node.module b/modules/node/node.module index 58a264749..d54f75e0a 100644 --- a/modules/node/node.module +++ b/modules/node/node.module @@ -576,6 +576,7 @@ function node_configure_fields($type) { $field = array( 'field_name' => 'body', 'type' => 'text_with_summary', + 'object_types' => array('node'), 'translatable' => TRUE, ); $field = field_create_field($field); |