Commit fcbb3c0c authored by alexpott's avatar alexpott

Issue #2458817 by Berdir, dawehner: Creating new user entities for anonymous users is very slow

parent a9c270f2
......@@ -631,31 +631,6 @@ function comment_preprocess_block(&$variables) {
}
}
/**
* Prepares a user account object for rendering comment authors.
*
* This helper handles anonymous authors in addition to registered comment
* authors.
*
* @param \Drupal\comment\CommentInterface $comment
* The comment to which the author replied.
*
* @return \Drupal\user\UserInterface
* A user account, for use with theme_username() or the user_picture template.
*/
function comment_prepare_author(CommentInterface $comment) {
// The account has been pre-loaded by CommentViewBuilder::buildComponents().
$account = $comment->getOwner();
if (empty($account->uid->value)) {
// @todo Avoid creating a new entity by just creating a new instance
// directly, see https://drupal.org/node/1867228.
$account = entity_create('user', array('uid' => 0, 'name' => $comment->getAuthorName(), 'homepage' => $comment->getHomepage()));
// The anonymous user is not a new account, do not treat it as one.
$account->enforceIsNew(FALSE);
}
return $account;
}
/**
* Prepares variables for comment templates.
*
......@@ -673,7 +648,7 @@ function template_preprocess_comment(&$variables) {
$variables['comment'] = $comment;
$variables['commented_entity'] = $commented_entity;
$account = comment_prepare_author($comment);
$account = $comment->getOwner();
$username = array(
'#theme' => 'username',
'#account' => $account,
......@@ -718,7 +693,7 @@ function template_preprocess_comment(&$variables) {
if ($comment->hasParentComment()) {
// Fetch and store the parent comment information for use in templates.
$comment_parent = $comment->getParentComment();
$account_parent = comment_prepare_author($comment_parent);
$account_parent = $comment_parent->getOwner();
$variables['parent_comment'] = $comment_parent;
$username = array(
'#theme' => 'username',
......
......@@ -14,6 +14,7 @@
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\user\Entity\User;
use Drupal\user\UserInterface;
/**
......@@ -534,7 +535,13 @@ public static function preCreate(EntityStorageInterface $storage, array &$values
* {@inheritdoc}
*/
public function getOwner() {
return $this->get('uid')->entity;
$user = $this->get('uid')->entity;
if (!$user || $user->isAnonymous()) {
$user = clone User::getAnonymousUser();
$user->name = $this->getAuthorName();
$user->homepage = $this->getHomepage();
}
return $user;
}
/**
......
......@@ -185,7 +185,7 @@ public function buildForm(array $form, FormStateInterface $form_state, $type = '
$commented_entity = $commented_entities[$comment->getCommentedEntityTypeId()][$comment->getCommentedEntityId()];
$username = array(
'#theme' => 'username',
'#account' => comment_prepare_author($comment),
'#account' => $comment->getOwner(),
);
$body = '';
if (!empty($comment->comment_body->value)) {
......
......@@ -11,6 +11,7 @@
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityViewBuilder;
use Drupal\node\Entity\Node;
use Drupal\user\Entity\User;
/**
* Render controller for nodes.
......@@ -26,9 +27,6 @@ public function buildComponents(array &$build, array $entities, array $displays,
return;
}
// Attach user account.
user_attach_accounts($build, $entities);
parent::buildComponents($build, $entities, $displays, $view_mode, $langcode);
foreach ($entities as $id => $entity) {
......
......@@ -62,6 +62,13 @@
*/
class User extends ContentEntityBase implements UserInterface {
/**
* Stores a reference for a reusable anonymous user entity.
*
* @var \Drupal\user\UserInterface
*/
protected static $anonymousUser;
/**
* The hostname for this user.
*
......@@ -424,6 +431,26 @@ public function checkExistingPassword(UserInterface $account_unchanged) {
return !empty($this->get('pass')->existing) && \Drupal::service('password')->check(trim($this->get('pass')->existing), $account_unchanged);
}
/**
* Returns an anonymous user entity.
*
* @return \Drupal\user\UserInterface
* An anonymous user entity.
*/
public static function getAnonymousUser() {
if (!isset(static::$anonymousUser)) {
// @todo Use the entity factory once available, see
// https://www.drupal.org/node/1867228.
$entity_manager = \Drupal::entityManager();
$entity_type = $entity_manager->getDefinition('user');
$class = $entity_type->getClass();
static::$anonymousUser = new $class(['uid' => [LanguageInterface::LANGCODE_DEFAULT => 0]], $entity_type->id());
}
return static::$anonymousUser;
}
/**
* {@inheritdoc}
*/
......
......@@ -9,7 +9,7 @@
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\FormatterBase;
use Drupal\Core\Field\Plugin\Field\FieldFormatter\EntityReferenceFormatterBase;
/**
* Plugin implementation of the 'author' formatter.
......@@ -23,7 +23,7 @@
* }
* )
*/
class AuthorFormatter extends FormatterBase {
class AuthorFormatter extends EntityReferenceFormatterBase {
/**
* {@inheritdoc}
......
......@@ -116,36 +116,6 @@ function user_js_settings_alter(&$settings, AttachedAssetsInterface $assets) {
$settings['user']['permissionsHash'] = \Drupal::service('user_permissions_hash_generator')->generate($user);
}
/**
* Populates $entity->account for each prepared entity.
*
* Called by Drupal\Core\Entity\EntityViewBuilderInterface::buildComponents()
* implementations.
*
* @param array &$build
* A renderable array representing the entity content.
* @param \Drupal\user\EntityOwnerInterface[] $entities
* The entities keyed by entity ID.
*/
function user_attach_accounts(array &$build, array $entities) {
$uids = array();
foreach ($entities as $entity) {
$uids[] = $entity->getOwnerId();
}
$uids = array_unique($uids);
$accounts = user_load_multiple($uids);
$anonymous = entity_create('user', array('uid' => 0));
foreach ($entities as $id => $entity) {
if (isset($accounts[$entity->getOwnerId()])) {
$entities[$id]->setOwner($accounts[$entity->getOwnerId()]);
}
else {
$entities[$id]->setOwner($anonymous);
}
}
}
/**
* Returns whether this site supports the default user picture feature.
*
......
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