diff -u b/core/lib/Drupal/Core/Entity/Entity.php b/core/lib/Drupal/Core/Entity/Entity.php --- b/core/lib/Drupal/Core/Entity/Entity.php +++ b/core/lib/Drupal/Core/Entity/Entity.php @@ -184,9 +184,8 @@ $entity_info = $this->entityInfo(); if ($entity_info['fieldable'] && field_info_instance($this->entityType, $property_name, $this->bundle())) { $field = field_info_field($property_name); - // Since we are getting and not setting, we call getFieldLangcode with - // strict = FALSE, so if we request a field with a invalid language we - // don't throw an exception. + // Prevent getFieldLangcode() from throwing an exception in case a + // $langcode has been passed and it is invalid for the field. $langcode = $this->getFieldLangcode($field, $langcode, FALSE); return isset($this->{$property_name}[$langcode]) ? $this->{$property_name}[$langcode] : NULL; } @@ -205,7 +204,7 @@ $entity_info = $this->entityInfo(); if ($entity_info['fieldable'] && field_info_instance($this->entityType, $property_name, $this->bundle())) { $field = field_info_field($property_name); - // This will throw an exception if the $langcode is invalid. + // Throws an exception if the $langcode is invalid. $langcode = $this->getFieldLangcode($field, $langcode); $this->{$property_name}[$langcode] = $value; } @@ -219,31 +218,38 @@ /** * Determines the language code for accessing a field value. * - * If the entity is language-specific and the field is translatable, the - * langcode is used to access the field value. Otherwise, - * LANGUAGE_NOT_SPECIFIED should be used to access the field value, as in the - * case of a field shared among all language versions of an entity. When the - * field is not translatable and the langcode attempted is not - * LANGUAGE_NOT_SPECIFIED an exception is thrown in strict mode, or NULL is - * returned in non-strict mode. + * The effective language code to be used for a field varies: + * - If the entity is language-specific and the requested field is + * translatable, the entity's language code should be used to access the + * field value. + * - If the entity is not language-specific, LANGUAGE_NOT_SPECIFIED should be + * used to access all field values. + * - If a field's values are shared among all language versions of an entity, + * LANGUAGE_NOT_SPECIFIED should be used to access them. * - * @param $field + * There cannot be valid field values if a field is not translatable and the + * requested langcode is not LANGUAGE_NOT_SPECIFIED. Therefore, this function + * throws an exception in that case (or returns NULL when $strict is FALSE). + * + * @param string $field * Field the language code is being determined for. - * @param $langcode + * @param string|null $langcode * (optional) The language code attempting to be applied to the field. - * @param $strict - * (optional) Flag for how strict to be, which takes a Boolean TRUE/FALSE - * value. This flag exists so we can be differently strict for invalid - * langcodes when setting and getting field values. When $strict is TRUE, - * an exception is thrown if the field is non-translatable and the langcode - * is anything other than LANGUAGE_NOT_SPECIFIED. When $strict is FALSE, - * NULL is returned instead of an exception being thrown. For example, the - * EntityInterface set() uses $strict TRUE, and the EntityInterface get() - * uses $strict FALSE. + * @param bool $strict + * (optional) When $strict is TRUE, an exception is thrown if the field is + * not translatable and the langcode is not LANGUAGE_NOT_SPECIFIED. When + * $strict is FALSE, NULL is returned and no exception is thrown. For + * example, EntityInterface::set() passes TRUE, since it must not set field + * values for invalid langcodes. EntityInterface::get() passes FALSE to + * determine whether any field values exist for a specific langcode. * - * @return + * @return string|null * The langcode if appropriate, LANGUAGE_NOT_SPECIFIED for non-translatable * fields, or NULL when an invalid langcode was used in non-strict mode. + * + * @throws \InvalidArgumentException + * Thrown in case a $langcode other than LANGUAGE_NOT_SPECIFIED is passed + * for a non-translatable field and $strict is TRUE. */ protected function getFieldLangcode($field, $langcode = NULL, $strict = TRUE) { // Only apply the given langcode if the entity is language-specific. @@ -254,18 +260,20 @@ return isset($langcode) ? $langcode : $default_language->langcode; } else { - // Field was non-translatable but the attempted langcode was something - // other than LANGUAGE_NOT_SPECIFIED. - if ($langcode != NULL && $langcode != LANGUAGE_NOT_SPECIFIED) { - // Only throw Exception in strict mode. + // The field is not translatable, but the caller requested a specific + // langcode that does not exist. + if (isset($langcode) && $langcode !== LANGUAGE_NOT_SPECIFIED) { if ($strict) { - throw new EntityStorageException(format_string("Field @field_name is not translatable and only works with langcode = LANGUAGE_NOT_SPECIFIED", array('@field_name' => $field['field_name']))); + throw new \InvalidArgumentException(format_string('Unable to resolve @langcode for non-translatable field @field_name. Use langcode LANGUAGE_NOT_SPECIFIED instead.', array( + '@field_name' => $field['field_name'], + '@langcode' => $langcode, + ))); } else { return NULL; } } - // Field was non-translatable and the langcode was LANGUAGE_NOT_SPECIFIED. + // The field is not translatable and no $langcode was specified. return LANGUAGE_NOT_SPECIFIED; } }