class LocaleLookup

Same name in other branches
  1. 9 core/modules/locale/src/LocaleLookup.php \Drupal\locale\LocaleLookup
  2. 10 core/modules/locale/src/LocaleLookup.php \Drupal\locale\LocaleLookup
  3. 11.x core/modules/locale/src/LocaleLookup.php \Drupal\locale\LocaleLookup

A cache collector to allow for dynamic building of the locale cache.

Hierarchy

Expanded class hierarchy of LocaleLookup

1 file declares its use of LocaleLookup
LocaleLookupTest.php in core/modules/locale/tests/src/Unit/LocaleLookupTest.php

File

core/modules/locale/src/LocaleLookup.php, line 16

Namespace

Drupal\locale
View source
class LocaleLookup extends CacheCollector {
    
    /**
     * A language code.
     *
     * @var string
     */
    protected $langcode;
    
    /**
     * The msgctxt context.
     *
     * @var string
     */
    protected $context;
    
    /**
     * The locale storage.
     *
     * @var \Drupal\locale\StringStorageInterface
     */
    protected $stringStorage;
    
    /**
     * The cache backend that should be used.
     *
     * @var \Drupal\Core\Cache\CacheBackendInterface
     */
    protected $cache;
    
    /**
     * The lock backend that should be used.
     *
     * @var \Drupal\Core\Lock\LockBackendInterface
     */
    protected $lock;
    
    /**
     * The configuration factory.
     *
     * @var \Drupal\Core\Config\ConfigFactoryInterface
     */
    protected $configFactory;
    
    /**
     * The language manager.
     *
     * @var \Drupal\Core\Language\LanguageManagerInterface
     */
    protected $languageManager;
    
    /**
     * The request stack.
     *
     * @var \Symfony\Component\HttpFoundation\RequestStack
     */
    protected $requestStack;
    
    /**
     * Constructs a LocaleLookup object.
     *
     * @param string $langcode
     *   The language code.
     * @param string $context
     *   The string context.
     * @param \Drupal\locale\StringStorageInterface $string_storage
     *   The string storage.
     * @param \Drupal\Core\Cache\CacheBackendInterface $cache
     *   The cache backend.
     * @param \Drupal\Core\Lock\LockBackendInterface $lock
     *   The lock backend.
     * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
     *   The config factory.
     * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
     *   The language manager.
     * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
     *   The request stack.
     */
    public function __construct($langcode, $context, StringStorageInterface $string_storage, CacheBackendInterface $cache, LockBackendInterface $lock, ConfigFactoryInterface $config_factory, LanguageManagerInterface $language_manager, RequestStack $request_stack) {
        $this->langcode = $langcode;
        $this->context = (string) $context;
        $this->stringStorage = $string_storage;
        $this->configFactory = $config_factory;
        $this->languageManager = $language_manager;
        $this->cache = $cache;
        $this->lock = $lock;
        $this->tags = [
            'locale',
        ];
        $this->requestStack = $request_stack;
    }
    
    /**
     * {@inheritdoc}
     */
    protected function getCid() {
        if (!isset($this->cid)) {
            // Add the current user's role IDs to the cache key, this ensures that,
            // for example, strings for admin menu items and settings forms are not
            // cached for anonymous users.
            $user = \Drupal::currentUser();
            $rids = $user ? implode(':', $user->getRoles()) : '';
            $this->cid = "locale:{$this->langcode}:{$this->context}:{$rids}";
            // Getting the roles from the current user might have resulted in t()
            // calls that attempted to get translations from the locale cache. In that
            // case they would not go into this method again as
            // CacheCollector::lazyLoadCache() already set the loaded flag. They would
            // however call resolveCacheMiss() and add that string to the list of
            // cache misses that need to be written into the cache. Prevent that by
            // resetting that list. All that happens in such a case are a few uncached
            // translation lookups.
            $this->keysToPersist = [];
        }
        return $this->cid;
    }
    
    /**
     * {@inheritdoc}
     */
    protected function resolveCacheMiss($offset) {
        $translation = $this->stringStorage
            ->findTranslation([
            '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([
                'source' => $offset,
                'context' => $this->context,
                'version' => \Drupal::VERSION,
            ])
                ->addLocation('path', $this->requestStack
                ->getCurrentRequest()
                ->getRequestUri())
                ->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([
                'langcode' => $this->langcode,
                'operation' => 'locale_lookup',
                'data' => $offset,
            ]);
            if (!empty($fallbacks)) {
                foreach ($fallbacks as $langcode) {
                    $translation = $this->stringStorage
                        ->findTranslation([
                        'language' => $langcode,
                        'source' => $offset,
                        'context' => $this->context,
                    ]);
                    if ($translation && !empty($translation->translation)) {
                        $value = $translation->translation;
                        break;
                    }
                }
            }
        }
        if (is_string($value) && strpos($value, PoItem::DELIMITER) !== FALSE) {
            // Community translations imported from localize.drupal.org as well as
            // migrated translations may contain @count[number].
            $value = preg_replace('!@count\\[\\d+\\]!', '@count', $value);
        }
        $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;
    }

}

Members

Title Sort descending Modifiers Object type Summary Overriden Title Overrides
CacheCollector::$cacheCreated protected property Stores the cache creation time.
CacheCollector::$cacheInvalidated protected property Flag that indicates of the cache has been invalidated.
CacheCollector::$cacheLoaded protected property Indicates if the collected cache was already loaded.
CacheCollector::$cid protected property The cache id that is used for the cache entry.
CacheCollector::$keysToPersist protected property An array of keys to add to the cache on service termination.
CacheCollector::$keysToRemove protected property An array of keys to remove from the cache on service termination.
CacheCollector::$storage protected property Storage for the data itself.
CacheCollector::$tags protected property A list of tags that are used for the cache entry.
CacheCollector::clear public function Clears the collected cache entry. Overrides CacheCollectorInterface::clear 1
CacheCollector::delete public function Deletes the element. Overrides CacheCollectorInterface::delete
CacheCollector::destruct public function Performs destruct operations. Overrides DestructableInterface::destruct
CacheCollector::get public function Gets value from the cache. Overrides CacheCollectorInterface::get 2
CacheCollector::has public function Returns whether data exists for this key. Overrides CacheCollectorInterface::has 1
CacheCollector::invalidateCache protected function Invalidate the cache.
CacheCollector::lazyLoadCache protected function Loads the cache if not already done. 1
CacheCollector::normalizeLockName protected function Normalizes a cache ID in order to comply with database limitations.
CacheCollector::persist protected function Flags an offset value to be written to the persistent cache.
CacheCollector::reset public function Resets the local cache. Overrides CacheCollectorInterface::reset 1
CacheCollector::set public function Implements \Drupal\Core\Cache\CacheCollectorInterface::set(). Overrides CacheCollectorInterface::set 1
CacheCollector::updateCache protected function Writes a value to the persistent cache immediately. 1
LocaleLookup::$cache protected property The cache backend that should be used. Overrides CacheCollector::$cache
LocaleLookup::$configFactory protected property The configuration factory.
LocaleLookup::$context protected property The msgctxt context.
LocaleLookup::$langcode protected property A language code.
LocaleLookup::$languageManager protected property The language manager.
LocaleLookup::$lock protected property The lock backend that should be used. Overrides CacheCollector::$lock
LocaleLookup::$requestStack protected property The request stack.
LocaleLookup::$stringStorage protected property The locale storage.
LocaleLookup::getCid protected function Gets the cache ID. Overrides CacheCollector::getCid
LocaleLookup::resolveCacheMiss protected function Resolves a cache miss. Overrides CacheCollector::resolveCacheMiss
LocaleLookup::__construct public function Constructs a LocaleLookup object. Overrides CacheCollector::__construct

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.