From bb4359a428e4d8b317fd29f1d5a385ebd0198846 Mon Sep 17 00:00:00 2001 From: webchick <webchick@24967.no-reply.drupal.org> Date: Fri, 27 Dec 2013 22:42:52 -0800 Subject: [PATCH] Issue #2067079 by yched, andypost: Remove the Field Language API. --- core/modules/field/field.api.php | 22 --- core/modules/field/field.deprecated.inc | 77 +------- core/modules/field/field.info.inc | 1 - core/modules/field/field.module | 24 ++- core/modules/field/field.multilingual.inc | 174 ------------------ .../Drupal/field/Tests/TranslationTest.php | 37 +--- .../Drupal/field/Tests/TranslationWebTest.php | 4 +- .../modules/field_test/field_test.entity.inc | 1 - .../modules/field_test/field_test.module | 13 -- .../system/Tests/Entity/EntityQueryTest.php | 2 - 10 files changed, 14 insertions(+), 341 deletions(-) delete mode 100644 core/modules/field/field.multilingual.inc diff --git a/core/modules/field/field.api.php b/core/modules/field/field.api.php index 8341c7a156a4..6d34707718ac 100644 --- a/core/modules/field/field.api.php +++ b/core/modules/field/field.api.php @@ -415,28 +415,6 @@ function hook_field_attach_view_alter(&$output, $context) { } } -/** - * Alter field_available_languages() values. - * - * This hook is invoked from field_available_languages() to allow modules to - * alter the array of available language codes for the given field. - * - * @param $langcodes - * A reference to an array of language codes to be made available. - * @param $context - * An associative array containing: - * - entity_type: The type of the entity the field is attached to. - * - field: A field data structure. - */ -function hook_field_available_languages_alter(&$langcodes, $context) { - // Add an unavailable language code. - $langcodes[] = 'xx'; - - // Remove an available language code. - $index = array_search('yy', $langcodes); - unset($langcodes[$index]); -} - /** * @} End of "addtogroup field_attach". */ diff --git a/core/modules/field/field.deprecated.inc b/core/modules/field/field.deprecated.inc index 94373bcd4982..31c67580fb25 100644 --- a/core/modules/field/field.deprecated.inc +++ b/core/modules/field/field.deprecated.inc @@ -774,8 +774,7 @@ function field_attach_view(EntityInterface $entity, EntityViewDisplayInterface $ * $entity->getTranslation($langcode)->{$field_name} */ function field_get_items(EntityInterface $entity, $field_name, $langcode = NULL) { - $langcode = field_language($entity, $field_name, $langcode); - return isset($entity->{$field_name}[$langcode]) ? $entity->{$field_name}[$langcode] : array(); + return \Drupal::entityManager()->getTranslationFromContext($entity, $langcode)->{$field_name}; } /** @@ -828,77 +827,3 @@ function field_access($op, FieldInterface $field, $entity_type, $entity = NULL, $items = $entity ? $entity->get($field->id()) : NULL; return $access_controller->fieldAccess($op, $field, $account, $items); } - -/** - * Ensures that a given language code is valid. - * - * Checks whether the given language code is one of the enabled language codes. - * Otherwise, it returns the current, global language code; or the site's - * default language code, if the additional parameter $default is TRUE. - * - * @param $langcode - * The language code to validate. - * @param $default - * Whether to return the default language code or the current language code in - * case $langcode is invalid. - * - * @return - * A valid language code. - * - * @deprecated This has been deprecated in favor of the Entity Field API. - */ -function field_valid_language($langcode, $default = TRUE) { - $languages = field_content_languages(); - if (in_array($langcode, $languages)) { - return $langcode; - } - return $default ? language_default()->id : language(Language::TYPE_CONTENT)->id; -} - -/** - * 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. - * - * @param \Drupal\Core\Entity\EntityInterface $entity - * The entity to be displayed. - * @param $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. - * @param $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. - * - * @return - * A language code if a field name is specified, an array of language codes - * keyed by field name otherwise. - * - * @see \Drupal\Core\Language\LanguageManager::getFallbackCandidates() - * @see \Drupal\Core\Entity\EntityInterface::getFieldLangcode() - * - * @deprecated This has been deprecated in favor of the Entity Field API. - */ -function field_language(EntityInterface $entity, $field_name = NULL, $langcode = NULL) { - $langcode = \Drupal::entityManager()->getTranslationFromContext($entity, $langcode)->language()->id; - $translatable = field_has_translation_handler($entity->entityType()); - if (!isset($field_name)) { - $display_langcodes = array(); - foreach ($entity->getPropertyDefinitions() as $name => $definition) { - $display_langcodes[$name] = $translatable ? $langcode : Language::LANGCODE_NOT_SPECIFIED; - } - return $display_langcodes; - } - else { - return $translatable ? $langcode : Language::LANGCODE_NOT_SPECIFIED; - } -} diff --git a/core/modules/field/field.info.inc b/core/modules/field/field.info.inc index d33b2df11a4b..119f6faf1235 100644 --- a/core/modules/field/field.info.inc +++ b/core/modules/field/field.info.inc @@ -29,7 +29,6 @@ function field_info_cache_clear() { drupal_static_reset('field_view_mode_settings'); drupal_static_reset('field_form_mode_settings'); - drupal_static_reset('field_available_languages'); // @todo: Remove this when field_attach_*_bundle() bundle management // functions are moved to the entity API. diff --git a/core/modules/field/field.module b/core/modules/field/field.module index e19408cabf5b..8b80c56bd872 100644 --- a/core/modules/field/field.module +++ b/core/modules/field/field.module @@ -7,8 +7,6 @@ use Drupal\Core\Entity\ContentEntityInterface; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Template\Attribute; -use Drupal\field\FieldInterface; -use Drupal\field\FieldInstanceInterface; /* * Load all public Field API functions. Drupal currently has no @@ -16,7 +14,6 @@ * every page request. */ require_once __DIR__ . '/field.info.inc'; -require_once __DIR__ . '/field.multilingual.inc'; require_once __DIR__ . '/field.attach.inc'; require_once __DIR__ . '/field.form.inc'; require_once __DIR__ . '/field.purge.inc'; @@ -348,13 +345,15 @@ function field_view_value(EntityInterface $entity, $field_name, $item, $display $output = array(); if ($field = field_info_field($entity->entityType(), $field_name)) { - // Determine the langcode that will be used by language fallback. - $langcode = field_language($entity, $field_name, $langcode); + // Clone the entity since we are going to modify field values. + $clone = clone $entity; + + // Apply language fallback. + $clone = \Drupal::entityManager()->getTranslationFromContext($clone, $langcode); // Push the item as the single value for the field, and defer to // field_view_field() to build the render array for the whole field. - $clone = clone $entity; - $clone->getTranslation($langcode)->{$field_name}->setValue(array($item)); + $clone->{$field_name}->setValue(array($item)); $elements = field_view_field($clone, $field_name, $display, $langcode); // Extract the part of the render array we need. @@ -419,8 +418,6 @@ function field_view_value(EntityInterface $entity, $field_name, $item, $display */ function field_view_field(ContentEntityInterface $entity, $field_name, $display_options = array(), $langcode = NULL) { $output = array(); - $bundle = $entity->bundle(); - $entity_type = $entity->entityType(); // Return nothing if the field doesn't exist. if (!$entity->hasField($field_name)) { @@ -448,10 +445,11 @@ function field_view_field(ContentEntityInterface $entity, $field_name, $display_ } if ($formatter) { - $display_langcode = field_language($entity, $field_name, $langcode); + // Apply language fallback. + $entity = \Drupal::entityManager()->getTranslationFromContext($entity, $langcode); + $items = $entity->get($field_name); - // Invoke the formatter's prepareView() and view() methods. - $items = $entity->getTranslation($display_langcode)->get($field_name); + // Run the formatter. $formatter->prepareView(array($entity->id() => $items)); $result = $formatter->view($items); @@ -461,7 +459,7 @@ function field_view_field(ContentEntityInterface $entity, $field_name, $display_ 'entity' => $entity, 'view_mode' => $view_mode, 'display_options' => $display_options, - 'langcode' => $display_langcode, + 'langcode' => $entity->language()->id, ); drupal_alter('field_attach_view', $result, $context); diff --git a/core/modules/field/field.multilingual.inc b/core/modules/field/field.multilingual.inc deleted file mode 100644 index d5d058acc64c..000000000000 --- a/core/modules/field/field.multilingual.inc +++ /dev/null @@ -1,174 +0,0 @@ -<?php - -/** - * @file - * Functions implementing Field API multilingual support. - */ - -use Drupal\Core\Language\Language; -use Drupal\Core\Entity\EntityInterface; -use Drupal\field\FieldInterface; - -/** - * @defgroup field_language Field Language API - * @{ - * Handles multilingual fields. - * - * Fields natively implement multilingual support, and all fields use the - * following structure: - * @code - * $entity->{$field_name}[$langcode][$delta][$column_name] - * @endcode - * Every field can hold a single or multiple value for each language code - * belonging to the available language codes set: - * - For untranslatable fields this set is only Language::LANGCODE_DEFAULT. - * - For translatable fields this set can contain any language code. By default - * it is the list returned by field_content_languages(), which contains all - * installed languages with the addition of Language::LANGCODE_NOT_SPECIFIED. - * This default can be altered by modules implementing - * hook_field_available_languages_alter(). - * - * The available language codes for a particular field are returned by - * field_available_languages(). Whether a field is translatable is determined by - * calling $field_definition->isTranslatable(). - * - * By default, field_invoke_method() processes a field in all available - * languages, unless it is given a language code suggestion. Based on that - * suggestion, _field_language_suggestion() determines the languages to act on. - * - * Most field_attach_*() functions act on all available language codes, except - * for the following: - * - field_attach_form() only takes a single language code, specifying which - * language the field values will be submitted in. - * - field_attach_view() requires the language the entity will be displayed in. - * Since it is unknown whether a field translation exists for the requested - * language, the translation handler is responsible for performing one of the - * following actions: - * - Ignore missing translations, i.e. do not show any field values for the - * requested language. For example, see field_field_language_alter(). - * - Provide a value in a different language as fallback. By default, the - * fallback logic is applied separately to each field to ensure that there - * is a value for each field to display. - * The field language fallback logic relies on the global language fallback - * configuration. Therefore, the displayed field values can be in the - * requested language, but may be different if no values for the requested - * language are available. The default language fallback rules inspect all the - * enabled languages ordered by their weight. This behavior can be altered or - * even disabled by modules implementing hook_field_language_alter(), making - * it possible to choose the first approach. The display language for each - * field is returned by field_language(). - * - * See @link field Field API @endlink for information about the other parts of - * the Field API. - */ - - -/** - * Collects the available language codes for the given entity type and field. - * - * If the given field has language support enabled, an array of available - * language codes will be returned, otherwise only Language::LANGCODE_DEFAULT - * will be returned. Since the default value for a 'translatable' entity - * property is FALSE, we ensure that only entities that are able to handle - * translations actually get translatable fields. - * - * @param $entity_type - * The type of the entity the field is attached to, e.g. 'node' or 'user'. - * @param $field - * A field structure. - * - * @return - * An array of valid language codes. - */ -function field_available_languages($entity_type, FieldInterface $field) { - static $drupal_static_fast; - if (!isset($drupal_static_fast)) { - $drupal_static_fast['field_langcodes'] = &drupal_static(__FUNCTION__); - } - $field_langcodes = &$drupal_static_fast['field_langcodes']; - $field_name = $field->getName(); - - if (!isset($field_langcodes[$entity_type][$field_name])) { - // If the field has language support enabled we retrieve an (alterable) list - // of enabled languages, otherwise we return Language::LANGCODE_DEFAULT. - if ($field->isTranslatable()) { - $langcodes = field_content_languages(); - // Let other modules alter the available languages. - $context = array('entity_type' => $entity_type, 'field' => $field); - drupal_alter('field_available_languages', $langcodes, $context); - $field_langcodes[$entity_type][$field_name] = $langcodes; - } - else { - $field_langcodes[$entity_type][$field_name] = array(Language::LANGCODE_DEFAULT); - } - } - - return $field_langcodes[$entity_type][$field_name]; -} - -/** - * Process the language code suggestion based on the available language codes. - * - * If a non-empty language code suggestion is provided it must appear among the - * available language codes, otherwise it will be ignored. - * - * @param $available_langcodes - * An array of valid language codes. - * @param $langcode_suggestion - * A language code or an array of language codes keyed by field name. - * @param $field_name - * The name of the field being processed. - * - * @return - * An array of valid language codes. - */ -function _field_language_suggestion($available_langcodes, $langcode_suggestion, $field_name) { - // Handle possible language suggestions. - if (!empty($langcode_suggestion)) { - // We might have an array of language suggestions keyed by field name. - if (is_array($langcode_suggestion) && isset($langcode_suggestion[$field_name])) { - $langcode_suggestion = $langcode_suggestion[$field_name]; - } - - // If we have a single language code suggestion and it is available, we just - // return it. - if (in_array($langcode_suggestion, $available_langcodes)) { - $available_langcodes = array($langcode_suggestion); - } - } - - return $available_langcodes; -} - -/** - * Returns available content language codes. - * - * @return - * An array of language codes. - */ -function field_content_languages() { - return array_keys(language_list(Language::STATE_ALL)); -} - -/** - * Checks if a module is registered as a translation handler for a given entity. - * - * If no handler is passed, the function simply checks if there is any - * translation handler enabled for the given entity type. - * - * @param $entity_type - * The type of the entity whose fields are to be translated. - * @param $handler - * (optional) The name of the handler to be checked. Defaults to NULL. - * - * @return - * TRUE, if the given handler is allowed to manage field translations. If no - * handler is passed, TRUE means there is at least one registered translation - * handler. - * - * @todo Remove this once the migration to the Entity Field API is complete. - */ -function field_has_translation_handler($entity_type, $handler = NULL) { - $info = entity_get_info($entity_type); - return !empty($info['translatable']); -} diff --git a/core/modules/field/lib/Drupal/field/Tests/TranslationTest.php b/core/modules/field/lib/Drupal/field/Tests/TranslationTest.php index c87802f92f04..b30625beda10 100644 --- a/core/modules/field/lib/Drupal/field/Tests/TranslationTest.php +++ b/core/modules/field/lib/Drupal/field/Tests/TranslationTest.php @@ -12,8 +12,7 @@ /** * Unit test class for the multilanguage fields logic. * - * The following tests will check the multilanguage logic in field handling, and - * that only the correct values are returned by field_available_languages(). + * The following tests will check the multilanguage logic in field handling. */ class TranslationTest extends FieldUnitTestBase { @@ -113,38 +112,6 @@ function setUp() { } } - /** - * Ensures that only valid values are returned by field_available_languages(). - */ - function testFieldAvailableLanguages() { - // Test 'translatable' fieldable info. - field_test_entity_info_translatable('entity_test', FALSE); - $field = clone($this->field); - $field->field_name .= '_untranslatable'; - $field->save(); - - // Enable field translations for the entity. - field_test_entity_info_translatable('entity_test', TRUE); - - // Test hook_field_languages() invocation on a translatable field. - \Drupal::state()->set('field_test.field_available_languages_alter', TRUE); - $langcodes = field_content_languages(); - $available_langcodes = field_available_languages($this->entity_type, $this->field); - foreach ($available_langcodes as $langcode) { - if ($langcode != 'xx' && $langcode != 'en') { - $this->assertTrue(in_array($langcode, $langcodes), format_string('%language is an enabled language.', array('%language' => $langcode))); - } - } - $this->assertTrue(in_array('xx', $available_langcodes), format_string('%language was made available.', array('%language' => 'xx'))); - $this->assertFalse(in_array('en', $available_langcodes), format_string('%language was made unavailable.', array('%language' => 'en'))); - - // Test field_available_languages() behavior for untranslatable fields. - $this->field->translatable = FALSE; - $this->field->save(); - $available_langcodes = field_available_languages($this->entity_type, $this->field); - $this->assertTrue(count($available_langcodes) == 1 && $available_langcodes[0] === Language::LANGCODE_DEFAULT, 'For untranslatable fields only Language::LANGCODE_DEFAULT is available.'); - } - /** * Test translatable fields storage/retrieval. */ @@ -159,8 +126,6 @@ function testTranslatableFieldSaveLoad() { field_test_entity_info_translatable($entity_type, TRUE); $entity = entity_create($entity_type, array('type' => $this->instance->bundle)); $field_translations = array(); - $available_langcodes = field_available_languages($entity_type, $this->field); - $this->assertTrue(count($available_langcodes) > 1, 'Field is translatable.'); $available_langcodes = array_keys(language_list()); $entity->langcode->value = reset($available_langcodes); foreach ($available_langcodes as $langcode) { diff --git a/core/modules/field/lib/Drupal/field/Tests/TranslationWebTest.php b/core/modules/field/lib/Drupal/field/Tests/TranslationWebTest.php index 349ee4c681db..4b2bb9587d38 100644 --- a/core/modules/field/lib/Drupal/field/Tests/TranslationWebTest.php +++ b/core/modules/field/lib/Drupal/field/Tests/TranslationWebTest.php @@ -103,9 +103,7 @@ function testFieldFormTranslationRevisions() { // Prepare the field translations. field_test_entity_info_translatable($this->entity_type, TRUE); $entity = entity_create($this->entity_type, array()); - $available_langcodes = array_flip(field_available_languages($this->entity_type, $this->field)); - unset($available_langcodes[Language::LANGCODE_NOT_SPECIFIED]); - unset($available_langcodes[Language::LANGCODE_NOT_APPLICABLE]); + $available_langcodes = array_flip(array_keys(language_list())); $field_name = $this->field->getName(); // Store the field translations. diff --git a/core/modules/field/tests/modules/field_test/field_test.entity.inc b/core/modules/field/tests/modules/field_test/field_test.entity.inc index 880636ebf6e5..a642b856241c 100644 --- a/core/modules/field/tests/modules/field_test/field_test.entity.inc +++ b/core/modules/field/tests/modules/field_test/field_test.entity.inc @@ -29,7 +29,6 @@ function field_test_entity_info_alter(&$entity_info) { * Helper function to enable entity translations. */ function field_test_entity_info_translatable($entity_type = NULL, $translatable = NULL) { - drupal_static_reset('field_has_translation_handler'); $stored_value = &drupal_static(__FUNCTION__, array()); if (isset($entity_type)) { $stored_value[$entity_type] = $translatable; diff --git a/core/modules/field/tests/modules/field_test/field_test.module b/core/modules/field/tests/modules/field_test/field_test.module index d1817c6bd43e..8215416b7873 100644 --- a/core/modules/field/tests/modules/field_test/field_test.module +++ b/core/modules/field/tests/modules/field_test/field_test.module @@ -49,19 +49,6 @@ function field_test_menu() { return $items; } -/** - * Implements hook_field_available_languages_alter(). - */ -function field_test_field_available_languages_alter(&$langcodes, $context) { - if (\Drupal::state()->get('field_test.field_available_languages_alter')) { - // Add an unavailable language code. - $langcodes[] = 'xx'; - // Remove an available language code. - $index = array_search('en', $langcodes); - unset($langcodes[$index]); - } -} - /** * Store and retrieve keyed data for later verification by unit tests. * diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityQueryTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityQueryTest.php index e0463f6bda84..f97a44f0d521 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityQueryTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityQueryTest.php @@ -126,8 +126,6 @@ function setUp() { 'name' => $this->randomString(), )); language_save($langcode); - $field_langcodes = &drupal_static('field_available_languages'); - $field_langcodes['entity_test_mulrev'][$greetings] = array('tr', 'pl'); // Calculate the cartesian product of the unit array by looking at the // bits of $i and add the unit at the bits that are 1. For example, // decimal 13 is binary 1101 so unit 3,2 and 0 will be added to the -- GitLab