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

8.0.x
Alex Pott 2015-04-07 12:39:10 +01:00
parent 804b2c9ffc
commit 3ab0ef9bb8
7 changed files with 41 additions and 64 deletions

View File

@ -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',

View File

@ -14,6 +14,7 @@ use Drupal\Core\Entity\EntityStorageInterface;
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 @@ class Comment extends ContentEntityBase implements CommentInterface {
* {@inheritdoc}
*/
public function getOwner() {
return $this->get('uid')->entity;
$user = $this->get('uid')->entity;
if (!$user || $user->isAnonymous()) {
$user = User::getAnonymousUser();
$user->name = $this->getAuthorName();
$user->homepage = $this->getHomepage();
}
return $user;
}
/**

View File

@ -185,7 +185,7 @@ class CommentAdminOverview extends FormBase {
$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)) {

View File

@ -11,6 +11,7 @@ use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
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 @@ class NodeViewBuilder extends EntityViewBuilder {
return;
}
// Attach user account.
user_attach_accounts($build, $entities);
parent::buildComponents($build, $entities, $displays, $view_mode, $langcode);
foreach ($entities as $id => $entity) {

View File

@ -62,6 +62,13 @@ use Drupal\user\UserInterface;
*/
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 @@ class User extends ContentEntityBase implements UserInterface {
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 clone static::$anonymousUser;
}
/**
* {@inheritdoc}
*/

View File

@ -9,7 +9,7 @@ namespace Drupal\user\Plugin\Field\FieldFormatter;
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 @@ use Drupal\Core\Field\FormatterBase;
* }
* )
*/
class AuthorFormatter extends FormatterBase {
class AuthorFormatter extends EntityReferenceFormatterBase {
/**
* {@inheritdoc}

View File

@ -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.
*