Commit f927e20b authored by catch's avatar catch

Issue #2753733 by alexpott, klausi: AccountProxy can do unnecessary user loads to get an ID

parent 08025b5e
......@@ -22,10 +22,19 @@ class AccountProxy implements AccountProxyInterface {
*/
protected $account;
/**
* Account id.
*
* @var int
*/
protected $id = 0;
/**
* Initial account id.
*
* @var int
*
* @deprecated Scheduled for removal in Drupal 8.4.x. Use $this->id instead.
*/
protected $initialAccountId;
......@@ -39,6 +48,7 @@ public function setAccount(AccountInterface $account) {
$account = $account->getAccount();
}
$this->account = $account;
$this->id = $account->id();
date_default_timezone_set(drupal_get_user_timezone());
}
......@@ -47,11 +57,11 @@ public function setAccount(AccountInterface $account) {
*/
public function getAccount() {
if (!isset($this->account)) {
if ($this->initialAccountId) {
if ($this->id) {
// After the container is rebuilt, DrupalKernel sets the initial
// account to the id of the logged in user. This is necessary in order
// to refresh the user account reference here.
$this->setAccount($this->loadUserEntity($this->initialAccountId));
$this->setAccount($this->loadUserEntity($this->id));
}
else {
$this->account = new AnonymousUserSession();
......@@ -65,7 +75,7 @@ public function getAccount() {
* {@inheritdoc}
*/
public function id() {
return $this->getAccount()->id();
return $this->id;
}
/**
......@@ -160,7 +170,7 @@ public function setInitialAccountId($account_id) {
throw new \LogicException('AccountProxyInterface::setInitialAccountId() cannot be called after an account was set on the AccountProxy');
}
$this->initialAccountId = $account_id;
$this->id = $this->initialAccountId = $account_id;
}
/**
......
<?php
namespace Drupal\Tests\Core\Session;
use Drupal\Core\Session\AccountInterface;
use Drupal\Tests\UnitTestCase;
use Drupal\Core\Session\AccountProxy;
/**
* @coversDefaultClass \Drupal\Core\Session\AccountProxy
* @group Session
*/
class AccountProxyTest extends UnitTestCase {
/**
* @covers ::id
* @covers ::setInitialAccountId
*/
public function testId() {
$account_proxy = new AccountProxy();
$this->assertSame(0, $account_proxy->id());
$account_proxy->setInitialAccountId(1);
$this->assertFalse(\Drupal::hasContainer());
// If the following call loaded the user entity it would call
// AccountProxy::loadUserEntity() which would fail because the container
// does not exist.
$this->assertSame(1, $account_proxy->id());
$current_user = $this->prophesize(AccountInterface::class);
$current_user->id()->willReturn(2);
$account_proxy->setAccount($current_user->reveal());
$this->assertSame(2, $account_proxy->id());
}
/**
* @covers ::setInitialAccountId
*/
public function testSetInitialAccountIdException() {
$this->setExpectedException(\LogicException::class);
$account_proxy = new AccountProxy();
$current_user = $this->prophesize(AccountInterface::class);
$account_proxy->setAccount($current_user->reveal());
$account_proxy->setInitialAccountId(1);
}
}
namespace Drupal\Core\Session;
if (!function_exists('drupal_get_user_timezone')) {
function drupal_get_user_timezone() {
return date_default_timezone_get();
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment