Issue #2288123 by Berdir, dawehner: Fixed Basic authentication broken for non-english sites.
parent
4f978d9800
commit
2d6516afec
|
@ -121,6 +121,15 @@ abstract class CacheCollector implements CacheCollectorInterface, DestructableIn
|
|||
$this->lock = $lock;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the cache ID.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getCid() {
|
||||
return $this->cid;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -221,19 +230,20 @@ abstract class CacheCollector implements CacheCollectorInterface, DestructableIn
|
|||
}
|
||||
|
||||
// Lock cache writes to help avoid stampedes.
|
||||
$lock_name = $this->cid . ':' . __CLASS__;
|
||||
$cid = $this->getCid();
|
||||
$lock_name = $cid . ':' . __CLASS__;
|
||||
if (!$lock || $this->lock->acquire($lock_name)) {
|
||||
// Set and delete operations invalidate the cache item. Try to also load
|
||||
// an eventually invalidated cache entry, only update an invalidated cache
|
||||
// entry if the creation date did not change as this could result in an
|
||||
// inconsistent cache.
|
||||
if ($cache = $this->cache->get($this->cid, $this->cacheInvalidated)) {
|
||||
if ($cache = $this->cache->get($cid, $this->cacheInvalidated)) {
|
||||
if ($this->cacheInvalidated && $cache->created != $this->cacheCreated) {
|
||||
// We have invalidated the cache in this request and got a different
|
||||
// cache entry. Do not attempt to overwrite data that might have been
|
||||
// changed in a different request. We'll let the cache rebuild in
|
||||
// later requests.
|
||||
$this->cache->delete($this->cid);
|
||||
$this->cache->delete($cid);
|
||||
$this->lock->release($lock_name);
|
||||
return;
|
||||
}
|
||||
|
@ -243,7 +253,7 @@ abstract class CacheCollector implements CacheCollectorInterface, DestructableIn
|
|||
foreach ($this->keysToRemove as $delete_key) {
|
||||
unset($data[$delete_key]);
|
||||
}
|
||||
$this->cache->set($this->cid, $data, Cache::PERMANENT, $this->tags);
|
||||
$this->cache->set($cid, $data, Cache::PERMANENT, $this->tags);
|
||||
if ($lock) {
|
||||
$this->lock->release($lock_name);
|
||||
}
|
||||
|
@ -272,7 +282,7 @@ abstract class CacheCollector implements CacheCollectorInterface, DestructableIn
|
|||
Cache::deleteTags($this->tags);
|
||||
}
|
||||
else {
|
||||
$this->cache->delete($this->cid);
|
||||
$this->cache->delete($this->getCid());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -293,7 +303,7 @@ abstract class CacheCollector implements CacheCollectorInterface, DestructableIn
|
|||
// The cache was not yet loaded, set flag to TRUE.
|
||||
$this->cacheLoaded = TRUE;
|
||||
|
||||
if ($cache = $this->cache->get($this->cid)) {
|
||||
if ($cache = $this->cache->get($this->getCid())) {
|
||||
$this->cacheCreated = $cache->created;
|
||||
$this->storage = $cache->data;
|
||||
}
|
||||
|
@ -305,7 +315,7 @@ abstract class CacheCollector implements CacheCollectorInterface, DestructableIn
|
|||
protected function invalidateCache() {
|
||||
// Invalidate the cache to make sure that other requests immediately see the
|
||||
// deletion before this request is terminated.
|
||||
$this->cache->invalidate($this->cid);
|
||||
$this->cache->invalidate($this->getCid());
|
||||
$this->cacheInvalidated = TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
|
||||
namespace Drupal\Core\Entity\Annotation;
|
||||
use Drupal\Core\StringTranslation\TranslationWrapper;
|
||||
|
||||
/**
|
||||
* Defines a config entity type annotation object.
|
||||
|
@ -36,7 +37,7 @@ class ConfigEntityType extends EntityType {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function get() {
|
||||
$this->definition['group_label'] = $this->t('Configuration', array(), array('context' => 'Entity type group'));
|
||||
$this->definition['group_label'] = new TranslationWrapper('Configuration', array(), array('context' => 'Entity type group'));
|
||||
|
||||
return parent::get();
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
|
||||
namespace Drupal\Core\Entity\Annotation;
|
||||
use Drupal\Core\StringTranslation\TranslationWrapper;
|
||||
|
||||
/**
|
||||
* Defines a content entity type annotation object.
|
||||
|
@ -36,7 +37,7 @@ class ContentEntityType extends EntityType {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function get() {
|
||||
$this->definition['group_label'] = $this->t('Content', array(), array('context' => 'Entity type group'));
|
||||
$this->definition['group_label'] = new TranslationWrapper('Content', array(), array('context' => 'Entity type group'));
|
||||
|
||||
return parent::get();
|
||||
}
|
||||
|
|
|
@ -578,7 +578,7 @@ class EntityType implements EntityTypeInterface {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function getBundleLabel() {
|
||||
return $this->bundle_label;
|
||||
return (string) $this->bundle_label;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -635,7 +635,7 @@ class EntityType implements EntityTypeInterface {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function getLabel() {
|
||||
return $this->label;
|
||||
return (string) $this->label;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -672,7 +672,7 @@ class EntityType implements EntityTypeInterface {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function getGroupLabel() {
|
||||
return !empty($this->group_label) ? $this->group_label : $this->t('Other', array(), array('context' => 'Entity type group'));
|
||||
return !empty($this->group_label) ? (string) $this->group_label : $this->t('Other', array(), array('context' => 'Entity type group'));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ namespace Drupal\Core\Field\Plugin\Field\FieldType;
|
|||
|
||||
use Drupal\Core\Field\FieldStorageDefinitionInterface;
|
||||
use Drupal\Core\Field\FieldItemBase;
|
||||
use Drupal\Core\StringTranslation\TranslationWrapper;
|
||||
use Drupal\Core\TypedData\DataDefinition;
|
||||
|
||||
/**
|
||||
|
@ -38,8 +39,10 @@ class StringItem extends FieldItemBase {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
|
||||
// This is called very early by the user entity roles field. Prevent
|
||||
// early t() calls by using the TranslationWrapper.
|
||||
$properties['value'] = DataDefinition::create('string')
|
||||
->setLabel(t('Text value'));
|
||||
->setLabel(new TranslationWrapper('Text value'));
|
||||
|
||||
return $properties;
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ namespace Drupal\Core\Language;
|
|||
use Drupal\Component\Utility\String;
|
||||
use Drupal\Core\DependencyInjection\DependencySerializationTrait;
|
||||
use Drupal\Core\StringTranslation\TranslationInterface;
|
||||
use Drupal\Core\StringTranslation\TranslationWrapper;
|
||||
|
||||
/**
|
||||
* Class responsible for providing language support on language-unaware sites.
|
||||
|
@ -195,15 +196,17 @@ class LanguageManager implements LanguageManagerInterface {
|
|||
'default' => FALSE,
|
||||
'locked' => TRUE,
|
||||
);
|
||||
// This is called very early while initializing the language system. Prevent
|
||||
// early t() calls by using the TranslationWrapper.
|
||||
$languages[LanguageInterface::LANGCODE_NOT_SPECIFIED] = new Language(array(
|
||||
'id' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
|
||||
'name' => $this->t('Not specified'),
|
||||
'name' => new TranslationWrapper('Not specified'),
|
||||
'weight' => ++$weight,
|
||||
) + $locked_language);
|
||||
|
||||
$languages[LanguageInterface::LANGCODE_NOT_APPLICABLE] = new Language(array(
|
||||
'id' => LanguageInterface::LANGCODE_NOT_APPLICABLE,
|
||||
'name' => $this->t('Not applicable'),
|
||||
'name' => new TranslationWrapper('Not applicable'),
|
||||
'weight' => ++$weight,
|
||||
) + $locked_language);
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
namespace Drupal\basic_auth\Tests\Authentication;
|
||||
|
||||
use Drupal\Core\Language\Language;
|
||||
use Drupal\simpletest\WebTestBase;
|
||||
|
||||
/**
|
||||
|
@ -21,7 +22,7 @@ class BasicAuthTest extends WebTestBase {
|
|||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('basic_auth', 'router_test');
|
||||
public static $modules = array('basic_auth', 'router_test', 'locale');
|
||||
|
||||
/**
|
||||
* Test http basic authentication.
|
||||
|
@ -114,6 +115,21 @@ class BasicAuthTest extends WebTestBase {
|
|||
$this->assertResponse('200', 'Per user flood prevention does not block access for other users.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests compatibility with locale/UI translation.
|
||||
*/
|
||||
function testLocale() {
|
||||
$language = new Language(array('id' => 'de', 'default' => TRUE));
|
||||
language_save($language);
|
||||
|
||||
$account = $this->drupalCreateUser();
|
||||
|
||||
$this->basicAuthGet('router_test/test11', $account->getUsername(), $account->pass_raw);
|
||||
$this->assertText($account->getUsername(), 'Account name is displayed.');
|
||||
$this->assertResponse('200', 'HTTP response is OK');
|
||||
$this->curlClose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Does HTTP basic auth request.
|
||||
*
|
||||
|
|
|
@ -92,12 +92,34 @@ class LocaleLookup extends CacheCollector {
|
|||
$this->configFactory = $config_factory;
|
||||
$this->languageManager = $language_manager;
|
||||
|
||||
// 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(':', array_keys($user->getRoles())) : '0';
|
||||
parent::__construct("locale:$langcode:$context:$rids", $cache, $lock, array('locale' => TRUE));
|
||||
$this->cache = $cache;
|
||||
$this->lock = $lock;
|
||||
$this->tags = array('locale' => TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@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(':', array_keys($user->getRoles())) : '0';
|
||||
$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 = array();
|
||||
}
|
||||
return $this->cid;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -106,11 +106,7 @@ abstract class EntityLanguageTestBase extends EntityUnitTestBase {
|
|||
}
|
||||
|
||||
// Create the default languages.
|
||||
$default_language = language_save($this->languageManager->getDefaultLanguage());
|
||||
$languages = $this->languageManager->getDefaultLockedLanguages($default_language->weight);
|
||||
foreach ($languages as $language) {
|
||||
language_save($language);
|
||||
}
|
||||
$this->installConfig(array('language'));
|
||||
|
||||
// Create test languages.
|
||||
$this->langcodes = array();
|
||||
|
|
Loading…
Reference in New Issue