Commit 55651cf3 authored by Dries's avatar Dries

Issue #1981314 by pcambra, aspilicious, andypost, swentel: Drop procedural...

Issue #1981314 by pcambra, aspilicious, andypost, swentel: Drop procedural usage of fields in field module.
parent 81b2685c
......@@ -1587,7 +1587,7 @@ function field_entity_bundle_delete($entity_type, $bundle) {
// entity types or bundles.
$instances = field_read_instances(array('entity_type' => $entity_type, 'bundle' => $bundle), array('include_inactive' => TRUE));
foreach ($instances as $instance) {
field_delete_instance($instance);
$instance->delete();
}
// Clear the cache.
......
......@@ -24,89 +24,6 @@
* the Field API.
*/
/**
* Creates a field.
*
* This function does not bind the field to any bundle; use
* field_create_instance() for that.
*
* @param array $field
* A field definition. The field_name and type properties are required.
* Other properties, if omitted, will be given the following default values:
* - cardinality: 1
* - locked: FALSE
* - indexes: the field-type indexes, specified by the field type's
* hook_field_schema(). The indexes specified in $field are added
* to those default indexes. It is possible to override the
* definition of a field-type index by providing an index with the
* same name, or to remove it by redefining it as an empty array
* of columns. Overriding field-type indexes should be done
* carefully, for it might seriously affect the site's performance.
* - settings: each omitted setting is given the default value defined in
* hook_field_info().
* - storage:
* - type: the storage backend specified in the
* 'field.settings.default_storage' configuration.
* - settings: each omitted setting is given the default value specified in
* hook_field_storage_info().
*
* @return \Drupal\field\Plugin\Core\Entity\Field
* The field entity.
*
* @throws Drupal\field\FieldException
*
* @deprecated as of Drupal 8.0. Use
* entity_create('field_entity', $definition)->save().
*
* See: @link field Field API data structures @endlink.
*/
function field_create_field(array $field) {
$field = entity_create('field_entity', $field);
$field->save();
return $field;
}
/**
* Updates a field.
*
* Any module may forbid any update for any reason. For example, the
* field's storage module might forbid an update if it would change
* the storage schema while data for the field exists. A field type
* module might forbid an update if it would change existing data's
* semantics, or if there are external dependencies on field settings
* that cannot be updated.
*
* @param mixed $field
* Either the \Drupal\field\Plugin\Core\Entity\Field object to update, or a
* field array structure. If the latter, $field['field_name'] must provided;
* it identifies the field that will be updated to match this structure. Any
* other properties of the field that are not specified in $field will be left
* unchanged, so it is not necessary to pass in a fully populated $field
* structure.
*
* @throws Drupal\field\FieldException
*
* @deprecated as of Drupal 8.0. Use $field->save().
*
* @see field_create_field()
*/
function field_update_field($field) {
// Module developers can still pass in an array of properties.
if (is_array($field)) {
$field_loaded = entity_load('field_entity', $field['field_name']);
if (empty($field_loaded)) {
throw new FieldException('Attempt to update a non-existent field.');
}
// Merge incoming values.
foreach ($field as $key => $value) {
$field_loaded[$key] = $value;
}
$field = $field_loaded;
}
$field->save();
}
/**
* Reads a single field record directly from the database.
*
......@@ -161,103 +78,6 @@ function field_read_fields($conditions = array(), $include_additional = array())
return entity_load_multiple_by_properties('field_entity', $conditions);
}
/**
* Marks a field and its instances and data for deletion.
*
* @param $field_name
* The field name to delete.
*
* @deprecated as of Drupal 8.0. Use $field->delete().
*/
function field_delete_field($field_name) {
if ($field = field_info_field($field_name)) {
$field->delete();
}
}
/**
* Creates an instance of a field, binding it to a bundle.
*
* @param array $instance
* A field instance definition array. The field_name, entity_type and
* bundle properties are required. Other properties, if omitted,
* will be given the following default values:
* - label: the field name
* - description: empty string
* - required: FALSE
* - default_value_function: empty string
* - settings: each omitted setting is given the default value specified in
* hook_field_info().
* - widget:
* - type: the default widget specified in hook_field_info().
* - settings: each omitted setting is given the default value specified in
* hook_field_widget_info().
*
* @return \Drupal\field\Plugin\Core\Entity\FieldInstance
* The field instance entity.
*
* @throws Drupal\field\FieldException
*
* @deprecated as of Drupal 8.0. Use
* entity_create('field_instance', $definition)->save().
*
* See: @link field Field API data structures @endlink.
*/
function field_create_instance(array $instance) {
$instance = entity_create('field_instance', $instance);
$instance->save();
return $instance;
}
/**
* Updates an instance of a field.
*
* @param mixed $instance
* Either the \Drupal\field\Plugin\Core\Entity\FieldInstance to update, or an
* associative array representing an instance structure. If the latter, the
* required keys and values are:
* - entity_type: The type of the entity the field is attached to.
* - bundle: The bundle this field belongs to.
* - field_name: The name of an existing field.
* The other array elements represent properties of the instance, and all
* properties must be specified or their default values will be used (except
* internal-use properties, which are assigned automatically). To avoid losing
* the previously stored properties of the instance when making a change,
* first load the instance with field_info_instance(), then override the
* values you want to override, and finally save using this function. Example:
* @code
* // Fetch an instance info array.
* $instance_info = field_info_instance($entity_type, $field_name, $bundle_name);
* // Change a single property in the instance definition.
* $instance_info['definition']['required'] = TRUE;
* // Write the changed definition back.
* field_update_instance($instance_info['definition']);
* @endcode
*
* @throws Drupal\field\FieldException
*
* @deprecated as of Drupal 8.0. Use $instance->save().
*
* @see field_info_instance()
* @see field_create_instance()
*/
function field_update_instance($instance) {
// Module developers can still pass in an array of properties.
if (is_array($instance)) {
$instance_loaded = entity_load('field_instance', $instance['entity_type'] . '.' . $instance['bundle'] . '.' . $instance['field_name']);
if (empty($instance_loaded)) {
throw new FieldException('Attempt to update a non-existent instance.');
}
// Merge incoming values.
foreach ($instance as $key => $value) {
$instance_loaded[$key] = $value;
}
$instance = $instance_loaded;
}
$instance->save();
}
/**
* Reads a single instance record from the database.
*
......@@ -316,22 +136,6 @@ function field_read_instances($conditions = array(), $include_additional = array
return entity_load_multiple_by_properties('field_instance', $conditions);
}
/**
* Marks a field instance and its data for deletion.
*
* @param \Drupal\field\Plugin\Core\Entity\FieldInstance $instance
* The field instance.
* @param $field_cleanup
* If TRUE, the field will be deleted as well if its last instance is being
* deleted. If FALSE, it is the caller's responsibility to handle the case of
* fields left without instances. Defaults to TRUE.
*
* @deprecated as of Drupal 8.0. Use $instance->delete().
*/
function field_delete_instance(FieldInstance $instance, $field_cleanup = TRUE) {
$instance->delete($field_cleanup);
}
/**
* @} End of "defgroup field_crud".
*/
......
......@@ -75,8 +75,7 @@
* field_sql_storage.module, stores field data in the local SQL database.
*
* - @link field_purge Field API bulk data deletion @endlink: Cleans up after
* bulk deletion operations such as field_delete_field() and
* field_delete_instance().
* bulk deletion operations such as deletion of field or field_instance.
*
* - @link field_language Field language API @endlink: Provides native
* multilingual support for the Field API.
......
......@@ -37,7 +37,7 @@ function testActive() {
'type' => 'field_sql_storage',
),
);
field_create_field($field_definition);
entity_create('field_entity', $field_definition)->save();
// Test disabling and enabling:
// - the field type module,
......
......@@ -11,6 +11,48 @@
class DisplayApiTest extends FieldUnitTestBase {
/**
* The field name to use in this test.
*
* @var string
*/
protected $field_name;
/**
* The field label to use in this test.
*
* @var string
*/
protected $label;
/**
* The field cardinality to use in this test.
*
* @var number
*/
protected $cardinality;
/**
* The field display options to use in this test.
*
* @var array
*/
protected $display_options;
/**
* The field display options to use in this test.
*
* @var \Drupal\Core\Entity\EntityInterface
*/
protected $entity;
/**
* An array of random values, in the format expected for field values.
*
* @var array
*/
protected $values;
public static function getInfo() {
return array(
'name' => 'Field Display API tests',
......@@ -27,12 +69,12 @@ function setUp() {
$this->label = $this->randomName();
$this->cardinality = 4;
$this->field = array(
$field = array(
'field_name' => $this->field_name,
'type' => 'test_field',
'cardinality' => $this->cardinality,
);
$this->instance = array(
$instance = array(
'field_name' => $this->field_name,
'entity_type' => 'test_entity',
'bundle' => 'test_bundle',
......@@ -54,14 +96,14 @@ function setUp() {
),
);
field_create_field($this->field);
field_create_instance($this->instance);
entity_create('field_entity', $field)->save();
entity_create('field_instance', $instance)->save();
// Create a display for the default view mode.
entity_get_display($this->instance['entity_type'], $this->instance['bundle'], 'default')
entity_get_display($instance['entity_type'], $instance['bundle'], 'default')
->setComponent($this->field_name, $this->display_options['default'])
->save();
// Create a display for the teaser view mode.
entity_get_display($this->instance['entity_type'], $this->instance['bundle'], 'teaser')
entity_get_display($instance['entity_type'], $instance['bundle'], 'teaser')
->setComponent($this->field_name, $this->display_options['teaser'])
->save();
......
......@@ -19,6 +19,20 @@ class FieldAccessTest extends FieldTestBase {
*/
public static $modules = array('node', 'field_test');
/**
* Node entity to use in this test.
*
* @var \Drupal\node\Plugin\Core\Entity\Node
*/
protected $node;
/**
* Field value to test display on nodes.
*
* @var string
*/
protected $test_view_field_value;
public static function getInfo() {
return array(
'name' => 'Field access tests',
......@@ -34,32 +48,32 @@ function setUp() {
$this->drupalLogin($web_user);
// Create content type.
$this->content_type_info = $this->drupalCreateContentType();
$this->content_type = $this->content_type_info->type;
$content_type_info = $this->drupalCreateContentType();
$content_type = $content_type_info->type;
$this->field = array(
$field = array(
'field_name' => 'test_view_field',
'type' => 'text',
);
field_create_field($this->field);
$this->instance = array(
'field_name' => $this->field['field_name'],
entity_create('field_entity', $field)->save();
$instance = array(
'field_name' => $field['field_name'],
'entity_type' => 'node',
'bundle' => $this->content_type,
'bundle' => $content_type,
);
field_create_instance($this->instance);
entity_create('field_instance', $instance)->save();
// Assign display properties for the 'default' and 'teaser' view modes.
foreach (array('default', 'teaser') as $view_mode) {
entity_get_display('node', $this->content_type, $view_mode)
->setComponent($this->field['field_name'])
entity_get_display('node', $content_type, $view_mode)
->setComponent($field['field_name'])
->save();
}
// Create test node.
$this->test_view_field_value = 'This is some text';
$settings = array();
$settings['type'] = $this->content_type;
$settings['type'] = $content_type;
$settings['title'] = 'Field view access test';
$settings['test_view_field'] = array(array('value' => $this->test_view_field_value));
$this->node = $this->drupalCreateNode($settings);
......
......@@ -14,6 +14,21 @@
* Unit test class for non-storage related field_attach_* functions.
*/
class FieldAttachOtherTest extends FieldUnitTestBase {
/**
* Field name to use in the test.
*
* @var string
*/
protected $field_name;
/**
* Field name to use in the test.
*
* @var string
*/
protected $field_name_2;
public static function getInfo() {
return array(
'name' => 'Field attach tests (other)',
......@@ -192,9 +207,10 @@ function testFieldAttachPrepareViewMultiple() {
// hook_field_formatter_prepare_view().
field_test_create_bundle('test_bundle_2');
$formatter_setting = $this->randomName();
$this->instance2 = $this->instance;
$this->instance2['bundle'] = 'test_bundle_2';
field_create_instance($this->instance2);
$instance_definition = $this->instance_definition;
$instance_definition['bundle'] = 'test_bundle_2';
$this->instance2 = entity_create('field_instance', $instance_definition);
$this->instance2->save();
$display_2 = entity_get_display('test_entity', 'test_bundle_2', 'full')
->setComponent($this->field['field_name'], array(
......@@ -268,9 +284,9 @@ function testFieldAttachCache() {
'fttype' => $this->instance['bundle'],
));
$cid = "field:$entity_type:{$entity_init->ftid}";
$instance = $this->instance;
$instance['entity_type'] = $entity_type;
field_create_instance($instance);
$instance_definition = $this->instance_definition;
$instance_definition['entity_type'] = $entity_type;
entity_create('field_instance', $instance_definition)->save();
// Check that no initial cache entry is present.
$this->assertFalse(cache('field')->get($cid), 'Cached: no initial cache entry');
......@@ -553,4 +569,5 @@ function testFieldAttachExtractFormValues() {
$this->assertFalse(isset($entity->{$this->field_name}), 'The first field does not exist in the entity object');
$this->assertIdentical($entity->{$this->field_name_2}[$langcode], $expected_values_2, 'Submit filters empty values');
}
}
......@@ -16,6 +16,21 @@
* all hook_field_attach_pre_{load,insert,update}() hooks.
*/
class FieldAttachStorageTest extends FieldUnitTestBase {
/**
* The field instance.
*
* @var \Drupal\field\Plugin\Core\Entity\FieldInstance
*/
protected $instance;
/**
* Field name to use in the test.
*
* @var string
*/
protected $field_name;
public static function getInfo() {
return array(
'name' => 'Field attach tests (storage-related)',
......@@ -39,7 +54,7 @@ function testFieldAttachSaveLoad() {
// Configure the instance so that we test hook_field_load() (see
// field_test_field_load() in field_test.module).
$this->instance['settings']['test_hook_field_load'] = TRUE;
field_update_instance($this->instance);
$this->instance->save();
$langcode = Language::LANGCODE_NOT_SPECIFIED;
$entity_type = 'test_entity';
......@@ -117,11 +132,11 @@ function testFieldAttachLoadMultiple() {
);
for ($i = 1; $i <= 3; $i++) {
$field_names[$i] = 'field_' . $i;
$field = array('field_name' => $field_names[$i], 'type' => 'test_field');
$field = field_create_field($field);
$field = entity_create('field_entity', array('field_name' => $field_names[$i], 'type' => 'test_field'));
$field->save();
$field_ids[$i] = $field['uuid'];
foreach ($field_bundles_map[$i] as $bundle) {
$instance = array(
entity_create('field_instance', array(
'field_name' => $field_names[$i],
'entity_type' => 'test_entity',
'bundle' => $bundles[$bundle],
......@@ -130,8 +145,7 @@ function testFieldAttachLoadMultiple() {
// (see field_test_field_load() in field_test.module).
'test_hook_field_load' => TRUE,
),
);
field_create_instance($instance);
))->save();
}
}
......@@ -191,13 +205,13 @@ function testFieldAttachSaveLoadDifferentStorage() {
),
);
foreach ($fields as $field) {
field_create_field($field);
entity_create('field_entity', $field)->save();
$instance = array(
'field_name' => $field['field_name'],
'entity_type' => 'test_entity',
'bundle' => 'test_bundle',
);
field_create_instance($instance);
entity_create('field_instance', $instance)->save();
}
$entity_init = field_test_create_entity();
......@@ -226,22 +240,19 @@ function testFieldAttachSaveLoadDifferentStorage() {
*/
function testFieldStorageDetailsAlter() {
$field_name = 'field_test_change_my_details';
$field = array(
$field = entity_create('field_entity', array(
'field_name' => $field_name,
'type' => 'test_field',
'cardinality' => 4,
'storage' => array('type' => 'field_test_storage'),
);
$field = field_create_field($field);
$instance = array(
));
$field->save();
$instance = entity_create('field_instance', array(
'field_name' => $field_name,
'entity_type' => 'test_entity',
'bundle' => 'test_bundle',
);
field_create_instance($instance);
$field = field_info_field($instance['field_name']);
$instance = field_info_instance($instance['entity_type'], $instance['field_name'], $instance['bundle']);
));
$instance->save();
// The storage details are indexed by a storage engine type.
$this->assertTrue(array_key_exists('drupal_variables', $field['storage_details']), 'The storage type is Drupal variables.');
......@@ -345,7 +356,7 @@ function testFieldAttachSaveMissingData() {
function testFieldAttachSaveMissingDataDefaultValue() {
// Add a default value function.
$this->instance['default_value_function'] = 'field_test_default_value';
field_update_instance($this->instance);
$this->instance->save();
// Verify that fields are populated with default values.
$entity_type = 'test_entity';
......@@ -444,8 +455,8 @@ function testEntityCreateRenameBundle() {
field_test_create_bundle($new_bundle);
// Add an instance to that bundle.
$this->instance['bundle'] = $new_bundle;
field_create_instance($this->instance);
$this->instance_definition['bundle'] = $new_bundle;
entity_create('field_instance', $this->instance_definition)->save();
// Save an entity with data in the field.
$entity = field_test_create_entity(0, 0, $this->instance['bundle']);
......@@ -483,13 +494,13 @@ function testEntityDeleteBundle() {
field_test_create_bundle($new_bundle);
// Add an instance to that bundle.
$this->instance['bundle'] = $new_bundle;
field_create_instance($this->instance);
$this->instance_definition['bundle'] = $new_bundle;
entity_create('field_instance', $this->instance_definition)->save();
// Create a second field for the test bundle
$field_name = drupal_strtolower($this->randomName() . '_field_name');
$field = array('field_name' => $field_name, 'type' => 'test_field', 'cardinality' => 1);
field_create_field($field);
entity_create('field_entity', $field)->save();
$instance = array(
'field_name' => $field_name,
'entity_type' => 'test_entity',
......@@ -498,7 +509,7 @@ function testEntityDeleteBundle() {
'description' => $this->randomName() . '_description',
'weight' => mt_rand(0, 127),
);
field_create_instance($instance);
entity_create('field_instance', $instance)->save();
// Save an entity with data for both fields
$entity = field_test_create_entity(0, 0, $this->instance['bundle']);
......@@ -527,4 +538,5 @@ function testEntityDeleteBundle() {
$this->assertFalse(field_read_instance('test_entity', $this->field_name, $this->instance['bundle']), "First field is deleted");
$this->assertFalse(field_read_instance('test_entity', $field_name, $instance['bundle']), "Second field is deleted");
}
}
......@@ -2,7 +2,7 @@
/**
* @file
* Definition of Drupal\field\Tests\FieldInfoTest.
* Contains \Drupal\field\Tests\FieldInfoTest.
*/
namespace Drupal\field\Tests;
......@@ -54,11 +54,11 @@ function testFieldInfo() {
// Create a field, verify it shows up.
$core_fields = field_info_fields();
$field = array(
$field = entity_create('field_entity', array(
'field_name' => drupal_strtolower($this->randomName()),
'type' => 'test_field',
);
field_create_field($field);
));
$field->save();
$fields = field_info_fields();
$this->assertEqual(count($fields), count($core_fields) + 1, 'One new field exists');
$this->assertEqual($fields[$field['field_name']]['field_name'], $field['field_name'], 'info fields contains field name');
......@@ -72,7 +72,7 @@ function testFieldInfo() {
$this->assertEqual($fields[$field['field_name']]['active'], TRUE, 'info fields contains active 1');
// Create an instance, verify that it shows up
$instance = array(
$instance_definition = array(
'field_name' => $field['field_name'],
'entity_type' => 'test_entity',
'bundle' => 'test_bundle',
......@@ -80,14 +80,15 @@ function testFieldInfo() {
'description' => $this->randomName(),
'weight' => mt_rand(0, 127),
);
field_create_instance($instance);
$instance = entity_create('field_instance', $instance_definition);
$instance->save();
$info = entity_get_info('test_entity');
$instances = field_info_instances('test_entity', $instance['bundle']);
$this->assertEqual(count($instances), 1, format_string('One instance shows up in info when attached to a bundle on a @label.', array(
'@label' => $info['label']
)));
$this->assertTrue($instance < $instances[$instance['field_name']], 'Instance appears in info correctly');
$this->assertTrue($instance_definition < $instances[$instance['field_name']], 'Instance appears in info correctly');
// Test a valid entity type but an invalid bundle.
$instances = field_info_instances('test_entity', 'invalid_bundle');
......@@ -127,7 +128,8 @@ function testFieldPrepare() {
'field_name' => 'field',
'type' => 'test_field',
);
$field = field_create_field($field_definition);
$field = entity_create('field_entity', $field_definition);
$field->save();
// Simulate a stored field definition missing a field setting (e.g. a
// third-party module adding a new field setting has been enabled, and
......@@ -153,13 +155,14 @@ function testInstancePrepare() {
'field_name' => 'field',
'type' => 'test_field',
);
field_create_field($field_definition);
entity_create('field_entity', $field_definition)->save();
$instance_definition = array(
'field_name' => $field_definition['field_name'],
'entity_type' => 'test_entity',
'bundle' => 'test_bundle',
);
$instance = field_create_instance($instance_definition);
$instance = entity_create('field_instance', $instance_definition);
$instance->save();
// Simulate a stored instance definition missing various settings (e.g. a
// third-party module adding instance or widget settings has been enabled,
......@@ -189,13 +192,13 @@ function testInstanceDisabledEntityType() {
'field_name' => 'field',
'type' => 'test_field',
);
field_create_field($field_definition);
entity_create('field_entity', $field_definition)->save();
$instance_definition = array(
'field_name' => 'field',
'entity_type' => 'comment',
'bundle' => 'comment_node_article',
);
field_create_instance($instance_definition);
entity_create('field_instance', $instance_definition)->save();
// Disable coment module. This clears field_info cache.
module_disable(array('comment'));
......@@ -224,7 +227,7 @@ function testFieldMap() {
),
);
foreach ($fields as $field) {
field_create_field($field);
entity_create('field_entity', $field)->save();
}
// Create a couple instances.
......@@ -251,7 +254,7 @@ function testFieldMap() {
),
);
foreach ($instances as $instance) {
field_create_instance($instance);
entity_create('field_instance', $instance)->save();
}
$expected = array(
......@@ -308,11 +311,11 @@ function testFieldInfoCache() {