/** * {@inheritdoc} */ public function getTranslationFromContext(EntityInterface $entity, $langcode = NULL, $context = array()) { $translation = $entity; if ($entity instanceof TranslatableInterface && count($entity->getTranslationLanguages()) > 1) { if (empty($langcode)) { $langcode = $this->languageManager->getCurrentLanguage(LanguageInterface::TYPE_CONTENT)->getId(); $entity->addCacheContexts(['languages:' . LanguageInterface::TYPE_CONTENT]); } // Retrieve language fallback candidates to perform the entity language // negotiation, unless the current translation is already the desired one. if ($entity->language()->getId() != $langcode) { $context['data'] = $entity; $context += array('operation' => 'entity_view', 'langcode' => $langcode); $candidates = $this->languageManager->getFallbackCandidates($context); // Ensure the default language has the proper language code. $default_language = $entity->getUntranslated()->language(); $candidates[$default_language->getId()] = LanguageInterface::LANGCODE_DEFAULT; // Return the most fitting entity translation. foreach ($candidates as $candidate) { if ($entity->hasTranslation($candidate)) { $translation = $entity->getTranslation($candidate); break; } } } } return $translation; }
/** * {@inheritdoc} */ protected function resolveCacheMiss($offset) { $translation = $this->stringStorage->findTranslation(array('language' => $this->langcode, 'source' => $offset, 'context' => $this->context)); if ($translation) { $value = !empty($translation->translation) ? $translation->translation : TRUE; } else { // We don't have the source string, update the {locales_source} table to // indicate the string is not translated. $this->stringStorage->createString(array('source' => $offset, 'context' => $this->context, 'version' => \Drupal::VERSION))->addLocation('path', $this->requestUri())->save(); $value = TRUE; } // If there is no translation available for the current language then use // language fallback to try other translations. if ($value === TRUE) { $fallbacks = $this->languageManager->getFallbackCandidates($this->langcode, array('operation' => 'locale_lookup', 'data' => $offset)); if (!empty($fallbacks)) { foreach ($fallbacks as $langcode) { $translation = $this->stringStorage->findTranslation(array('language' => $langcode, 'source' => $offset, 'context' => $this->context)); if ($translation && !empty($translation->translation)) { $value = $translation->translation; break; } } } } $this->storage[$offset] = $value; // Disabling the usage of string caching allows a module to watch for // the exact list of strings used on a page. From a performance // perspective that is a really bad idea, so we have no user // interface for this. Be careful when turning this option off! if ($this->configFactory->get('locale.settings')->get('cache_strings')) { $this->persist($offset); } return $value; }
/** * Tests the getTranslationFromContext() method. * * @covers ::getTranslationFromContext */ public function testGetTranslationFromContext() { $language = new Language(['id' => 'en']); $this->languageManager->getCurrentLanguage(LanguageInterface::TYPE_CONTENT)->willReturn($language)->shouldBeCalledTimes(1); $this->languageManager->getFallbackCandidates(Argument::type('array'))->will(function ($args) { $context = $args[0]; $candidates = array(); if (!empty($context['langcode'])) { $candidates[$context['langcode']] = $context['langcode']; } return $candidates; })->shouldBeCalledTimes(1); $translated_entity = $this->prophesize(ContentEntityInterface::class); $entity = $this->prophesize(ContentEntityInterface::class); $entity->getUntranslated()->willReturn($entity); $entity->language()->willReturn($language); $entity->hasTranslation(LanguageInterface::LANGCODE_DEFAULT)->willReturn(FALSE); $entity->hasTranslation('custom_langcode')->willReturn(TRUE); $entity->getTranslation('custom_langcode')->willReturn($translated_entity->reveal()); $entity->getTranslationLanguages()->willReturn([new Language(['id' => 'en']), new Language(['id' => 'custom_langcode'])]); $entity->addCacheContexts(['languages:language_content'])->shouldBeCalled(); $this->assertSame($entity->reveal(), $this->entityRepository->getTranslationFromContext($entity->reveal())); $this->assertSame($translated_entity->reveal(), $this->entityRepository->getTranslationFromContext($entity->reveal(), 'custom_langcode')); }
/** * {@inheritdoc} */ public function getTranslationFromContext(EntityInterface $entity, $langcode = NULL, $context = array()) { $translation = $entity; if ($entity instanceof TranslatableInterface) { if (empty($langcode)) { $langcode = $this->languageManager->getCurrentLanguage(LanguageInterface::TYPE_CONTENT)->id; } // Retrieve language fallback candidates to perform the entity language // negotiation. $context['data'] = $entity; $context += array('operation' => 'entity_view'); $candidates = $this->languageManager->getFallbackCandidates($langcode, $context); // Ensure the default language has the proper language code. $default_language = $entity->getUntranslated()->language(); $candidates[$default_language->id] = LanguageInterface::LANGCODE_DEFAULT; // Return the most fitting entity translation. foreach ($candidates as $candidate) { if ($entity->hasTranslation($candidate)) { $translation = $entity->getTranslation($candidate); break; } } } return $translation; }
/** * Called to add the field to a query. * * By default, all needed data is taken from entities loaded by the query * plugin. Columns are added only if they are used in groupings. */ public function query($use_groupby = FALSE) { $this->get_base_table(); $entity_type = $this->definition['entity_tables'][$this->base_table]; $fields = $this->additional_fields; // No need to add the entity type. $entity_type_key = array_search('entity_type', $fields); if ($entity_type_key !== FALSE) { unset($fields[$entity_type_key]); } $field_definition = $this->getFieldDefinition(); if ($use_groupby) { // Add the fields that we're actually grouping on. $options = array(); if ($this->options['group_column'] != 'entity_id') { $options = array($this->options['group_column'] => $this->options['group_column']); } $options += is_array($this->options['group_columns']) ? $this->options['group_columns'] : array(); $fields = array(); $rkey = $this->definition['is revision'] ? EntityStorageInterface::FIELD_LOAD_REVISION : EntityStorageInterface::FIELD_LOAD_CURRENT; // Go through the list and determine the actual column name from field api. foreach ($options as $column) { $name = $column; if (isset($field_definition['storage_details']['sql'][$rkey][$this->table][$column])) { $name = $field_definition['storage_details']['sql'][$rkey][$this->table][$column]; } $fields[$column] = $name; } $this->group_fields = $fields; } // Add additional fields (and the table join itself) if needed. if ($this->add_field_table($use_groupby)) { $this->ensureMyTable(); $this->addAdditionalFields($fields); // If we are grouping by something on this field, we want to group by // the displayed value, which is translated. So, we need to figure out // which language should be used to translate the value. See also // $this->field_langcode(). $field = $field_definition; if ($field->isTranslatable() && !empty($this->view->display_handler->options['field_langcode_add_to_query'])) { $column = $this->tableAlias . '.langcode'; $langcode = $this->view->display_handler->options['field_langcode']; $substitutions = static::queryLanguageSubstitutions(); if (isset($substitutions[$langcode])) { $langcode = $substitutions[$langcode]; } $placeholder = $this->placeholder(); $langcode_fallback_candidates = $this->languageManager->getFallbackCandidates(array('langcode' => $langcode, 'operation' => 'views_query', 'data' => $this)); $this->query->addWhereExpression(0, "{$column} IN({$placeholder}) OR {$column} IS NULL", array($placeholder => $langcode_fallback_candidates)); } } }