diff -u b/modules/field/FieldInfo.php b/modules/field/FieldInfo.php --- b/modules/field/FieldInfo.php +++ b/modules/field/FieldInfo.php @@ -305,7 +305,7 @@ // Cache miss: collect from the definitions. - $info = array( + $this->bundleInfo[$entity_type][$bundle] = array( 'instances' => array(), 'extra_fields' => array(), ); @@ -320,7 +320,7 @@ $field = $fields[$instance['field_name']]; $instance = $this->prepareInstance($instance, $field['type']); - $info['instances'][$field['field_name']] = $instance; + $this->bundleInfo[$entity_type][$bundle]['instances'][$field['field_name']] = $instance; // If the field is not in our global "static" list yet, add it. if (!isset($this->fieldsById[$field['id']])) { @@ -338,21 +338,18 @@ drupal_alter('field_extra_fields', $extra); // Merge in saved settings. if (isset($extra[$entity_type][$bundle])) { - $info['extra_fields'] = $this->prepareExtraFields($extra[$entity_type][$bundle], $entity_type, $bundle); + $this->bundleInfo[$entity_type][$bundle]['extra_fields'] = $this->prepareExtraFields($extra[$entity_type][$bundle], $entity_type, $bundle); } - // Save in the "static" cache. - $this->bundleInfo[$entity_type][$bundle] = $info; - // The persistent cache additionally contains the definitions of the fields // involved in the bundle. - $cache = $info + array('fields' => array()); - foreach ($info['instances'] as $instance) { + $cache = $this->bundleInfo[$entity_type][$bundle] + array('fields' => array()); + foreach ($this->bundleInfo[$entity_type][$bundle]['instances'] as $instance) { $cache['fields'][] = $this->fieldsById[$instance['field_id']]; } cache_set("field_info:bundle:$entity_type:$bundle", $cache, 'cache_field'); - return $info; + return $this->bundleInfo[$entity_type][$bundle]; } /** diff -u b/modules/field/tests/field.test b/modules/field/tests/field.test --- b/modules/field/tests/field.test +++ b/modules/field/tests/field.test @@ -1274,6 +1274,31 @@ $this->assertIdentical(field_info_formatter_settings($type), $data['settings'], "field_info_formatter_settings returns {$type}'s formatter settings"); } } + + /** + * Tests that the field info cache can be built correctly. + */ + function testFieldInfoCache() { + // Create a test field and ensure it's in the array returned by + // field_info_fields(). + $field_name = drupal_strtolower($this->randomName()); + $field = array( + 'field_name' => $field_name, + 'type' => 'test_field', + ); + field_create_field($field); + $fields = field_info_fields(); + $this->assertTrue(isset($fields[$field_name]), 'The test field is initially found in the array returned by field_info_fields().'); + + // Now rebuild the field info cache, and set a variable which will cause + // the cache to be cleared while it's being rebuilt; see + // field_test_entity_info(). Ensure the test field is still in the returned + // array. + field_info_cache_clear(); + variable_set('field_test_clear_info_cache_in_hook_entity_info', TRUE); + $fields = field_info_fields(); + $this->assertTrue(isset($fields[$field_name]), 'The test field is found in the array returned by field_info_fields() even if its cache is cleared while being rebuilt.'); + } } class FieldFormTestCase extends FieldTestCase { only in patch2: unchanged: --- a/modules/field/tests/field_test.entity.inc +++ b/modules/field/tests/field_test.entity.inc @@ -9,6 +9,12 @@ * Implements hook_entity_info(). */ function field_test_entity_info() { + // If requested, clear the field cache while this hook is being called. See + // testFieldInfoCache(). + if (variable_get('field_test_clear_info_cache_in_hook_entity_info', FALSE)) { + field_info_cache_clear(); + } + $bundles = variable_get('field_test_bundles', array('test_bundle' => array('label' => 'Test Bundle'))); $test_entity_modes = array( 'full' => array(