Chris@0: langcode = $langcode; Chris@0: $this->context = (string) $context; Chris@0: $this->stringStorage = $string_storage; Chris@0: $this->configFactory = $config_factory; Chris@0: $this->languageManager = $language_manager; Chris@0: Chris@0: $this->cache = $cache; Chris@0: $this->lock = $lock; Chris@0: $this->tags = ['locale']; Chris@0: $this->requestStack = $request_stack; Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: protected function getCid() { Chris@0: if (!isset($this->cid)) { Chris@0: // Add the current user's role IDs to the cache key, this ensures that, Chris@0: // for example, strings for admin menu items and settings forms are not Chris@0: // cached for anonymous users. Chris@0: $user = \Drupal::currentUser(); Chris@0: $rids = $user ? implode(':', $user->getRoles()) : ''; Chris@0: $this->cid = "locale:{$this->langcode}:{$this->context}:$rids"; Chris@0: Chris@0: // Getting the roles from the current user might have resulted in t() Chris@0: // calls that attempted to get translations from the locale cache. In that Chris@0: // case they would not go into this method again as Chris@0: // CacheCollector::lazyLoadCache() already set the loaded flag. They would Chris@0: // however call resolveCacheMiss() and add that string to the list of Chris@0: // cache misses that need to be written into the cache. Prevent that by Chris@0: // resetting that list. All that happens in such a case are a few uncached Chris@0: // translation lookups. Chris@0: $this->keysToPersist = []; Chris@0: } Chris@0: return $this->cid; Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: protected function resolveCacheMiss($offset) { Chris@0: $translation = $this->stringStorage->findTranslation([ Chris@0: 'language' => $this->langcode, Chris@0: 'source' => $offset, Chris@0: 'context' => $this->context, Chris@0: ]); Chris@0: Chris@0: if ($translation) { Chris@0: $value = !empty($translation->translation) ? $translation->translation : TRUE; Chris@0: } Chris@0: else { Chris@0: // We don't have the source string, update the {locales_source} table to Chris@0: // indicate the string is not translated. Chris@0: $this->stringStorage->createString([ Chris@0: 'source' => $offset, Chris@0: 'context' => $this->context, Chris@0: 'version' => \Drupal::VERSION, Chris@0: ])->addLocation('path', $this->requestStack->getCurrentRequest()->getRequestUri())->save(); Chris@0: $value = TRUE; Chris@0: } Chris@0: Chris@0: // If there is no translation available for the current language then use Chris@0: // language fallback to try other translations. Chris@0: if ($value === TRUE) { Chris@0: $fallbacks = $this->languageManager->getFallbackCandidates(['langcode' => $this->langcode, 'operation' => 'locale_lookup', 'data' => $offset]); Chris@0: if (!empty($fallbacks)) { Chris@0: foreach ($fallbacks as $langcode) { Chris@0: $translation = $this->stringStorage->findTranslation([ Chris@0: 'language' => $langcode, Chris@0: 'source' => $offset, Chris@0: 'context' => $this->context, Chris@0: ]); Chris@0: Chris@0: if ($translation && !empty($translation->translation)) { Chris@0: $value = $translation->translation; Chris@0: break; Chris@0: } Chris@0: } Chris@0: } Chris@0: } Chris@0: Chris@18: if (is_string($value) && strpos($value, PoItem::DELIMITER) !== FALSE) { Chris@12: // Community translations imported from localize.drupal.org as well as Chris@12: // migrated translations may contain @count[number]. Chris@12: $value = preg_replace('!@count\[\d+\]!', '@count', $value); Chris@12: } Chris@12: Chris@0: $this->storage[$offset] = $value; Chris@0: // Disabling the usage of string caching allows a module to watch for Chris@0: // the exact list of strings used on a page. From a performance Chris@0: // perspective that is a really bad idea, so we have no user Chris@0: // interface for this. Be careful when turning this option off! Chris@0: if ($this->configFactory->get('locale.settings')->get('cache_strings')) { Chris@0: $this->persist($offset); Chris@0: } Chris@0: return $value; Chris@0: } Chris@0: Chris@0: }