Commit e5f48f0f authored by webchick's avatar webchick
Browse files

#680910 by yched and bjaspan: Allow fields to be restricted to entity types.

parent 02c1eeee
......@@ -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);
......
......@@ -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'];
......
......@@ -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.
}
......
......@@ -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'],
......
......@@ -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',
......
......@@ -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);
......
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