This is not an issue that comes up often, but it's got the potential to bite.

field_available_languages caches it's set of languages for a given entity type and field, but the static cache is not cleared when a field is updated in field_update_field. This means that even though a field might have had it's 'translatable' setting changed, the available languages won't change.

This leads to interesting things like this, if you had a node with a 'translatable' => FALSE 'body' field.

// Load a node type with a body field, which will cache the languages as array(LANGAUGE_NONE);
$nid = 1;
$node = node_load($nid);

// Change the field language.
$body = field_info_field('body');
$body['translatable'] = 1;
field_update_field($body);

// Move the LANGUAGE_NONE field values to be english values
$node->body['en'] = $node->body[LANGUAGE_NONE];
$node->body[LANGUAGE_NONE] = array();
node_save($node);

At this point, because the list LANGUAGE_NONE was cached as the only language, the body field english values are erased and the field will no longer have any values.

There are a few different places that this could be cleared, and I'm not sure which is best.
* http://api.drupal.org/api/drupal/modules--field--field.crud.inc/function...
* http://api.drupal.org/api/drupal/modules--field--field.module/function/f...
* http://api.drupal.org/api/drupal/modules--field--field.info.inc/function...

This came up when I was reviewing #1279372: Enable bulk field language updates when switching field translatability

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

plach’s picture

Good catch, Logan!
At a first glance I'd say field_info_cache_clear looks like the most appropriate place to fix this.

loganfsmyth’s picture

Here's an initial shot at this.

The test in entity_query.test was actually resetting this cache all on its own because it doesn't pass otherwise, so I've also fixed it to not clear the cache.

There is one test in field.test that would have caught this, but it was changing the field array to have a different name. I can't think of any good reason that it needs to do that, so I've removed the field name change, and added a proper field_update_field call so that the field_available_languages call will be running on a real field object.

Lets see what the testbot thinks.

plach’s picture

Status: Needs review » Reviewed & tested by the community

Looks great!

catch’s picture

Version: 8.x-dev » 7.x-dev
Status: Reviewed & tested by the community » Patch (to be ported)

Yep. Committed/pushed to 8.x, will need a quick re-roll for D7.

yched’s picture

Status: Patch (to be ported) » Needs work
+++ b/core/modules/field/tests/field.testundefined
@@ -2678,7 +2678,7 @@ class FieldTranslationsTestCase extends FieldTestCase {
-    $this->field_name = $this->field['field_name'] = $this->instance['field_name'] = drupal_strtolower($this->randomName() . '_field_name');

I don't understand that hunk ?

-2 days to next Drupal core point release.

loganfsmyth’s picture

@yched field_available_languages takes a field array as an argument and caches the languages based on the entity_type and field_name values. In the original test the field array's field_name was being changed so no apparent reason. This change means that the next call doesn't read from the cache since the name is different. It also meant that field_available_languages was essentially being passed a fake field array that doesn't exist in the DB, which seems odd.

By removing the name change, and calling field_update_field, I make sure that the field is properly updated before calling field_available_languages.

Does that seem reasonable.

plach’s picture

Status: Needs work » Patch (to be ported)

Exactly. Moreover the field's translatabilty is changed, so the call to field_update_field() makes that "official" :)

aspilicious’s picture

Status: Patch (to be ported) » Needs review
FileSize
2.26 KB

Reroll :)

plach’s picture

Thanks! can you post also the test only patch?

aspilicious’s picture

yched’s picture

@loganfsmyth : ok, makes sense now, thanks !

Status: Needs review » Needs work

The last submitted patch, field-available-languages-cache-1380660-8-test-only.patch, failed testing.

aspilicious’s picture

Status: Needs work » Needs review

I think #8 is rtbc

plach’s picture

Status: Needs review » Reviewed & tested by the community

Yes, RTBC patch in #8.

webchick’s picture

Status: Reviewed & tested by the community » Fixed

Committed and pushed to 7.x. Thanks!

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

cweagans’s picture

Issue tags: +Needs backport to D7
cweagans’s picture

cweagans’s picture

Issue summary: View changes

Updated issue summary.