Update to Drupal 8.0.0 beta 14. For more information, see https://drupal.org/node/2544542
This commit is contained in:
parent
3b2511d96d
commit
81ccda77eb
2155 changed files with 54307 additions and 46870 deletions
78
core/modules/user/src/ContextProvider/CurrentUserContext.php
Normal file
78
core/modules/user/src/ContextProvider/CurrentUserContext.php
Normal file
|
@ -0,0 +1,78 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\user\ContextProvider\CurrentUserContext.
|
||||
*/
|
||||
|
||||
namespace Drupal\user\ContextProvider;
|
||||
|
||||
use Drupal\Core\Cache\CacheableMetadata;
|
||||
use Drupal\Core\Entity\EntityManagerInterface;
|
||||
use Drupal\Core\Plugin\Context\Context;
|
||||
use Drupal\Core\Plugin\Context\ContextDefinition;
|
||||
use Drupal\Core\Plugin\Context\ContextProviderInterface;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Drupal\Core\StringTranslation\StringTranslationTrait;
|
||||
|
||||
/**
|
||||
* Sets the current user as a context.
|
||||
*/
|
||||
class CurrentUserContext implements ContextProviderInterface {
|
||||
|
||||
use StringTranslationTrait;
|
||||
|
||||
/**
|
||||
* The current user.
|
||||
*
|
||||
* @var \Drupal\Core\Session\AccountInterface
|
||||
*/
|
||||
protected $account;
|
||||
|
||||
/**
|
||||
* The user storage.
|
||||
*
|
||||
* @var \Drupal\user\UserStorageInterface
|
||||
*/
|
||||
protected $userStorage;
|
||||
|
||||
/**
|
||||
* Constructs a new CurrentUserContext.
|
||||
*
|
||||
* @param \Drupal\Core\Session\AccountInterface $account
|
||||
* The current user.
|
||||
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
|
||||
* The entity manager.
|
||||
*/
|
||||
public function __construct(AccountInterface $account, EntityManagerInterface $entity_manager) {
|
||||
$this->account = $account;
|
||||
$this->userStorage = $entity_manager->getStorage('user');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getRuntimeContexts(array $unqualified_context_ids) {
|
||||
$current_user = $this->userStorage->load($this->account->id());
|
||||
|
||||
$context = new Context(new ContextDefinition('entity:user', $this->t('Current user')));
|
||||
$context->setContextValue($current_user);
|
||||
$cacheability = new CacheableMetadata();
|
||||
$cacheability->setCacheContexts(['user']);
|
||||
$context->addCacheableDependency($cacheability);
|
||||
|
||||
$result = [
|
||||
'current_user' => $context,
|
||||
];
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAvailableContexts() {
|
||||
return $this->getRuntimeContexts([]);
|
||||
}
|
||||
|
||||
}
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
namespace Drupal\user\Controller;
|
||||
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Component\Utility\Xss;
|
||||
use Drupal\Core\Controller\ControllerBase;
|
||||
use Drupal\Core\Datetime\DateFormatter;
|
||||
|
@ -123,7 +124,7 @@ class UserController extends ControllerBase {
|
|||
drupal_set_message($this->t('You have tried to use a one-time login link that has expired. Please request a new one using the form below.'), 'error');
|
||||
return $this->redirect('user.pass');
|
||||
}
|
||||
elseif ($user->isAuthenticated() && ($timestamp >= $user->getLastLoginTime()) && ($timestamp <= $current) && ($hash === user_pass_rehash($user->getPassword(), $timestamp, $user->getLastLoginTime(), $user->id()))) {
|
||||
elseif ($user->isAuthenticated() && ($timestamp >= $user->getLastLoginTime()) && ($timestamp <= $current) && ($hash === user_pass_rehash($user, $timestamp))) {
|
||||
$expiration_date = $user->getLastLoginTime() ? $this->dateFormatter->format($timestamp + $timeout) : NULL;
|
||||
return $this->formBuilder()->getForm('Drupal\user\Form\UserPasswordResetForm', $user, $expiration_date, $timestamp, $hash);
|
||||
}
|
||||
|
@ -161,7 +162,7 @@ class UserController extends ControllerBase {
|
|||
* The user account name.
|
||||
*/
|
||||
public function userTitle(UserInterface $user = NULL) {
|
||||
return $user ? Xss::filter($user->getUsername()) : '';
|
||||
return $user ? SafeMarkup::xssFilter($user->getUsername()) : '';
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -197,7 +198,7 @@ class UserController extends ControllerBase {
|
|||
$account_data = $this->userData->get('user', $user->id());
|
||||
if (isset($account_data['cancel_method']) && !empty($timestamp) && !empty($hashed_pass)) {
|
||||
// Validate expiration and hashed password/login.
|
||||
if ($timestamp <= $current && $current - $timestamp < $timeout && $user->id() && $timestamp >= $user->getLastLoginTime() && $hashed_pass == user_pass_rehash($user->getPassword(), $timestamp, $user->getLastLoginTime(), $user->id())) {
|
||||
if ($timestamp <= $current && $current - $timestamp < $timeout && $user->id() && $timestamp >= $user->getLastLoginTime() && $hashed_pass == user_pass_rehash($user, $timestamp)) {
|
||||
$edit = array(
|
||||
'user_cancel_notify' => isset($account_data['cancel_notify']) ? $account_data['cancel_notify'] : $this->config('user.settings')->get('notify.status_canceled'),
|
||||
);
|
||||
|
|
|
@ -79,7 +79,7 @@ class UserLoginBlock extends BlockBase implements ContainerFactoryPluginInterfac
|
|||
$route_name = $this->routeMatch->getRouteName();
|
||||
if ($account->isAnonymous() && !in_array($route_name, array('user.register', 'user.login', 'user.logout'))) {
|
||||
return AccessResult::allowed()
|
||||
->addCacheContexts(['route', 'user.roles:anonymous']);
|
||||
->addCacheContexts(['route.name', 'user.roles:anonymous']);
|
||||
}
|
||||
return AccessResult::forbidden();
|
||||
}
|
||||
|
|
|
@ -87,4 +87,17 @@ class UserRole extends ConditionPluginBase {
|
|||
return (bool) array_intersect($this->configuration['roles'], $user->getRoles());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCacheContexts() {
|
||||
// Optimize cache context, if a user cache context is provided, only use
|
||||
// user.roles, since that's the only part this condition cares about.
|
||||
$contexts = [];
|
||||
foreach (parent::getCacheContexts() as $context) {
|
||||
$contexts[] = $context == 'user' ? 'user.roles' : $context;
|
||||
}
|
||||
return $contexts;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ class RolesRid extends ManyToOne {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
|
||||
return parent::create($container, $configuration, $plugin_id, $plugin_definition, $container->get('entity.manager'));
|
||||
return new static($configuration, $plugin_id, $plugin_definition, $container->get('entity.manager'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
namespace Drupal\user;
|
||||
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface;
|
||||
use Drupal\Core\Lock\LockBackendInterface;
|
||||
use Drupal\Core\Session\AccountProxyInterface;
|
||||
|
@ -122,10 +121,7 @@ class PrivateTempStore {
|
|||
if (!$this->lockBackend->acquire($key)) {
|
||||
$this->lockBackend->wait($key);
|
||||
if (!$this->lockBackend->acquire($key)) {
|
||||
throw new TempStoreException(SafeMarkup::format("Couldn't acquire lock to update item %key in %collection temporary storage.", array(
|
||||
'%key' => $key,
|
||||
'%collection' => $this->storage->getCollectionName(),
|
||||
)));
|
||||
throw new TempStoreException("Couldn't acquire lock to update item '$key' in '{$this->storage->getCollectionName()}' temporary storage.");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -180,10 +176,7 @@ class PrivateTempStore {
|
|||
if (!$this->lockBackend->acquire($key)) {
|
||||
$this->lockBackend->wait($key);
|
||||
if (!$this->lockBackend->acquire($key)) {
|
||||
throw new TempStoreException(SafeMarkup::format("Couldn't acquire lock to delete item %key from %collection temporary storage.", array(
|
||||
'%key' => $key,
|
||||
'%collection' => $this->storage->getCollectionName(),
|
||||
)));
|
||||
throw new TempStoreException("Couldn't acquire lock to delete item '$key' from '{$this->storage->getCollectionName()}' temporary storage.");
|
||||
}
|
||||
}
|
||||
$this->storage->delete($key);
|
||||
|
|
|
@ -78,9 +78,9 @@ interface RoleInterface extends ConfigEntityInterface {
|
|||
* Sets the role to be an admin role.
|
||||
*
|
||||
* @param bool $is_admin
|
||||
* TRUE, if the role should be an admin role.
|
||||
* TRUE if the role should be an admin role.
|
||||
*
|
||||
* return $this
|
||||
* @return $this
|
||||
*/
|
||||
public function setIsAdmin($is_admin);
|
||||
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
namespace Drupal\user;
|
||||
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface;
|
||||
use Drupal\Core\Lock\LockBackendInterface;
|
||||
use Symfony\Component\HttpFoundation\RequestStack;
|
||||
|
@ -196,10 +195,7 @@ class SharedTempStore {
|
|||
if (!$this->lockBackend->acquire($key)) {
|
||||
$this->lockBackend->wait($key);
|
||||
if (!$this->lockBackend->acquire($key)) {
|
||||
throw new TempStoreException(SafeMarkup::format("Couldn't acquire lock to update item %key in %collection temporary storage.", array(
|
||||
'%key' => $key,
|
||||
'%collection' => $this->storage->getCollectionName(),
|
||||
)));
|
||||
throw new TempStoreException("Couldn't acquire lock to update item '$key' in '{$this->storage->getCollectionName()}' temporary storage.");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -242,10 +238,7 @@ class SharedTempStore {
|
|||
if (!$this->lockBackend->acquire($key)) {
|
||||
$this->lockBackend->wait($key);
|
||||
if (!$this->lockBackend->acquire($key)) {
|
||||
throw new TempStoreException(SafeMarkup::format("Couldn't acquire lock to delete item %key from %collection temporary storage.", array(
|
||||
'%key' => $key,
|
||||
'%collection' => $this->storage->getCollectionName(),
|
||||
)));
|
||||
throw new TempStoreException("Couldn't acquire lock to delete item '$key' from {$this->storage->getCollectionName()} temporary storage.");
|
||||
}
|
||||
}
|
||||
$this->storage->delete($key);
|
||||
|
|
|
@ -59,7 +59,7 @@ class UserCancelTest extends WebTestBase {
|
|||
|
||||
// Attempt bogus account cancellation request confirmation.
|
||||
$timestamp = $account->getLastLoginTime();
|
||||
$this->drupalGet("user/" . $account->id() . "/cancel/confirm/$timestamp/" . user_pass_rehash($account->getPassword(), $timestamp, $account->getLastLoginTime(), $account->id()));
|
||||
$this->drupalGet("user/" . $account->id() . "/cancel/confirm/$timestamp/" . user_pass_rehash($account, $timestamp));
|
||||
$this->assertResponse(403, 'Bogus cancelling request rejected.');
|
||||
$user_storage->resetCache(array($account->id()));
|
||||
$account = $user_storage->load($account->id());
|
||||
|
@ -165,7 +165,7 @@ class UserCancelTest extends WebTestBase {
|
|||
|
||||
// Attempt bogus account cancellation request confirmation.
|
||||
$bogus_timestamp = $timestamp + 60;
|
||||
$this->drupalGet("user/" . $account->id() . "/cancel/confirm/$bogus_timestamp/" . user_pass_rehash($account->getPassword(), $bogus_timestamp, $account->getLastLoginTime(), $account->id()));
|
||||
$this->drupalGet("user/" . $account->id() . "/cancel/confirm/$bogus_timestamp/" . user_pass_rehash($account, $bogus_timestamp));
|
||||
$this->assertText(t('You have tried to use an account cancellation link that has expired. Please request a new one using the form below.'), 'Bogus cancelling request rejected.');
|
||||
$user_storage->resetCache(array($account->id()));
|
||||
$account = $user_storage->load($account->id());
|
||||
|
@ -173,7 +173,7 @@ class UserCancelTest extends WebTestBase {
|
|||
|
||||
// Attempt expired account cancellation request confirmation.
|
||||
$bogus_timestamp = $timestamp - 86400 - 60;
|
||||
$this->drupalGet("user/" . $account->id() . "/cancel/confirm/$bogus_timestamp/" . user_pass_rehash($account->getPassword(), $bogus_timestamp, $account->getLastLoginTime(), $account->id()));
|
||||
$this->drupalGet("user/" . $account->id() . "/cancel/confirm/$bogus_timestamp/" . user_pass_rehash($account, $bogus_timestamp));
|
||||
$this->assertText(t('You have tried to use an account cancellation link that has expired. Please request a new one using the form below.'), 'Expired cancel account request rejected.');
|
||||
$user_storage->resetCache(array($account->id()));
|
||||
$account = $user_storage->load($account->id());
|
||||
|
@ -214,7 +214,7 @@ class UserCancelTest extends WebTestBase {
|
|||
$this->assertText(t('A confirmation request to cancel your account has been sent to your email address.'), 'Account cancellation request mailed message displayed.');
|
||||
|
||||
// Confirm account cancellation request.
|
||||
$this->drupalGet("user/" . $account->id() . "/cancel/confirm/$timestamp/" . user_pass_rehash($account->getPassword(), $timestamp, $account->getLastLoginTime(), $account->id()));
|
||||
$this->drupalGet("user/" . $account->id() . "/cancel/confirm/$timestamp/" . user_pass_rehash($account, $timestamp));
|
||||
$user_storage->resetCache(array($account->id()));
|
||||
$account = $user_storage->load($account->id());
|
||||
$this->assertTrue($account->isBlocked(), 'User has been blocked.');
|
||||
|
@ -272,7 +272,7 @@ class UserCancelTest extends WebTestBase {
|
|||
$this->assertText(t('A confirmation request to cancel your account has been sent to your email address.'), 'Account cancellation request mailed message displayed.');
|
||||
|
||||
// Confirm account cancellation request.
|
||||
$this->drupalGet("user/" . $account->id() . "/cancel/confirm/$timestamp/" . user_pass_rehash($account->getPassword(), $timestamp, $account->getLastLoginTime(), $account->id()));
|
||||
$this->drupalGet("user/" . $account->id() . "/cancel/confirm/$timestamp/" . user_pass_rehash($account, $timestamp));
|
||||
$user_storage->resetCache(array($account->id()));
|
||||
$account = $user_storage->load($account->id());
|
||||
$this->assertTrue($account->isBlocked(), 'User has been blocked.');
|
||||
|
@ -348,7 +348,7 @@ class UserCancelTest extends WebTestBase {
|
|||
$this->assertText(t('A confirmation request to cancel your account has been sent to your email address.'), 'Account cancellation request mailed message displayed.');
|
||||
|
||||
// Confirm account cancellation request.
|
||||
$this->drupalGet("user/" . $account->id() . "/cancel/confirm/$timestamp/" . user_pass_rehash($account->getPassword(), $timestamp, $account->getLastLoginTime(), $account->id()));
|
||||
$this->drupalGet("user/" . $account->id() . "/cancel/confirm/$timestamp/" . user_pass_rehash($account, $timestamp));
|
||||
$user_storage->resetCache(array($account->id()));
|
||||
$this->assertFalse($user_storage->load($account->id()), 'User is not found in the database.');
|
||||
|
||||
|
@ -427,7 +427,7 @@ class UserCancelTest extends WebTestBase {
|
|||
$this->assertText(t('A confirmation request to cancel your account has been sent to your email address.'), 'Account cancellation request mailed message displayed.');
|
||||
|
||||
// Confirm account cancellation request.
|
||||
$this->drupalGet("user/" . $account->id() . "/cancel/confirm/$timestamp/" . user_pass_rehash($account->getPassword(), $timestamp, $account->getLastLoginTime(), $account->id()));
|
||||
$this->drupalGet("user/" . $account->id() . "/cancel/confirm/$timestamp/" . user_pass_rehash($account, $timestamp));
|
||||
$user_storage->resetCache(array($account->id()));
|
||||
$this->assertFalse($user_storage->load($account->id()), 'User is not found in the database.');
|
||||
|
||||
|
|
|
@ -144,14 +144,14 @@ class UserPasswordResetTest extends PageCacheTagsTestBase {
|
|||
$timeout = $this->config('user.settings')->get('password_reset_timeout');
|
||||
$bogus_timestamp = REQUEST_TIME - $timeout - 60;
|
||||
$_uid = $this->account->id();
|
||||
$this->drupalGet("user/reset/$_uid/$bogus_timestamp/" . user_pass_rehash($this->account->getPassword(), $bogus_timestamp, $this->account->getLastLoginTime(), $this->account->id()));
|
||||
$this->drupalGet("user/reset/$_uid/$bogus_timestamp/" . user_pass_rehash($this->account, $bogus_timestamp));
|
||||
$this->assertText(t('You have tried to use a one-time login link that has expired. Please request a new one using the form below.'), 'Expired password reset request rejected.');
|
||||
|
||||
// Create a user, block the account, and verify that a login link is denied.
|
||||
$timestamp = REQUEST_TIME - 1;
|
||||
$blocked_account = $this->drupalCreateUser()->block();
|
||||
$blocked_account->save();
|
||||
$this->drupalGet("user/reset/" . $blocked_account->id() . "/$timestamp/" . user_pass_rehash($blocked_account->getPassword(), $timestamp, $blocked_account->getLastLoginTime(), $this->account->id()));
|
||||
$this->drupalGet("user/reset/" . $blocked_account->id() . "/$timestamp/" . user_pass_rehash($blocked_account, $timestamp));
|
||||
$this->assertResponse(403);
|
||||
|
||||
// Verify a blocked user can not request a new password.
|
||||
|
@ -162,6 +162,16 @@ class UserPasswordResetTest extends PageCacheTagsTestBase {
|
|||
$this->drupalPostForm(NULL, $edit, t('Submit'));
|
||||
$this->assertRaw(t('%name is blocked or has not been activated yet.', array('%name' => $blocked_account->getUsername())), 'Notified user blocked accounts can not request a new password');
|
||||
$this->assertTrue(count($this->drupalGetMails(array('id' => 'user_password_reset'))) === $before, 'No email was sent when requesting password reset for a blocked account');
|
||||
|
||||
// Verify a password reset link is invalidated when the user's email address changes.
|
||||
$this->drupalGet('user/password');
|
||||
$edit = array('name' => $this->account->getUsername());
|
||||
$this->drupalPostForm(NULL, $edit, t('Submit'));
|
||||
$old_email_reset_link = $this->getResetURL();
|
||||
$this->account->setEmail("1" . $this->account->getEmail());
|
||||
$this->account->save();
|
||||
$this->drupalGet($old_email_reset_link);
|
||||
$this->assertText(t('You have tried to use a one-time login link that has either been used or is no longer valid. Please request a new one using the form below.'), 'One-time link is no longer valid.');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
namespace Drupal\user\Tests;
|
||||
|
||||
use Drupal\simpletest\WebTestBase;
|
||||
use Drupal\file\Entity\File;
|
||||
|
||||
/**
|
||||
* Tests user picture functionality.
|
||||
|
@ -75,7 +76,7 @@ class UserPictureTest extends WebTestBase {
|
|||
\Drupal::service('cron')->run();
|
||||
|
||||
// Verify that the image has been deleted.
|
||||
$this->assertFalse(file_load($file->id(), TRUE), 'File was removed from the database.');
|
||||
$this->assertFalse(File::load($file->id()), 'File was removed from the database.');
|
||||
// Clear out PHP's file stat cache so we see the current value.
|
||||
clearstatcache(TRUE, $file->getFileUri());
|
||||
$this->assertFalse(is_file($file->getFileUri()), 'File was removed from the file system.');
|
||||
|
@ -133,6 +134,6 @@ class UserPictureTest extends WebTestBase {
|
|||
$user_storage = $this->container->get('entity.manager')->getStorage('user');
|
||||
$user_storage->resetCache(array($this->webUser->id()));
|
||||
$account = $user_storage->load($this->webUser->id());
|
||||
return file_load($account->user_picture->target_id, TRUE);
|
||||
return File::load($account->user_picture->target_id);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
namespace Drupal\user\Tests;
|
||||
|
||||
use Drupal\Core\Entity\Entity\EntityFormDisplay;
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Core\Field\FieldStorageDefinitionInterface;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
|
@ -264,6 +265,24 @@ class UserRegistrationTest extends WebTestBase {
|
|||
$this->assertEqual($new_user->init->value, $mail, 'Correct init field.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests username and email field constraints on user registration.
|
||||
*
|
||||
* @see \Drupal\user\Plugin\Validation\Constraint\UserNameUnique
|
||||
* @see \Drupal\user\Plugin\Validation\Constraint\UserMailUnique
|
||||
*/
|
||||
public function testUniqueFields() {
|
||||
$account = $this->drupalCreateUser();
|
||||
|
||||
$edit = ['mail' => 'test@example.com', 'name' => $account->getUsername()];
|
||||
$this->drupalPostForm('user/register', $edit, t('Create new account'));
|
||||
$this->assertRaw(SafeMarkup::format('The username %value is already taken.', ['%value' => $account->getUsername()]));
|
||||
|
||||
$edit = ['mail' => $account->getEmail(), 'name' => $this->randomString()];
|
||||
$this->drupalPostForm('user/register', $edit, t('Create new account'));
|
||||
$this->assertRaw(SafeMarkup::format('The email address %value is already taken.', ['%value' => $account->getEmail()]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests Field API fields on user registration forms.
|
||||
*/
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
namespace Drupal\user\Tests;
|
||||
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Core\Render\BubbleableMetadata;
|
||||
use Drupal\language\Entity\ConfigurableLanguage;
|
||||
use Drupal\simpletest\WebTestBase;
|
||||
use Drupal\user\Entity\User;
|
||||
|
@ -66,15 +67,58 @@ class UserTokenReplaceTest extends WebTestBase {
|
|||
$tests['[user:created:short]'] = format_date($account->getCreatedTime(), 'short', '', NULL, $language_interface->getId());
|
||||
$tests['[current-user:name]'] = SafeMarkup::checkPlain(user_format_name($global_account));
|
||||
|
||||
$base_bubbleable_metadata = BubbleableMetadata::createFromObject($account);
|
||||
$metadata_tests = [];
|
||||
$metadata_tests['[user:uid]'] = $base_bubbleable_metadata;
|
||||
$metadata_tests['[user:name]'] = $base_bubbleable_metadata;
|
||||
$metadata_tests['[user:mail]'] = $base_bubbleable_metadata;
|
||||
$metadata_tests['[user:url]'] = $base_bubbleable_metadata;
|
||||
$metadata_tests['[user:edit-url]'] = $base_bubbleable_metadata;
|
||||
$bubbleable_metadata = clone $base_bubbleable_metadata;
|
||||
// This test runs with the Language module enabled, which means config is
|
||||
// overridden by LanguageConfigFactoryOverride (to provide translations of
|
||||
// config). This causes the interface language cache context to be added for
|
||||
// config entities. The four next tokens use DateFormat Config entities, and
|
||||
// therefore have the interface language cache context.
|
||||
$bubbleable_metadata->addCacheContexts(['languages:language_interface']);
|
||||
$metadata_tests['[user:last-login]'] = $bubbleable_metadata->addCacheTags(['rendered']);
|
||||
$metadata_tests['[user:last-login:short]'] = $bubbleable_metadata;
|
||||
$metadata_tests['[user:created]'] = $bubbleable_metadata;
|
||||
$metadata_tests['[user:created:short]'] = $bubbleable_metadata;
|
||||
$metadata_tests['[current-user:name]'] = $base_bubbleable_metadata->merge(BubbleableMetadata::createFromObject($global_account)->addCacheContexts(['user']));
|
||||
|
||||
// Test to make sure that we generated something for each token.
|
||||
$this->assertFalse(in_array(0, array_map('strlen', $tests)), 'No empty tokens generated.');
|
||||
|
||||
foreach ($tests as $input => $expected) {
|
||||
$output = $token_service->replace($input, array('user' => $account), array('langcode' => $language_interface->getId()));
|
||||
$bubbleable_metadata = new BubbleableMetadata();
|
||||
$output = $token_service->replace($input, array('user' => $account), array('langcode' => $language_interface->getId()), $bubbleable_metadata);
|
||||
$this->assertEqual($output, $expected, format_string('Sanitized user token %token replaced.', array('%token' => $input)));
|
||||
$this->assertEqual($bubbleable_metadata, $metadata_tests[$input]);
|
||||
}
|
||||
|
||||
// Generate tokens for the anonymous user.
|
||||
$anonymous_user = User::load(0);
|
||||
$tests = [];
|
||||
$tests['[user:uid]'] = t('not yet assigned');
|
||||
$tests['[user:name]'] = SafeMarkup::checkPlain(user_format_name($anonymous_user));
|
||||
|
||||
$base_bubbleable_metadata = BubbleableMetadata::createFromObject($anonymous_user);
|
||||
$metadata_tests = [];
|
||||
$metadata_tests['[user:uid]'] = $base_bubbleable_metadata;
|
||||
$bubbleable_metadata = clone $base_bubbleable_metadata;
|
||||
$bubbleable_metadata->addCacheableDependency(\Drupal::config('user.settings'));
|
||||
$metadata_tests['[user:name]'] = $bubbleable_metadata;
|
||||
|
||||
foreach ($tests as $input => $expected) {
|
||||
$bubbleable_metadata = new BubbleableMetadata();
|
||||
$output = $token_service->replace($input, array('user' => $anonymous_user), array('langcode' => $language_interface->getId()), $bubbleable_metadata);
|
||||
$this->assertEqual($output, $expected, format_string('Sanitized user token %token replaced.', array('%token' => $input)));
|
||||
$this->assertEqual($bubbleable_metadata, $metadata_tests[$input]);
|
||||
}
|
||||
|
||||
// Generate and test unsanitized tokens.
|
||||
$tests = [];
|
||||
$tests['[user:name]'] = user_format_name($account);
|
||||
$tests['[user:mail]'] = $account->getEmail();
|
||||
$tests['[current-user:name]'] = user_format_name($global_account);
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
namespace Drupal\user\Tests\Views;
|
||||
|
||||
use Drupal\Core\Render\RenderContext;
|
||||
use Drupal\views\Views;
|
||||
|
||||
/**
|
||||
|
@ -25,6 +26,9 @@ class HandlerFieldUserNameTest extends UserTestBase {
|
|||
public static $testViews = array('test_views_handler_field_user_name');
|
||||
|
||||
public function testUserName() {
|
||||
/** @var \Drupal\Core\Render\RendererInterface $renderer */
|
||||
$renderer = \Drupal::service('renderer');
|
||||
|
||||
$this->drupalLogin($this->drupalCreateUser(array('access user profiles')));
|
||||
|
||||
// Set defaults.
|
||||
|
@ -37,13 +41,17 @@ class HandlerFieldUserNameTest extends UserTestBase {
|
|||
$this->executeView($view);
|
||||
|
||||
$anon_name = $this->config('user.settings')->get('anonymous');
|
||||
$render = $view->field['name']->advancedRender($view->result[0]);
|
||||
$render = $renderer->executeInRenderContext(new RenderContext(), function () use ($view) {
|
||||
return $view->field['name']->advancedRender($view->result[0]);
|
||||
});
|
||||
$this->assertTrue(strpos($render, $anon_name) !== FALSE, 'For user 0 it should use the default anonymous name by default.');
|
||||
|
||||
$username = $this->randomMachineName();
|
||||
$view->result[0]->_entity->setUsername($username);
|
||||
$view->result[0]->_entity->uid->value = 1;
|
||||
$render = $view->field['name']->advancedRender($view->result[0]);
|
||||
$render = $renderer->executeInRenderContext(new RenderContext(), function () use ($view) {
|
||||
return $view->field['name']->advancedRender($view->result[0]);
|
||||
});
|
||||
$this->assertTrue(strpos($render, $username) !== FALSE, 'If link to user is checked the username should be part of the output.');
|
||||
$this->assertTrue(strpos($render, 'user/1') !== FALSE, 'If link to user is checked the link to the user should appear as well.');
|
||||
|
||||
|
@ -52,7 +60,9 @@ class HandlerFieldUserNameTest extends UserTestBase {
|
|||
$username = $this->randomMachineName();
|
||||
$view->result[0]->_entity->setUsername($username);
|
||||
$view->result[0]->_entity->uid->value = 1;
|
||||
$render = $view->field['name']->advancedRender($view->result[0]);
|
||||
$render = $renderer->executeInRenderContext(new RenderContext(), function () use ($view) {
|
||||
return $view->field['name']->advancedRender($view->result[0]);
|
||||
});
|
||||
$this->assertIdentical($render, $username, 'If the user is not linked the username should be printed out for a normal user.');
|
||||
|
||||
}
|
||||
|
@ -61,13 +71,18 @@ class HandlerFieldUserNameTest extends UserTestBase {
|
|||
* Tests that the field handler works when no additional fields are added.
|
||||
*/
|
||||
public function testNoAdditionalFields() {
|
||||
/** @var \Drupal\Core\Render\RendererInterface $renderer */
|
||||
$renderer = \Drupal::service('renderer');
|
||||
|
||||
$view = Views::getView('test_views_handler_field_user_name');
|
||||
$this->executeView($view);
|
||||
|
||||
$username = $this->randomMachineName();
|
||||
$view->result[0]->_entity->setUsername($username);
|
||||
$view->result[0]->_entity->uid->value = 1;
|
||||
$render = $view->field['name']->advancedRender($view->result[0]);
|
||||
$render = $renderer->executeInRenderContext(new RenderContext(), function () use ($view) {
|
||||
return $view->field['name']->advancedRender($view->result[0]);
|
||||
});
|
||||
$this->assertTrue(strpos($render, $username) !== FALSE, 'If link to user is checked the username should be part of the output.');
|
||||
}
|
||||
|
||||
|
|
|
@ -80,8 +80,11 @@ class UserAccessControlHandler extends EntityAccessControlHandler {
|
|||
$is_own_account = $items ? $items->getEntity()->id() == $account->id() : FALSE;
|
||||
switch ($field_definition->getName()) {
|
||||
case 'name':
|
||||
// Allow view access to anyone with access to the entity.
|
||||
if ($operation == 'view') {
|
||||
// Allow view access to anyone with access to the entity. Anonymous
|
||||
// users should be able to access the username field during the
|
||||
// registration process, otherwise the username and email constraints
|
||||
// are not checked.
|
||||
if ($operation == 'view' || ($items && $account->isAnonymous() && $items->getEntity()->isAnonymous())) {
|
||||
return AccessResult::allowed()->cachePerPermissions();
|
||||
}
|
||||
// Allow edit access for the own user name if the permission is
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace Drupal\user;
|
|||
|
||||
use Drupal\Core\Database\Connection;
|
||||
use Drupal\Core\Cache\CacheBackendInterface;
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
use Drupal\Core\Entity\ContentEntityInterface;
|
||||
use Drupal\Core\Entity\EntityManagerInterface;
|
||||
use Drupal\Core\Entity\EntityTypeInterface;
|
||||
use Drupal\Core\Entity\Sql\SqlContentEntityStorage;
|
||||
|
@ -72,14 +72,14 @@ class UserStorage extends SqlContentEntityStorage implements UserStorageInterfac
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function save(EntityInterface $entity) {
|
||||
protected function doSaveFieldItems(ContentEntityInterface $entity, array $names = []) {
|
||||
// The anonymous user account is saved with the fixed user ID of 0.
|
||||
// Therefore we need to check for NULL explicitly.
|
||||
if ($entity->id() === NULL) {
|
||||
$entity->uid->value = $this->database->nextId($this->database->query('SELECT MAX(uid) FROM {users}')->fetchField());
|
||||
$entity->enforceIsNew();
|
||||
}
|
||||
return parent::save($entity);
|
||||
return parent::doSaveFieldItems($entity, $names);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Reference in a new issue