diff --git a/core/includes/module.inc b/core/includes/module.inc index 215d165..c202b8e 100644 --- a/core/includes/module.inc +++ b/core/includes/module.inc @@ -498,6 +498,7 @@ function module_enable($module_list, $enable_dependencies = TRUE) { } // Allow modules to react prior to the enabling of a module. + entity_info_cache_clear(); module_invoke_all('modules_preenable', array($module)); // Enable the module. diff --git a/core/modules/field/field.api.php b/core/modules/field/field.api.php index a1c93de..c70a2ea 100644 --- a/core/modules/field/field.api.php +++ b/core/modules/field/field.api.php @@ -1593,11 +1593,10 @@ function hook_field_storage_details_alter(&$details, $field) { * fields. If unset or FALSE, only non-deleted fields should be loaded. */ function hook_field_storage_load($entity_type, $entities, $age, $fields, $options) { - $field_info = field_info_field_by_ids(); $load_current = $age == FIELD_LOAD_CURRENT; foreach ($fields as $field_id => $ids) { - $field = $field_info[$field_id]; + $field = field_info_field_by_id($field_id); $field_name = $field['field_name']; $table = $load_current ? _field_sql_storage_tablename($field) : _field_sql_storage_revision_tablename($field); @@ -1742,6 +1741,11 @@ function hook_field_storage_write($entity_type, $entity, $op, $fields) { * This hook is invoked from field_attach_delete() to ask the field storage * module to delete field data. * + * By the time this hook runs, the relevant field definitions have been + * populated and cached in FieldInfo, so calling field_info_field_by_id() on + * each field individually is more efficient than loading all fields in memory + * upfront with field_info_field_by_ids() (which is uncached). + * * @param $entity_type * The entity type of entity, such as 'node' or 'user'. * @param $entity diff --git a/core/modules/field/field.attach.inc b/core/modules/field/field.attach.inc index 2579126..c928f50 100644 --- a/core/modules/field/field.attach.inc +++ b/core/modules/field/field.attach.inc @@ -7,6 +7,7 @@ use Drupal\field\FieldValidationException; use Drupal\Core\Entity\EntityInterface; +use Drupal\field\FieldInstance; /** * @defgroup field_storage Field Storage API @@ -349,7 +350,6 @@ function _field_invoke_multiple($op, $entity_type, $entities, &$a = NULL, &$b = 'langcode' => NULL, ); $options += $default_options; - $field_info = field_info_field_by_ids(); $fields = array(); $grouped_instances = array(); @@ -373,7 +373,7 @@ function _field_invoke_multiple($op, $entity_type, $entities, &$a = NULL, &$b = foreach ($instances as $instance) { $field_id = $instance['field_id']; $field_name = $instance['field_name']; - $field = $field_info[$field_id]; + $field = field_info_field_by_id($field_id); $function = $options['default'] ? 'field_default_' . $op : $field['module'] . '_field_' . $op; if (function_exists($function)) { // Add the field to the list of fields to invoke the hook on. @@ -573,6 +573,7 @@ function _field_invoke_get_instances($entity_type, $bundle, $options) { */ function _field_invoke_widget_target() { return function ($instance) { + $instance = new FieldInstance($instance); return $instance->getWidget(); }; } @@ -736,7 +737,6 @@ function field_attach_form($entity_type, EntityInterface $entity, &$form, &$form * operated on. */ function field_attach_load($entity_type, $entities, $age = FIELD_LOAD_CURRENT, $options = array()) { - $field_info = field_info_field_by_ids(); $load_current = $age == FIELD_LOAD_CURRENT; // Merge default options. @@ -814,7 +814,7 @@ function field_attach_load($entity_type, $entities, $age = FIELD_LOAD_CURRENT, $ } // Collect the storage backend if the field has not been loaded yet. if (!isset($skip_fields[$field_id])) { - $field = $field_info[$field_id]; + $field = field_info_field_by_id($field_id); $storages[$field['storage']['type']][$field_id][] = $load_current ? $id : $vid; } } diff --git a/core/modules/field/field.crud.inc b/core/modules/field/field.crud.inc index 2b28a56..ba2f09e 100644 --- a/core/modules/field/field.crud.inc +++ b/core/modules/field/field.crud.inc @@ -322,7 +322,11 @@ function field_read_field($field_name, $include_additional = array()) { * Reads in fields that match an array of conditions. * * @param array $params - * An array of conditions to match against. + * An array of conditions to match against. Keys are columns from the + * 'field_config' table, values are conditions to match. Additionally, + * conditions on the 'entity_type' and 'bundle' columns from the + * 'field_config_instance' table are supported (select fields having an + * instance on a given bundle). * @param array $include_additional * The default behavior of this function is to not return fields that are * inactive or have been deleted. Setting @@ -340,8 +344,18 @@ function field_read_fields($params = array(), $include_additional = array()) { // Turn the conditions into a query. foreach ($params as $key => $value) { + // Allow filtering on the 'entity_type' and 'bundle' columns of the + // field_config_instance table. + if ($key == 'entity_type' || $key == 'bundle') { + if (empty($fci_join)) { + $fci_join = $query->join('field_config_instance', 'fci', 'fc.id = fci.field_id'); + } + $key = 'fci.' . $key; + } + $query->condition($key, $value); } + if (!isset($include_additional['include_inactive']) || !$include_additional['include_inactive']) { $query ->condition('fc.active', 1) diff --git a/core/modules/field/field.info.inc b/core/modules/field/field.info.inc index 50b270f..0658750 100644 --- a/core/modules/field/field.info.inc +++ b/core/modules/field/field.info.inc @@ -5,7 +5,29 @@ * Field Info API, providing information about available fields and field types. */ -use Drupal\field\FieldInstance; +use Drupal\field\FieldInfo; + +/** + * Retrieves the Drupal\field\FieldInfo object for the current request. + * + * @return Drupal\field\FieldInfo + * An instance of the Drupal\field\FieldInfo class. + */ +function _field_info_field_cache() { + // Use the advanced drupal_static() pattern, since this is called very often. + static $drupal_static_fast; + + if (!isset($drupal_static_fast)) { + $drupal_static_fast['field_info_field_cache'] = &drupal_static(__FUNCTION__); + } + $info = &$drupal_static_fast['field_info_field_cache']; + + if (!isset($info)) { + $info = new FieldInfo(); + } + + return $info; +} /** * @defgroup field_info Field Info API @@ -35,7 +57,7 @@ function field_info_cache_clear() { entity_info_cache_clear(); _field_info_collate_types_reset(); - _field_info_collate_fields_reset(); + _field_info_field_cache()->flush(); } /** @@ -153,265 +175,6 @@ function _field_info_collate_types_reset() { } /** - * Collates all information on existing fields and instances. - * - * @return - * An associative array containing: - * - fields: Array of existing fields, keyed by field ID. This element lists - * deleted and non-deleted fields, but not inactive ones. Each field has an - * additional element, 'bundles', which is an array of all non-deleted - * instances of that field. - * - field_ids: Array of field IDs, keyed by field name. This element only - * lists non-deleted, active fields. - * - instances: Array of existing instances, keyed by entity type, bundle name - * and field name. This element only lists non-deleted instances whose field - * is active. - * - * @see _field_info_collate_fields_reset() - */ -function _field_info_collate_fields() { - // Use the advanced drupal_static() pattern, since this is called very often. - static $drupal_static_fast; - - if (!isset($drupal_static_fast)) { - $drupal_static_fast['field_info_collate_fields'] = &drupal_static(__FUNCTION__); - } - $info = &$drupal_static_fast['field_info_collate_fields']; - - if (!isset($info)) { - if ($cached = cache('field')->get('field_info_fields')) { - $info = $cached->data; - } - else { - $definitions = array( - 'field_ids' => field_read_fields(array(), array('include_deleted' => 1)), - 'instances' => field_read_instances(), - ); - - // Populate 'fields' with all fields, keyed by ID. - $info['fields'] = array(); - foreach ($definitions['field_ids'] as $key => $field) { - $info['fields'][$key] = $definitions['field_ids'][$key] = _field_info_prepare_field($field); - } - - // Build an array of field IDs for non-deleted fields, keyed by name. - $info['field_ids'] = array(); - foreach ($info['fields'] as $key => $field) { - if (!$field['deleted']) { - $info['field_ids'][$field['field_name']] = $key; - } - } - - // Populate 'instances'. Only non-deleted instances are considered. - $info['instances'] = array(); - foreach (field_info_bundles() as $entity_type => $bundles) { - foreach ($bundles as $bundle => $bundle_info) { - $info['instances'][$entity_type][$bundle] = array(); - } - } - foreach ($definitions['instances'] as $instance) { - $field = $info['fields'][$instance['field_id']]; - $instance = _field_info_prepare_instance($instance, $field); - $info['instances'][$instance['entity_type']][$instance['bundle']][$instance['field_name']] = new FieldInstance($instance); - // Enrich field definitions with the list of bundles where they have - // instances. NOTE: Deleted fields in $info['field_ids'] are not - // enriched because all of their instances are deleted, too, and - // are thus not in $definitions['instances']. - $info['fields'][$instance['field_id']]['bundles'][$instance['entity_type']][] = $instance['bundle']; - } - - // Populate 'extra_fields'. - $extra = module_invoke_all('field_extra_fields'); - drupal_alter('field_extra_fields', $extra); - // Merge in saved settings. - foreach ($extra as $entity_type => $bundles) { - foreach ($bundles as $bundle => $extra_fields) { - $extra_fields = _field_info_prepare_extra_fields($extra_fields, $entity_type, $bundle); - $info['extra_fields'][$entity_type][$bundle] = $extra_fields; - } - } - - cache('field')->set('field_info_fields', $info); - } - } - - return $info; -} - -/** - * Clears collated information on existing fields and instances. - */ -function _field_info_collate_fields_reset() { - drupal_static_reset('_field_info_collate_fields'); - cache('field')->delete('field_info_fields'); -} - -/** - * Prepares a field definition for the current run-time context. - * - * Since the field was last saved or updated, new field settings can be - * expected. - * - * @param $field - * The raw field structure as read from the database. - * - * @return - * The field array with storage and settings data added. - */ -function _field_info_prepare_field($field) { - // Make sure all expected field settings are present. - $field['settings'] += field_info_field_settings($field['type']); - $field['storage']['settings'] += field_info_storage_settings($field['storage']['type']); - - // Add storage details. - $details = (array) module_invoke($field['storage']['module'], 'field_storage_details', $field); - drupal_alter('field_storage_details', $details, $field, $instance); - $field['storage']['details'] = $details; - - // Initialize the 'bundles' list. - $field['bundles'] = array(); - - return $field; -} - -/** - * Prepares an instance definition for the current run-time context. - * - * Since the instance was last saved or updated, a number of things might have - * changed: widgets or formatters disabled, new settings expected, new view - * modes added, etc. - * - * @param $instance - * The raw instance structure as read from the database. - * @param $field - * The field structure for the instance. - * - * @return - * Field instance array. - */ -function _field_info_prepare_instance($instance, $field) { - // Make sure all expected instance settings are present. - $instance['settings'] += field_info_instance_settings($field['type']); - - // Set a default value for the instance. - if (field_behaviors_widget('default value', $instance) == FIELD_BEHAVIOR_DEFAULT && !isset($instance['default_value'])) { - $instance['default_value'] = NULL; - } - - foreach ($instance['display'] as $view_mode => $display) { - $instance['display'][$view_mode] = _field_info_prepare_instance_display($field, $display); - } - - // Fallback to 'hidden' for view modes configured to use custom display - // settings, and for which the instance has no explicit settings. - $entity_info = entity_get_info($instance['entity_type']); - $view_modes = array_merge(array('default'), array_keys($entity_info['view modes'])); - $view_mode_settings = field_view_mode_settings($instance['entity_type'], $instance['bundle']); - foreach ($view_modes as $view_mode) { - if ($view_mode == 'default' || !empty($view_mode_settings[$view_mode]['custom_settings'])) { - if (!isset($instance['display'][$view_mode])) { - $instance['display'][$view_mode] = array( - 'type' => 'hidden', - 'label' => 'above', - 'settings' => array(), - 'weight' => 0, - ); - } - } - } - - return $instance; -} - -/** - * Adapts display specifications to the current run-time context. - * - * @param $field - * The field structure for the instance. - * @param $display - * Display specifications as found in $instance['display']['some_view_mode']. - * - * @return - * The modified $display array. - */ -function _field_info_prepare_instance_display($field, $display) { - $field_type = field_info_field_types($field['type']); - - // Fill in default values. - $display += array( - 'label' => 'above', - 'type' => $field_type['default_formatter'], - 'settings' => array(), - 'weight' => 0, - ); - if ($display['type'] != 'hidden') { - $formatter_type = field_info_formatter_types($display['type']); - // Fallback to default formatter if formatter type is not available. - if (!$formatter_type) { - $display['type'] = $field_type['default_formatter']; - $formatter_type = field_info_formatter_types($display['type']); - } - $display['module'] = $formatter_type['module']; - // Fill in default settings for the formatter. - $display['settings'] += field_info_formatter_settings($display['type']); - } - - return $display; -} - -/** - * Prepares 'extra fields' for the current run-time context. - * - * @param $extra_fields - * The array of extra fields, as collected in hook_field_extra_fields(). - * @param $entity_type - * The entity type. - * @param $bundle - * The bundle name. - * - * @return - * An array of data about extra fields. - */ -function _field_info_prepare_extra_fields($extra_fields, $entity_type, $bundle) { - $entity_type_info = entity_get_info($entity_type); - $bundle_settings = field_bundle_settings($entity_type, $bundle); - $extra_fields += array('form' => array(), 'display' => array()); - - $result = array(); - // Extra fields in forms. - foreach ($extra_fields['form'] as $name => $field_data) { - $settings = isset($bundle_settings['extra_fields']['form'][$name]) ? $bundle_settings['extra_fields']['form'][$name] : array(); - if (isset($settings['weight'])) { - $field_data['weight'] = $settings['weight']; - } - $result['form'][$name] = $field_data; - } - - // Extra fields in displayed entities. - $data = $extra_fields['display']; - foreach ($extra_fields['display'] as $name => $field_data) { - $settings = isset($bundle_settings['extra_fields']['display'][$name]) ? $bundle_settings['extra_fields']['display'][$name] : array(); - $field_data['visible'] = isset($field_data['visible']) ? $field_data['visible'] : TRUE; - $view_modes = array_merge(array('default'), array_keys($entity_type_info['view modes'])); - foreach ($view_modes as $view_mode) { - if (isset($settings[$view_mode])) { - $field_data['display'][$view_mode] = $settings[$view_mode]; - } - else { - $field_data['display'][$view_mode] = array( - 'weight' => $field_data['weight'], - 'visible' => $field_data['visible'], - ); - } - } - unset($field_data['weight']); - $result['display'][$name] = $field_data; - } - - return $result; -} - -/** * Determines the behavior of a widget with respect to an operation. * * @param $op @@ -550,6 +313,22 @@ function field_info_bundles($entity_type = NULL) { } /** + * Returns a lightweight map of fields across bundles. + * + * The function only returns active, non deleted fields. + * + * @return + * An array keyed by field name. Each value is an array with two entries: + * - type: The field type. + * - bundles: The bundles in which the field appears, as an array with entity + * types as keys and the array of bundle names as values. + */ +function field_info_field_map() { + $cache = _field_info_field_cache(); + return $cache->getFieldMap(); +} + +/** * Returns all field definitions. * * @return @@ -558,9 +337,11 @@ function field_info_bundles($entity_type = NULL) { * which this field belongs, keyed by entity type. */ function field_info_fields() { + $cache = _field_info_field_cache(); + $info = $cache->getFields(); + $fields = array(); - $info = _field_info_collate_fields(); - foreach ($info['fields'] as $key => $field) { + foreach ($info as $key => $field) { if (!$field['deleted']) { $fields[$field['field_name']] = $field; } @@ -586,10 +367,8 @@ function field_info_fields() { * @see field_info_field_by_id() */ function field_info_field($field_name) { - $info = _field_info_collate_fields(); - if (isset($info['field_ids'][$field_name])) { - return $info['fields'][$info['field_ids'][$field_name]]; - } + $cache = _field_info_field_cache(); + return $cache->getField($field_name); } /** @@ -607,17 +386,19 @@ function field_info_field($field_name) { * @see field_info_field() */ function field_info_field_by_id($field_id) { - $info = _field_info_collate_fields(); - if (isset($info['fields'][$field_id])) { - return $info['fields'][$field_id]; - } + $cache = _field_info_field_cache(); + return $cache->getFieldById($field_id); } /** * Returns the same data as field_info_field_by_id() for every field. * - * This function is typically used when handling all fields of some entities - * to avoid thousands of calls to field_info_field_by_id(). + * Use of this function should be avoided when possible, since it loads and + * statically caches a potentially large array of information. + * + * When iterating over the fields present in a given bundle after a call to + * field_info_instances($entity_type, $bundle), it is recommended to use + * field_info_field() on each individual field instead. * * @return * An array, each key is a field ID and the values are field arrays as @@ -635,6 +416,21 @@ function field_info_field_by_ids() { /** * Retrieves information about field instances. * + * Use of this function to retrieve instances across separate bundles (i.e. + * when the $bundle parameter is NULL) should be avoided when possible, since + * it loads and statically caches a potentially large array of information. + * Use field_info_field_map() instead. + * + * When retrieving the instances of a specific bundle (i.e. when both + * $entity_type and $bundle_name are provided, the function also populates a + * static cache with the corresponding field definitions, allowing fast + * retrieval of field_info_field() later in the request. + * + * @param $entity_type + * (optional) The entity type for which to return instances. + * @param $bundle_name + * (optional) The bundle name for which to return instances. If $entity_type + * is NULL, the $bundle_name parameter is ignored. * * @param $entity_type * The entity type for which to return instances. * @param $bundle_name @@ -645,24 +441,29 @@ function field_info_field_by_ids() { * bundle name. If $entity_type is set, return all instances for that entity * type, keyed by bundle name. If $entity_type and $bundle_name are set, * return all instances for that bundle. + * + * @see field_info_field_map() */ function field_info_instances($entity_type = NULL, $bundle_name = NULL) { - $info = _field_info_collate_fields(); + $cache = _field_info_field_cache(); - if (isset($entity_type) && isset($bundle_name)) { - return isset($info['instances'][$entity_type][$bundle_name]) ? $info['instances'][$entity_type][$bundle_name] : array(); + if (!isset($entity_type)) { + return $cache->getInstances(); } - elseif (isset($entity_type)) { - return isset($info['instances'][$entity_type]) ? $info['instances'][$entity_type] : array(); - } - else { - return $info['instances']; + if (!isset($bundle_name)) { + return $cache->getInstances($entity_type); } + + return $cache->getBundleInstances($entity_type, $bundle_name); } /** * Returns an array of instance data for a specific field and bundle. * + * The function populates a static cache with all fields and instances used in + * the bundle, allowing fast retrieval of field_info_field() or + * field_info_instance() later in the request. + * * @param $entity_type * The entity type for the instance. * @param $field_name @@ -675,9 +476,10 @@ function field_info_instances($entity_type = NULL, $bundle_name = NULL) { * NULL if the instance does not exist. */ function field_info_instance($entity_type, $field_name, $bundle_name) { - $info = _field_info_collate_fields(); - if (isset($info['instances'][$entity_type][$bundle_name][$field_name])) { - return $info['instances'][$entity_type][$bundle_name][$field_name]; + $cache = _field_info_field_cache(); + $info = $cache->getBundleInstances($entity_type, $bundle_name); + if (isset($info[$field_name])) { + return $info[$field_name]; } } @@ -735,11 +537,10 @@ function field_info_instance($entity_type, $field_name, $bundle_name) { * The array of pseudo-field elements in the bundle. */ function field_info_extra_fields($entity_type, $bundle, $context) { - $info = _field_info_collate_fields(); - if (isset($info['extra_fields'][$entity_type][$bundle][$context])) { - return $info['extra_fields'][$entity_type][$bundle][$context]; - } - return array(); + $cache = _field_info_field_cache(); + $info = $cache->getBundleExtraFields($entity_type, $bundle); + + return isset($info[$context]) ? $info[$context] : array(); } /** diff --git a/core/modules/field/field.module b/core/modules/field/field.module index e13f386..283833d 100644 --- a/core/modules/field/field.module +++ b/core/modules/field/field.module @@ -942,7 +942,8 @@ function field_view_field($entity_type, $entity, $field_name, $display = array() if ($field = field_info_field($field_name)) { if (is_array($display)) { // When using custom display settings, fill in default values. - $display = _field_info_prepare_instance_display($field, $display); + $cache = _field_info_field_cache(); + $display = $cache->prepareInstanceDisplay($display, $field["type"]); } // Hook invocations are done through the _field_invoke() functions in diff --git a/core/modules/field/lib/Drupal/field/FieldInfo.php b/core/modules/field/lib/Drupal/field/FieldInfo.php new file mode 100644 index 0000000..3b355d8 --- /dev/null +++ b/core/modules/field/lib/Drupal/field/FieldInfo.php @@ -0,0 +1,665 @@ +fieldMap = NULL; + + $this->fieldsById = array(); + $this->fieldIdsByName = array(); + $this->loadedAllFields = FALSE; + $this->unknownFields = array(); + + $this->bundleInstances = array(); + $this->loadedAllInstances = FALSE; + $this->emptyBundles = array(); + + $this->bundleExtraFields = array(); + + cache('field')->deletePrefix('field_info:'); + } + + /** + * Collects a lightweight map of fields across bundles. + * + * @return + * An array keyed by field name. Each value is an array with two entries: + * - type: The field type. + * - bundles: The bundles in which the field appears, as an array with + * entity types as keys and the array of bundle names as values. + */ + public function getFieldMap() { + // Read from the "static" cache. + if ($this->fieldMap !== NULL) { + return $this->fieldMap; + } + + // Read from persistent cache. + if ($cached = cache('field')->get('field_info:field_map')) { + $map = $cached->data; + + // Save in "static" cache. + $this->fieldMap = $map; + + return $map; + } + + $map = array(); + + $query = db_select('field_config_instance', 'fci'); + $query->join('field_config', 'fc', 'fc.id = fci.field_id'); + $query->fields('fc', array('type')); + $query->fields('fci', array('field_name', 'entity_type', 'bundle')) + ->condition('fc.active', 1) + ->condition('fc.storage_active', 1) + ->condition('fc.deleted', 0) + ->condition('fci.deleted', 0); + foreach ($query->execute() as $row) { + $map[$row->field_name]['bundles'][$row->entity_type][] = $row->bundle; + $map[$row->field_name]['type'] = $row->type; + } + + // Save in "static" and persistent caches. + $this->fieldMap = $map; + cache('field')->set('field_info:field_map', $map); + + return $map; + } + + /** + * Returns all active fields, including deleted ones. + * + * @return + * An array of field definitions, keyed by field ID. + */ + public function getFields() { + // Read from the "static" cache. + if ($this->loadedAllFields) { + return $this->fieldsById; + } + + // Read from persistent cache. + if ($cached = cache('field')->get('field_info:fields')) { + $this->fieldsById = $cached->data; + } + else { + // Collect and prepare fields. + foreach (field_read_fields(array(), array('include_deleted' => TRUE)) as $field) { + $this->fieldsById[$field['id']] = $this->prepareField($field); + } + + // Store in persistent cache. + cache('field')->set('field_info:fields', $this->fieldsById); + } + + // Fill the name/ID map. + foreach ($this->fieldsById as $field) { + if (!$field['deleted']) { + $this->fieldIdsByName[$field['field_name']] = $field['id']; + } + } + + $this->loadedAllFields = TRUE; + + return $this->fieldsById; + } + + /** + * Retrieves all active, non-deleted instances definitions. + * + * This method does not read from nor populate the "static" and persistent + * caches. + * + * @param $entity_type + * (optional) The entity type. + * + * @return + * If $entity_type is not set, all instances keyed by entity type and bundle + * name. If $entity_type is set, all instances for that entity type, keyed + * by bundle name. + */ + public function getInstances($entity_type = NULL) { + // If the full list is not present in "static" cache yet. + if (!$this->loadedAllInstances) { + + // Read from persistent cache. + if ($cached = cache('field')->get('field_info:instances')) { + $this->bundleInstances = $cached->data; + } + else { + // Collect and prepare instances. + + // We also need to populate the static field cache, since it will not + // be set by subsequent getBundleInstances() calls. + $this->getFields(); + + foreach (field_read_instances() as $instance) { + $field = $this->getField($instance['field_name']); + $instance = $this->prepareInstance($instance, $field['type']); + $this->bundleInstances[$instance['entity_type']][$instance['bundle']][$instance['field_name']] = $instance; + } + + // Store in persistent cache. + cache('field')->set('field_info:instances', $this->bundleInstances); + } + + $this->loadedAllInstances = TRUE; + } + + if (isset($entity_type)) { + return isset($this->bundleInstances[$entity_type]) ? $this->bundleInstances[$entity_type] : array(); + } + else { + return $this->bundleInstances; + } + } + + /** + * Returns a field definition from a field name. + * + * This method only retrieves active, non-deleted fields. + * + * @param $field_name + * The field name. + * + * @return + * The field definition, or NULL if no field was found. + */ + public function getField($field_name) { + // Read from the "static" cache. + if (isset($this->fieldIdsByName[$field_name])) { + $field_id = $this->fieldIdsByName[$field_name]; + return $this->fieldsById[$field_id]; + } + if (isset($this->unknownFields[$field_name])) { + return; + } + + // Do not check the (large) persistent cache, but read the definition. + + // Cache miss: read from definition. + if ($field = field_read_field(array('field_name' => $field_name))) { + $field = $this->prepareField($field); + + // Save in the "static" cache. + $this->fieldsById[$field['id']] = $field; + $this->fieldIdsByName[$field['field_name']] = $field['id']; + + return $field; + } + else { + $this->unknownFields[$field_name] = TRUE; + } + } + + /** + * Returns a field definition from a field ID. + * + * This method only retrieves active fields, deleted or not. + * + * @param $field_id + * The field ID. + * + * @return + * The field definition, or NULL if no field was found. + */ + public function getFieldById($field_id) { + // Read from the "static" cache. + if (isset($this->fieldsById[$field_id])) { + return $this->fieldsById[$field_id]; + } + if (isset($this->unknownFields[$field_id])) { + return; + } + + // No persistent cache, fields are only persistently cached as part of a + // bundle. + + // Cache miss: read from definition. + if ($fields = field_read_fields(array('id' => $field_id), array('include_deleted' => TRUE))) { + $field = current($fields); + $field = $this->prepareField($field); + + // Store in the static cache. + $this->fieldsById[$field['id']] = $field; + if (!$field['deleted']) { + $this->fieldIdsByName[$field['field_name']] = $field['id']; + } + + return $field; + } + else { + $this->unknownFields[$field_id] = TRUE; + } + } + + /** + * Retrieves the instances for a bundle. + * + * The function also populates the corresponding field definitions in the + * "static" cache. + * + * @param $entity_type + * The entity type. + * @param $bundle + * The bundle name. + * + * @return + * The array of instance definitions, keyed by field name. + */ + public function getBundleInstances($entity_type, $bundle) { + // Read from the "static" cache. + if (isset($this->bundleInstances[$entity_type][$bundle])) { + return $this->bundleInstances[$entity_type][$bundle]; + } + if (isset($this->emptyBundles[$entity_type][$bundle])) { + return array(); + } + + // Read from the persistent cache. + if ($cached = cache('field')->get("field_info:bundle:$entity_type:$bundle")) { + $info = $cached->data; + + // Extract the field definitions and save them in the "static" cache. + foreach ($info['fields'] as $field) { + if (!isset($this->fieldsById[$field['id']])) { + $this->fieldsById[$field['id']] = $field; + if (!$field['deleted']) { + $this->fieldIdsByName[$field['field_name']] = $field['id']; + } + } + } + unset($info['fields']); + + // Save in the "static" cache. + $this->bundleInstances[$entity_type][$bundle] = $info['instances']; + + return $info['instances']; + } + + // Cache miss: collect from the definitions. + + $instances = array(); + + // Collect the fields in the bundle. + $params = array('entity_type' => $entity_type, 'bundle' => $bundle); + $fields = field_read_fields($params); + + // This iterates on non-deleted instances, so deleted fields are kept out of + // the persistent caches. + foreach (field_read_instances($params) as $instance) { + $field = $fields[$instance['field_name']]; + + $instance = $this->prepareInstance($instance, $field['type']); + $instances[$field['field_name']] = $instance; + + // If the field is not in our global "static" list yet, add it. + if (!isset($this->fieldsById[$field['id']])) { + $field = $this->prepareField($field); + + $this->fieldsById[$field['id']] = $field; + $this->fieldIdsByName[$field['field_name']] = $field['id']; + } + } + + // Store in the 'static' cache'. Empty (or non-existent) bundles are stored + // separately, so that they do not pollute the global list returned by + // getInstances(). + if ($instances) { + $this->bundleInstances[$entity_type][$bundle] = $instances; + } + else { + $this->emptyBundles[$entity_type][$bundle] = TRUE; + } + + // The persistent cache additionally contains the definitions of the fields + // involved in the bundle. + $cache = array( + 'instances' => $instances, + 'fields' => array() + ); + foreach ($instances as $instance) { + $cache['fields'][] = $this->fieldsById[$instance['field_id']]; + } + cache('field')->set("field_info:bundle:$entity_type:$bundle", $cache); + + return $instances; + } + + /** + * Retrieves the "extra fields" for a bundle. + * + * @param $entity_type + * The entity type. + * @param $bundle + * The bundle name. + * + * @return + * The array of extra fields. + */ + public function getBundleExtraFields($entity_type, $bundle) { + // Read from the "static" cache. + if (isset($this->bundleExtraFields[$entity_type][$bundle])) { + return $this->bundleExtraFields[$entity_type][$bundle]; + } + + // Read from the persistent cache. + if ($cached = cache('field')->get("field_info:bundle_extra:$entity_type:$bundle")) { + $this->bundleExtraFields[$entity_type][$bundle] = $cached->data; + return $this->bundleExtraFields[$entity_type][$bundle]; + } + + // Cache miss: read from hook_field_extra_fields(). Note: given the current + // shape of the hook, we have no other way than collecting extra fields on + // all bundles. + $info = array(); + $extra = module_invoke_all('field_extra_fields'); + drupal_alter('field_extra_fields', $extra); + // Merge in saved settings. + if (isset($extra[$entity_type][$bundle])) { + $info = $this->prepareExtraFields($extra[$entity_type][$bundle], $entity_type, $bundle); + } + + // Store in the 'static' and persistent caches. + $this->bundleExtraFields[$entity_type][$bundle] = $info; + cache('field')->set("field_info:bundle_extra:$entity_type:$bundle", $info); + + return $this->bundleExtraFields[$entity_type][$bundle]; + } + + /** + * Prepares a field definition for the current run-time context. + * + * @param $field + * The raw field structure as read from the database. + * + * @return + * The field definition completed for the current runtime context. + */ + public function prepareField($field) { + // Make sure all expected field settings are present. + $field['settings'] += field_info_field_settings($field['type']); + $field['storage']['settings'] += field_info_storage_settings($field['storage']['type']); + + // Add storage details. + $details = (array) module_invoke($field['storage']['module'], 'field_storage_details', $field); + drupal_alter('field_storage_details', $details, $field); + $field['storage']['details'] = $details; + + // Populate the list of bundles using the field. + $field['bundles'] = array(); + if (!$field['deleted']) { + $map = $this->getFieldMap(); + if (isset($map[$field['field_name']])) { + $field['bundles'] = $map[$field['field_name']]['bundles']; + } + } + + return $field; + } + + /** + * Prepares an instance definition for the current run-time context. + * + * @param $instance + * The raw instance structure as read from the database. + * @param $field_type + * The field type. + * + * @return + * The field instance array completed for the current runtime context. + */ + public function prepareInstance($instance, $field_type) { + // Make sure all expected instance settings are present. + $instance['settings'] += field_info_instance_settings($field_type); + + // Set a default value for the instance. + if (field_behaviors_widget('default value', $instance) == FIELD_BEHAVIOR_DEFAULT && !isset($instance['default_value'])) { + $instance['default_value'] = NULL; + } + + // Prepare widget settings. + $instance['widget'] = $this->prepareInstanceWidget($instance['widget'], $field_type); + + // Prepare display settings. + foreach ($instance['display'] as $view_mode => $display) { + $instance['display'][$view_mode] = $this->prepareInstanceDisplay($display, $field_type); + } + + // Fall back to 'hidden' for view modes configured to use custom display + // settings, and for which the instance has no explicit settings. + $entity_info = entity_get_info($instance['entity_type']); + $view_modes = array_merge(array('default'), array_keys($entity_info['view modes'])); + $view_mode_settings = field_view_mode_settings($instance['entity_type'], $instance['bundle']); + foreach ($view_modes as $view_mode) { + if ($view_mode == 'default' || !empty($view_mode_settings[$view_mode]['custom_settings'])) { + if (!isset($instance['display'][$view_mode])) { + $instance['display'][$view_mode] = array( + 'type' => 'hidden', + 'label' => 'above', + 'settings' => array(), + 'weight' => 0, + ); + } + } + } + + return $instance; + } + + /** + * Prepares widget properties for the current run-time context. + * + * @param $widget + * Widget specifications as found in $instance['widget']. + * @param $field_type + * The field type. + * + * @return + * The widget properties completed for the current runtime context. + */ + public function prepareInstanceWidget($widget, $field_type) { + $field_type_info = field_info_field_types($field_type); + + // Fill in default values. + $widget += array( + 'type' => $field_type_info['default_widget'], + 'settings' => array(), + 'weight' => 0, + ); + + $widget_type_info = field_info_widget_types($widget['type']); + // Fall back to default formatter if formatter type is not available. + if (!$widget_type_info) { + $widget['type'] = $field_type_info['default_widget']; + $widget_type_info = field_info_widget_types($widget['type']); + } + $widget['module'] = $widget_type_info['module']; + // Fill in default settings for the widget. + $widget['settings'] += field_info_widget_settings($widget['type']); + + return $widget; + } + + /** + * Adapts display specifications to the current run-time context. + * + * @param $display + * Display specifications as found in $instance['display']['a_view_mode']. + * @param $field_type + * The field type. + * + * @return + * The display properties completed for the current runtime context. + */ + public function prepareInstanceDisplay($display, $field_type) { + $field_type_info = field_info_field_types($field_type); + + // Fill in default values. + $display += array( + 'label' => 'above', + 'type' => $field_type_info['default_formatter'], + 'settings' => array(), + 'weight' => 0, + ); + if ($display['type'] != 'hidden') { + $formatter_type_info = field_info_formatter_types($display['type']); + // Fall back to default formatter if formatter type is not available. + if (!$formatter_type_info) { + $display['type'] = $field_type_info['default_formatter']; + $formatter_type_info = field_info_formatter_types($display['type']); + } + $display['module'] = $formatter_type_info['module']; + // Fill in default settings for the formatter. + $display['settings'] += field_info_formatter_settings($display['type']); + } + + return $display; + } + + /** + * Prepares 'extra fields' for the current run-time context. + * + * @param $extra_fields + * The array of extra fields, as collected in hook_field_extra_fields(). + * @param $entity_type + * The entity type. + * @param $bundle + * The bundle name. + * + * @return + * The list of extra fields completed for the current runtime context. + */ + public function prepareExtraFields($extra_fields, $entity_type, $bundle) { + $entity_type_info = entity_get_info($entity_type); + $bundle_settings = field_bundle_settings($entity_type, $bundle); + $extra_fields += array('form' => array(), 'display' => array()); + + $result = array(); + // Extra fields in forms. + foreach ($extra_fields['form'] as $name => $field_data) { + $settings = isset($bundle_settings['extra_fields']['form'][$name]) ? $bundle_settings['extra_fields']['form'][$name] : array(); + if (isset($settings['weight'])) { + $field_data['weight'] = $settings['weight']; + } + $result['form'][$name] = $field_data; + } + + // Extra fields in displayed entities. + $data = $extra_fields['display']; + foreach ($extra_fields['display'] as $name => $field_data) { + $settings = isset($bundle_settings['extra_fields']['display'][$name]) ? $bundle_settings['extra_fields']['display'][$name] : array(); + $view_modes = array_merge(array('default'), array_keys($entity_type_info['view modes'])); + foreach ($view_modes as $view_mode) { + if (isset($settings[$view_mode])) { + $field_data['display'][$view_mode] = $settings[$view_mode]; + } + else { + $field_data['display'][$view_mode] = array( + 'weight' => $field_data['weight'], + 'visible' => isset($field_data['visible']) ? $field_data['visible'] : TRUE, + ); + } + } + unset($field_data['weight']); + unset($field_data['visible']); + $result['display'][$name] = $field_data; + } + + return $result; + } +} diff --git a/core/modules/field/lib/Drupal/field/FieldUpdateForbiddenException.php b/core/modules/field/lib/Drupal/field/FieldUpdateForbiddenException.php index 6bf914f..1fead43 100644 --- a/core/modules/field/lib/Drupal/field/FieldUpdateForbiddenException.php +++ b/core/modules/field/lib/Drupal/field/FieldUpdateForbiddenException.php @@ -1,6 +1,6 @@ $field_type) { foreach ($field_type as $key => $val) { - $this->assertEqual($info[$t_key][$key], $val, t("Field type $t_key key $key is $val")); + $this->assertEqual($info[$t_key][$key], $val, "Field type $t_key key $key is $val"); } - $this->assertEqual($info[$t_key]['module'], 'field_test', t("Field type field_test module appears")); + $this->assertEqual($info[$t_key]['module'], 'field_test', "Field type field_test module appears"); } $formatter_info = field_test_field_formatter_info(); $info = field_info_formatter_types(); foreach ($formatter_info as $f_key => $formatter) { foreach ($formatter as $key => $val) { - $this->assertEqual($info[$f_key][$key], $val, t("Formatter type $f_key key $key is $val")); + $this->assertEqual($info[$f_key][$key], $val, "Formatter type $f_key key $key is $val"); } - $this->assertEqual($info[$f_key]['module'], 'field_test', t("Formatter type field_test module appears")); + $this->assertEqual($info[$f_key]['module'], 'field_test', "Formatter type field_test module appears"); } $storage_info = field_test_field_storage_info(); $info = field_info_storage_types(); foreach ($storage_info as $s_key => $storage) { foreach ($storage as $key => $val) { - $this->assertEqual($info[$s_key][$key], $val, t("Storage type $s_key key $key is $val")); + $this->assertEqual($info[$s_key][$key], $val, "Storage type $s_key key $key is $val"); } - $this->assertEqual($info[$s_key]['module'], 'field_test', t("Storage type field_test module appears")); + $this->assertEqual($info[$s_key]['module'], 'field_test', "Storage type field_test module appears"); } // Verify that no unexpected instances exist. $instances = field_info_instances('test_entity'); - $expected = array('test_bundle' => array()); + $expected = array(); $this->assertIdentical($instances, $expected, "field_info_instances('test_entity') returns " . var_export($expected, TRUE) . '.'); $instances = field_info_instances('test_entity', 'test_bundle'); $this->assertIdentical($instances, array(), "field_info_instances('test_entity', 'test_bundle') returns an empty array."); @@ -76,16 +76,16 @@ class FieldInfoTest extends FieldTestBase { ); field_create_field($field); $fields = field_info_fields(); - $this->assertEqual(count($fields), count($core_fields) + 1, t('One new field exists')); - $this->assertEqual($fields[$field['field_name']]['field_name'], $field['field_name'], t('info fields contains field name')); - $this->assertEqual($fields[$field['field_name']]['type'], $field['type'], t('info fields contains field type')); - $this->assertEqual($fields[$field['field_name']]['module'], 'field_test', t('info fields contains field module')); + $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'); + $this->assertEqual($fields[$field['field_name']]['type'], $field['type'], 'info fields contains field type'); + $this->assertEqual($fields[$field['field_name']]['module'], 'field_test', 'info fields contains field module'); $settings = array('test_field_setting' => 'dummy test string'); foreach ($settings as $key => $val) { - $this->assertEqual($fields[$field['field_name']]['settings'][$key], $val, t("Field setting $key has correct default value $val")); + $this->assertEqual($fields[$field['field_name']]['settings'][$key], $val, "Field setting $key has correct default value $val"); } - $this->assertEqual($fields[$field['field_name']]['cardinality'], 1, t('info fields contains cardinality 1')); - $this->assertEqual($fields[$field['field_name']]['active'], 1, t('info fields contains active 1')); + $this->assertEqual($fields[$field['field_name']]['cardinality'], 1, 'info fields contains cardinality 1'); + $this->assertEqual($fields[$field['field_name']]['active'], 1, 'info fields contains active 1'); // Create an instance, verify that it shows up $instance = array( @@ -103,8 +103,8 @@ class FieldInfoTest extends FieldTestBase { field_create_instance($instance); $instances = field_info_instances('test_entity', $instance['bundle']); - $this->assertEqual(count($instances), 1, t('One instance shows up in info when attached to a bundle.')); - $this->assertTrue($instance < $instances[$instance['field_name']], t('Instance appears in info correctly')); + $this->assertEqual(count($instances), 1, 'One instance shows up in info when attached to a bundle.'); + $this->assertTrue($instance < $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'); @@ -120,7 +120,7 @@ class FieldInfoTest extends FieldTestBase { // Test with an entity type that has no bundles. $instances = field_info_instances('user'); - $expected = array('user' => array()); + $expected = array(); $this->assertIdentical($instances, $expected, "field_info_instances('user') returns " . var_export($expected, TRUE) . '.'); $instances = field_info_instances('user', 'user'); $this->assertIdentical($instances, array(), "field_info_instances('user', 'user') returns an empty array."); @@ -154,7 +154,7 @@ class FieldInfoTest extends FieldTestBase { // Check that all expected settings are in place. $field_type = field_info_field_types($field_definition['type']); - $this->assertIdentical($field['settings'], $field_type['settings'], t('All expected default field settings are present.')); + $this->assertIdentical($field['settings'], $field_type['settings'], 'All expected default field settings are present.'); } /** @@ -196,19 +196,19 @@ class FieldInfoTest extends FieldTestBase { // Check that all expected instance settings are in place. $field_type = field_info_field_types($field_definition['type']); - $this->assertIdentical($instance['settings'], $field_type['instance_settings'] , t('All expected instance settings are present.')); + $this->assertIdentical($instance['settings'], $field_type['instance_settings'] , 'All expected instance settings are present.'); // Check that the default widget is used and expected settings are in place. $widget = $instance->getWidget(); - $this->assertIdentical($widget->getPluginId(), $field_type['default_widget'], t('Unavailable widget replaced with default widget.')); + $this->assertIdentical($widget->getPluginId(), $field_type['default_widget'], 'Unavailable widget replaced with default widget.'); $widget_type = $widget->getDefinition(); - $this->assertIdentical($widget->getSettings(), $widget_type['settings'] , t('All expected widget settings are present.')); + $this->assertIdentical($widget->getSettings(), $widget_type['settings'] , 'All expected widget settings are present.'); // Check that display settings are set for the 'default' mode. $display = $instance['display']['default']; - $this->assertIdentical($display['type'], $field_type['default_formatter'], t("Formatter is set for the 'default' view mode")); + $this->assertIdentical($display['type'], $field_type['default_formatter'], "Formatter is set for the 'default' view mode"); $formatter_type = field_info_formatter_types($display['type']); - $this->assertIdentical($display['settings'], $formatter_type['settings'] , t("Formatter settings are set for the 'default' view mode")); + $this->assertIdentical($display['settings'], $formatter_type['settings'] , "Formatter settings are set for the 'default' view mode"); } /** @@ -231,10 +231,85 @@ class FieldInfoTest extends FieldTestBase { // Disable coment module. This clears field_info cache. module_disable(array('comment')); - $this->assertNull(field_info_instance('comment', 'field', 'comment_node_article'), t('No instances are returned on disabled entity types.')); + $this->assertNull(field_info_instance('comment', 'field', 'comment_node_article'), 'No instances are returned on disabled entity types.'); } /** + * Test field_info_field_map(). + */ + function testFieldMap() { + // We will overlook fields created by the 'standard' install profile. + $exclude = field_info_field_map(); + + // Create a new bundle for 'test_entity' entity type. + field_test_create_bundle('test_bundle_2'); + + // Create a couple fields. + $fields = array( + array( + 'field_name' => 'field_1', + 'type' => 'test_field', + ), + array( + 'field_name' => 'field_2', + 'type' => 'hidden_test_field', + ), + ); + foreach ($fields as $field) { + field_create_field($field); + } + + // Create a couple instances. + $instances = array( + array( + 'field_name' => 'field_1', + 'entity_type' => 'test_entity', + 'bundle' => 'test_bundle', + ), + array( + 'field_name' => 'field_1', + 'entity_type' => 'test_entity', + 'bundle' => 'test_bundle_2', + ), + array( + 'field_name' => 'field_2', + 'entity_type' => 'test_entity', + 'bundle' => 'test_bundle', + ), + array( + 'field_name' => 'field_2', + 'entity_type' => 'test_cacheable_entity', + 'bundle' => 'test_bundle', + ), + ); + foreach ($instances as $instance) { + field_create_instance($instance); + } + + $expected = array( + 'field_1' => array( + 'type' => 'test_field', + 'bundles' => array( + 'test_entity' => array('test_bundle', 'test_bundle_2'), + ), + ), + 'field_2' => array( + 'type' => 'hidden_test_field', + 'bundles' => array( + 'test_entity' => array('test_bundle'), + 'test_cacheable_entity' => array('test_bundle'), + ), + ), + ); + + // Check that the field map is correct. + $map = field_info_field_map(); + $map = array_diff_key($map, $exclude); + $this->assertEqual($map, $expected); + } + + + /** * Test that the field_info settings convenience functions work. */ function testSettingsInfo() { diff --git a/core/modules/field/modules/field_sql_storage/field_sql_storage.module b/core/modules/field/modules/field_sql_storage/field_sql_storage.module index 310cf6c..26b2ba8 100644 --- a/core/modules/field/modules/field_sql_storage/field_sql_storage.module +++ b/core/modules/field/modules/field_sql_storage/field_sql_storage.module @@ -335,11 +335,10 @@ function field_sql_storage_field_storage_delete_field($field) { * Implements hook_field_storage_load(). */ function field_sql_storage_field_storage_load($entity_type, $entities, $age, $fields, $options) { - $field_info = field_info_field_by_ids(); $load_current = $age == FIELD_LOAD_CURRENT; foreach ($fields as $field_id => $ids) { - $field = $field_info[$field_id]; + $field = field_info_field_by_id($field_id); $field_name = $field['field_name']; $table = $load_current ? _field_sql_storage_tablename($field) : _field_sql_storage_revision_tablename($field); diff --git a/core/modules/field_ui/field_ui.admin.inc b/core/modules/field_ui/field_ui.admin.inc index 924a85b..2ea775f 100644 --- a/core/modules/field_ui/field_ui.admin.inc +++ b/core/modules/field_ui/field_ui.admin.inc @@ -350,7 +350,8 @@ function field_ui_field_overview_form($form, &$form_state, $entity_type, $bundle foreach ($instances as $name => $instance) { $field = field_info_field($instance['field_name']); $admin_field_path = $admin_path . '/fields/' . $instance['field_name']; - $widget_definition = $instance->getWidget()->getDefinition(); + $instanceObject = new FieldInstance($instance); + $widget_definition = $instanceObject->getWidget()->getDefinition(); $table[$name] = array( '#attributes' => array('class' => array('draggable', 'tabledrag-leaf')), diff --git a/core/modules/field_ui/field_ui.module b/core/modules/field_ui/field_ui.module index 2efc07c..e984b87 100644 --- a/core/modules/field_ui/field_ui.module +++ b/core/modules/field_ui/field_ui.module @@ -327,23 +327,30 @@ function _field_ui_bundle_admin_path($entity_type, $bundle_name) { * Identifies inactive fields within a bundle. */ function field_ui_inactive_instances($entity_type, $bundle_name = NULL) { - if (!empty($bundle_name)) { - $inactive = array($bundle_name => array()); - $params = array('bundle' => $bundle_name); + $params = array('entity_type' => $entity_type); + + if (empty($bundle_name)) { + $active = field_info_instances($entity_type); + $inactive = array(); } else { - $inactive = array(); - $params = array(); + // Restrict to the specified bundle. For consistency with the case where + // $bundle_name is NULL, the $active and $inactive arrays are keyed by + // bundle name first. + $params['bundle'] = $bundle_name; + $active = array($bundle_name => field_info_instances($entity_type, $bundle_name)); + $inactive = array($bundle_name => array()); } - $params['entity_type'] = $entity_type; - $active_instances = field_info_instances($entity_type); + // Iterate on existing definitions, and spot those that do not appear in the + // $active list collected earlier. $all_instances = field_read_instances($params, array('include_inactive' => TRUE)); foreach ($all_instances as $instance) { - if (!isset($active_instances[$instance['bundle']][$instance['field_name']])) { + if (!isset($active[$instance['bundle']][$instance['field_name']])) { $inactive[$instance['bundle']][$instance['field_name']] = $instance; } } + if (!empty($bundle_name)) { return $inactive[$bundle_name]; } diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageFieldsTest.php b/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageFieldsTest.php index 4aa0dd6..d086cb5 100644 --- a/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageFieldsTest.php +++ b/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageFieldsTest.php @@ -172,7 +172,7 @@ class ManageFieldsTest extends FieldUiTestBase { */ function assertFieldSettings($bundle, $field_name, $string = 'dummy test string', $entity_type = 'node') { // Reset the fields info. - _field_info_collate_fields_reset(); + field_info_cache_clear(); // Assert field settings. $field = field_info_field($field_name); $this->assertTrue($field['settings']['test_field_setting'] == $string, t('Field settings were found.')); @@ -262,7 +262,7 @@ class ManageFieldsTest extends FieldUiTestBase { $this->fieldUIDeleteField($bundle_path1, $this->field_name, $this->field_label, $this->type); // Reset the fields info. - _field_info_collate_fields_reset(); + field_info_cache_clear(); // Check that the field instance was deleted. $this->assertNull(field_info_instance('node', $this->field_name, $this->type), t('Field instance was deleted.')); // Check that the field was not deleted @@ -272,7 +272,7 @@ class ManageFieldsTest extends FieldUiTestBase { $this->fieldUIDeleteField($bundle_path2, $this->field_name, $this->field_label, $type_name2); // Reset the fields info. - _field_info_collate_fields_reset(); + field_info_cache_clear(); // Check that the field instance was deleted. $this->assertNull(field_info_instance('node', $this->field_name, $type_name2), t('Field instance was deleted.')); // Check that the field was deleted too.