annotate core/modules/locale/src/LocaleLookup.php @ 0:4c8ae668cc8c

Initial import (non-working)
author Chris Cannam
date Wed, 29 Nov 2017 16:09:58 +0000
parents
children 7a779792577d
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 namespace Drupal\locale;
Chris@0 4
Chris@0 5 use Drupal\Core\Cache\CacheBackendInterface;
Chris@0 6 use Drupal\Core\Cache\CacheCollector;
Chris@0 7 use Drupal\Core\Config\ConfigFactoryInterface;
Chris@0 8 use Drupal\Core\Language\LanguageManagerInterface;
Chris@0 9 use Drupal\Core\Lock\LockBackendInterface;
Chris@0 10 use Symfony\Component\HttpFoundation\RequestStack;
Chris@0 11
Chris@0 12 /**
Chris@0 13 * A cache collector to allow for dynamic building of the locale cache.
Chris@0 14 */
Chris@0 15 class LocaleLookup extends CacheCollector {
Chris@0 16
Chris@0 17 /**
Chris@0 18 * A language code.
Chris@0 19 *
Chris@0 20 * @var string
Chris@0 21 */
Chris@0 22 protected $langcode;
Chris@0 23
Chris@0 24 /**
Chris@0 25 * The msgctxt context.
Chris@0 26 *
Chris@0 27 * @var string
Chris@0 28 */
Chris@0 29 protected $context;
Chris@0 30
Chris@0 31 /**
Chris@0 32 * The locale storage.
Chris@0 33 *
Chris@0 34 * @var \Drupal\locale\StringStorageInterface
Chris@0 35 */
Chris@0 36 protected $stringStorage;
Chris@0 37
Chris@0 38 /**
Chris@0 39 * The cache backend that should be used.
Chris@0 40 *
Chris@0 41 * @var \Drupal\Core\Cache\CacheBackendInterface
Chris@0 42 */
Chris@0 43 protected $cache;
Chris@0 44
Chris@0 45 /**
Chris@0 46 * The lock backend that should be used.
Chris@0 47 *
Chris@0 48 * @var \Drupal\Core\Lock\LockBackendInterface
Chris@0 49 */
Chris@0 50 protected $lock;
Chris@0 51
Chris@0 52 /**
Chris@0 53 * The configuration factory.
Chris@0 54 *
Chris@0 55 * @var \Drupal\Core\Config\ConfigFactoryInterface
Chris@0 56 */
Chris@0 57 protected $configFactory;
Chris@0 58
Chris@0 59 /**
Chris@0 60 * The language manager.
Chris@0 61 *
Chris@0 62 * @var \Drupal\Core\Language\LanguageManagerInterface
Chris@0 63 */
Chris@0 64 protected $languageManager;
Chris@0 65
Chris@0 66 /**
Chris@0 67 * The request stack.
Chris@0 68 *
Chris@0 69 * @var \Symfony\Component\HttpFoundation\RequestStack
Chris@0 70 */
Chris@0 71 protected $requestStack;
Chris@0 72
Chris@0 73 /**
Chris@0 74 * Constructs a LocaleLookup object.
Chris@0 75 *
Chris@0 76 * @param string $langcode
Chris@0 77 * The language code.
Chris@0 78 * @param string $context
Chris@0 79 * The string context.
Chris@0 80 * @param \Drupal\locale\StringStorageInterface $string_storage
Chris@0 81 * The string storage.
Chris@0 82 * @param \Drupal\Core\Cache\CacheBackendInterface $cache
Chris@0 83 * The cache backend.
Chris@0 84 * @param \Drupal\Core\Lock\LockBackendInterface $lock
Chris@0 85 * The lock backend.
Chris@0 86 * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
Chris@0 87 * The config factory.
Chris@0 88 * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
Chris@0 89 * The language manager.
Chris@0 90 * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
Chris@0 91 * The request stack.
Chris@0 92 */
Chris@0 93 public function __construct($langcode, $context, StringStorageInterface $string_storage, CacheBackendInterface $cache, LockBackendInterface $lock, ConfigFactoryInterface $config_factory, LanguageManagerInterface $language_manager, RequestStack $request_stack) {
Chris@0 94 $this->langcode = $langcode;
Chris@0 95 $this->context = (string) $context;
Chris@0 96 $this->stringStorage = $string_storage;
Chris@0 97 $this->configFactory = $config_factory;
Chris@0 98 $this->languageManager = $language_manager;
Chris@0 99
Chris@0 100 $this->cache = $cache;
Chris@0 101 $this->lock = $lock;
Chris@0 102 $this->tags = ['locale'];
Chris@0 103 $this->requestStack = $request_stack;
Chris@0 104 }
Chris@0 105
Chris@0 106 /**
Chris@0 107 * {@inheritdoc}
Chris@0 108 */
Chris@0 109 protected function getCid() {
Chris@0 110 if (!isset($this->cid)) {
Chris@0 111 // Add the current user's role IDs to the cache key, this ensures that,
Chris@0 112 // for example, strings for admin menu items and settings forms are not
Chris@0 113 // cached for anonymous users.
Chris@0 114 $user = \Drupal::currentUser();
Chris@0 115 $rids = $user ? implode(':', $user->getRoles()) : '';
Chris@0 116 $this->cid = "locale:{$this->langcode}:{$this->context}:$rids";
Chris@0 117
Chris@0 118 // Getting the roles from the current user might have resulted in t()
Chris@0 119 // calls that attempted to get translations from the locale cache. In that
Chris@0 120 // case they would not go into this method again as
Chris@0 121 // CacheCollector::lazyLoadCache() already set the loaded flag. They would
Chris@0 122 // however call resolveCacheMiss() and add that string to the list of
Chris@0 123 // cache misses that need to be written into the cache. Prevent that by
Chris@0 124 // resetting that list. All that happens in such a case are a few uncached
Chris@0 125 // translation lookups.
Chris@0 126 $this->keysToPersist = [];
Chris@0 127 }
Chris@0 128 return $this->cid;
Chris@0 129 }
Chris@0 130
Chris@0 131 /**
Chris@0 132 * {@inheritdoc}
Chris@0 133 */
Chris@0 134 protected function resolveCacheMiss($offset) {
Chris@0 135 $translation = $this->stringStorage->findTranslation([
Chris@0 136 'language' => $this->langcode,
Chris@0 137 'source' => $offset,
Chris@0 138 'context' => $this->context,
Chris@0 139 ]);
Chris@0 140
Chris@0 141 if ($translation) {
Chris@0 142 $value = !empty($translation->translation) ? $translation->translation : TRUE;
Chris@0 143 }
Chris@0 144 else {
Chris@0 145 // We don't have the source string, update the {locales_source} table to
Chris@0 146 // indicate the string is not translated.
Chris@0 147 $this->stringStorage->createString([
Chris@0 148 'source' => $offset,
Chris@0 149 'context' => $this->context,
Chris@0 150 'version' => \Drupal::VERSION,
Chris@0 151 ])->addLocation('path', $this->requestStack->getCurrentRequest()->getRequestUri())->save();
Chris@0 152 $value = TRUE;
Chris@0 153 }
Chris@0 154
Chris@0 155 // If there is no translation available for the current language then use
Chris@0 156 // language fallback to try other translations.
Chris@0 157 if ($value === TRUE) {
Chris@0 158 $fallbacks = $this->languageManager->getFallbackCandidates(['langcode' => $this->langcode, 'operation' => 'locale_lookup', 'data' => $offset]);
Chris@0 159 if (!empty($fallbacks)) {
Chris@0 160 foreach ($fallbacks as $langcode) {
Chris@0 161 $translation = $this->stringStorage->findTranslation([
Chris@0 162 'language' => $langcode,
Chris@0 163 'source' => $offset,
Chris@0 164 'context' => $this->context,
Chris@0 165 ]);
Chris@0 166
Chris@0 167 if ($translation && !empty($translation->translation)) {
Chris@0 168 $value = $translation->translation;
Chris@0 169 break;
Chris@0 170 }
Chris@0 171 }
Chris@0 172 }
Chris@0 173 }
Chris@0 174
Chris@0 175 $this->storage[$offset] = $value;
Chris@0 176 // Disabling the usage of string caching allows a module to watch for
Chris@0 177 // the exact list of strings used on a page. From a performance
Chris@0 178 // perspective that is a really bad idea, so we have no user
Chris@0 179 // interface for this. Be careful when turning this option off!
Chris@0 180 if ($this->configFactory->get('locale.settings')->get('cache_strings')) {
Chris@0 181 $this->persist($offset);
Chris@0 182 }
Chris@0 183 return $value;
Chris@0 184 }
Chris@0 185
Chris@0 186 }