Returns the display language code for the fields attached to the given entity.
The actual language code for each given field is determined based on the requested language code and the actual data available in the fields themselves. If there is no registered translation handler for the given entity type, the display language code to be used is just Language::LANGCODE_NOT_SPECIFIED, as no other language code is allowed by field_available_languages().
If translation handlers are found, we let modules provide alternative display language codes for fields not having the requested language code available. Core language fallback rules are provided by field_language_fallback() which is called by field_field_language_alter().
\Drupal\Core\Entity\EntityInterface $entity: The entity to be displayed.
$field_name: (optional) The name of the field to be displayed. Defaults to NULL. If no value is specified, the display language codes for every field attached to the given entity will be returned.
$langcode: (optional) The language code $entity has to be displayed in. Defaults to NULL. If no value is given the current language will be used.
A language code if a field name is specified, an array of language codes keyed by field name otherwise.
function field_language(EntityInterface $entity, $field_name = NULL, $langcode = NULL) {
$display_langcodes =& drupal_static(__FUNCTION__, array());
$id = $entity
->id();
$bundle = $entity
->bundle();
$entity_type = $entity
->entityType();
$langcode = field_valid_language($langcode, FALSE);
if (!isset($display_langcodes[$entity_type][$id][$langcode])) {
$display_langcode = array();
// By default, display language is set to one of the locked languages
// if the field translation is not available. It is up to translation
// handlers to implement language fallback rules.
foreach (field_info_instances($entity_type, $bundle) as $instance) {
if (isset($entity->{$instance['field_name']}[$langcode])) {
$display_langcode[$instance['field_name']] = $langcode;
}
else {
// If the field has a value for one of the locked languages, then use
// that language for display. If not, the default one will be
// Language::LANGCODE_NOT_SPECIFIED.
$display_langcode[$instance['field_name']] = Language::LANGCODE_NOT_SPECIFIED;
foreach (language_list(Language::STATE_LOCKED) as $language_locked) {
if (isset($entity->{$instance['field_name']}[$language_locked->langcode])) {
$display_langcode[$instance['field_name']] = $language_locked->langcode;
break;
}
}
}
}
if (field_has_translation_handler($entity_type)) {
$context = array(
'entity' => $entity,
'langcode' => $langcode,
);
// Do not apply core language fallback rules if they are disabled or if
// the entity does not have a translation handler registered.
if (field_language_fallback_enabled() && field_has_translation_handler($entity_type)) {
field_language_fallback($display_langcode, $context['entity'], $context['langcode']);
}
drupal_alter('field_language', $display_langcode, $context);
}
$display_langcodes[$entity_type][$id][$langcode] = $display_langcode;
}
$display_langcode = $display_langcodes[$entity_type][$id][$langcode];
// Single-field mode.
if (isset($field_name)) {
return isset($display_langcode[$field_name]) ? $display_langcode[$field_name] : FALSE;
}
return $display_langcode;
}