Commit b3695e87 authored by alexpott's avatar alexpott

Issue #1498664 by andypost, plach, penyaskito | dawehner: Refactor user entity...

Issue #1498664 by andypost, plach, penyaskito | dawehner: Refactor user entity properties to multilingual.
parent 80ba1c1b
......@@ -87,14 +87,14 @@ public function read($sid) {
// database.
if ($this->requestStack->getCurrentRequest()->isSecure()) {
// Try to load a session using the HTTPS-only secure session id.
$values = $this->connection->query("SELECT u.*, s.* FROM {users} u INNER JOIN {sessions} s ON u.uid = s.uid WHERE s.ssid = :ssid", array(
$values = $this->connection->query("SELECT u.*, s.* FROM {users_field_data} u INNER JOIN {sessions} s ON u.uid = s.uid WHERE u.default_langcode = 1 AND s.ssid = :ssid", array(
':ssid' => Crypt::hashBase64($sid),
))->fetchAssoc();
if (!$values) {
// Fallback and try to load the anonymous non-HTTPS session. Use the
// non-HTTPS session id as the key.
if ($cookies->has($insecure_session_name)) {
$values = $this->connection->query("SELECT u.*, s.* FROM {users} u INNER JOIN {sessions} s ON u.uid = s.uid WHERE s.sid = :sid AND s.uid = 0", array(
$values = $this->connection->query("SELECT u.*, s.* FROM {users_field_data} u INNER JOIN {sessions} s ON u.uid = s.uid WHERE u.default_langcode = 1 AND s.sid = :sid AND s.uid = 0", array(
':sid' => Crypt::hashBase64($cookies->get($insecure_session_name)),
))->fetchAssoc();
}
......@@ -102,7 +102,7 @@ public function read($sid) {
}
else {
// Try to load a session using the non-HTTPS session id.
$values = $this->connection->query("SELECT u.*, s.* FROM {users} u INNER JOIN {sessions} s ON u.uid = s.uid WHERE s.sid = :sid", array(
$values = $this->connection->query("SELECT u.*, s.* FROM {users_field_data} u INNER JOIN {sessions} s ON u.uid = s.uid WHERE u.default_langcode = 1 AND s.sid = :sid", array(
':sid' => Crypt::hashBase64($sid),
))->fetchAssoc();
}
......@@ -183,12 +183,9 @@ public function write($sid, $value) {
// Likewise, do not update access time more than once per 180 seconds.
if ($user->isAuthenticated() && REQUEST_TIME - $user->getLastAccessedTime() > Settings::get('session_write_interval', 180)) {
$this->connection->update('users')
->fields(array(
'access' => REQUEST_TIME,
))
->condition('uid', $user->id())
->execute();
/** @var \Drupal\user\UserStorageInterface $storage */
$storage = \Drupal::entityManager()->getStorage('user');
$storage->updateLastAccessTimestamp($user, REQUEST_TIME);
}
return TRUE;
}
......
......@@ -654,7 +654,7 @@ function comment_views_data_alter(&$data) {
'help' => t('Display nodes only if a user posted the @entity_type or commented on the @entity_type.', $args),
'argument' => array(
'field' => 'uid',
'name table' => 'users',
'name table' => 'users_field_data',
'name field' => 'name',
'id' => 'argument_comment_user_uid',
'no group by' => TRUE,
......@@ -663,7 +663,7 @@ function comment_views_data_alter(&$data) {
),
'filter' => array(
'field' => 'uid',
'name table' => 'users',
'name table' => 'users_field_data',
'name field' => 'name',
'id' => 'comment_user_uid',
'entity_type' => $entity_type_id,
......
......@@ -59,7 +59,7 @@ function title() {
$title = \Drupal::config('user.settings')->get('anonymous');
}
else {
$title = $this->database->query('SELECT u.name FROM {users} u WHERE u.uid = :uid', array(':uid' => $this->argument))->fetchField();
$title = $this->database->query('SELECT name FROM {users_field_data} WHERE uid = :uid AND default_langcode = 1', array(':uid' => $this->argument))->fetchField();
}
if (empty($title)) {
return t('No user');
......
......@@ -25,7 +25,7 @@ public function query() {
$this->ensureMyTable();
// join 'users' to this table via vid
$definition = array(
'table' => 'users',
'table' => 'users_field_data',
'field' => 'uid',
'left_table' => 'comment_entity_statistics',
'left_field' => 'last_comment_uid',
......
......@@ -22,7 +22,7 @@ class StatisticsLastCommentName extends SortPluginBase {
public function query() {
$this->ensureMyTable();
$definition = array(
'table' => 'users',
'table' => 'users_field_data',
'field' => 'uid',
'left_table' => 'comment_entity_statistics',
'left_field' => 'last_comment_uid',
......
......@@ -38,7 +38,7 @@ display:
fields:
name:
id: name
table: users
table: users_field_data
field: name
label: Username
link_to_user: true
......@@ -76,7 +76,7 @@ display:
sorts:
created:
id: created
table: users
table: users_field_data
field: created
order: DESC
plugin_id: date
......
......@@ -223,7 +223,7 @@ public function overview() {
*/
public function eventDetails($event_id) {
$build = array();
if ($dblog = $this->database->query('SELECT w.*, u.name, u.uid FROM {watchdog} w INNER JOIN {users} u ON w.uid = u.uid WHERE w.wid = :id', array(':id' => $event_id))->fetchObject()) {
if ($dblog = $this->database->query('SELECT w.*, u.name, u.uid FROM {watchdog} w INNER JOIN {users_field_data} u ON w.uid = u.uid WHERE w.wid = :id AND u.default_langcode = 1', array(':id' => $event_id))->fetchObject()) {
$severity = watchdog_severity_levels();
$message = $this->formatMessage($dblog);
$username = array(
......
......@@ -195,10 +195,10 @@ public function getTopics($tid, AccountInterface $account) {
$query->join('forum_index', 'f', 'f.nid = n.nid');
$query->addField('f', 'tid', 'forum_tid');
$query->join('users', 'u', 'n.uid = u.uid');
$query->join('users_field_data', 'u', 'n.uid = u.uid AND u.default_langcode = 1');
$query->addField('u', 'name');
$query->join('users', 'u2', 'ces.last_comment_uid = u2.uid');
$query->join('users_field_data', 'u2', 'ces.last_comment_uid = u2.uid AND u.default_langcode = 1');
$query->addExpression('CASE ces.last_comment_uid WHEN 0 THEN ces.last_comment_name ELSE u2.name END', 'last_comment_name');
......@@ -341,7 +341,7 @@ protected function getLastPost($tid) {
$query = $this->connection->select('node_field_data', 'n');
$query->join('forum', 'f', 'n.vid = f.vid AND f.tid = :tid', array(':tid' => $tid));
$query->join('comment_entity_statistics', 'ces', "n.nid = ces.entity_id AND ces.field_name = 'comment_forum' AND ces.entity_type = 'node'");
$query->join('users', 'u', 'ces.last_comment_uid = u.uid');
$query->join('users_field_data', 'u', 'ces.last_comment_uid = u.uid AND u.default_langcode = 1');
$query->addExpression('CASE ces.last_comment_uid WHEN 0 THEN ces.last_comment_name ELSE u.name END', 'last_comment_name');
$topic = $query
......
......@@ -194,7 +194,7 @@ display:
provider: node
name:
id: name
table: users
table: users_field_data
field: name
relationship: uid
label: Author
......
......@@ -210,7 +210,7 @@ display:
provider: history
name:
id: name
table: users
table: users_field_data
field: name
relationship: uid
group_type: group
......
......@@ -112,7 +112,7 @@ display:
provider: node
name:
id: name
table: users
table: users_field_data
field: name
label: Author
link_to_user: true
......
......@@ -83,13 +83,13 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta
$count = $this->connection->query("SELECT COUNT(*) FROM {users}")->fetchField();
$owner_name = '';
if (is_numeric($this->configuration['owner_uid'])) {
$owner_name = $this->connection->query("SELECT name FROM {users} WHERE uid = :uid", array(':uid' => $this->configuration['owner_uid']))->fetchField();
$owner_name = $this->connection->query("SELECT name FROM {users_field_data} WHERE uid = :uid AND default_langcode = 1", array(':uid' => $this->configuration['owner_uid']))->fetchField();
}
// Use dropdown for fewer than 200 users; textbox for more than that.
if (intval($count) < 200) {
$options = array();
$result = $this->connection->query("SELECT uid, name FROM {users} WHERE uid > 0 ORDER BY name");
$result = $this->connection->query("SELECT uid, name FROM {users_field_data} WHERE uid > 0 AND default_langcode = 1 ORDER BY name");
foreach ($result as $data) {
$options[$data->name] = $data->name;
}
......@@ -119,7 +119,7 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta
* {@inheritdoc}
*/
public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
$exists = (bool) $this->connection->queryRange('SELECT 1 FROM {users} WHERE name = :name', 0, 1, array(':name' => $form_state->getValue('owner_name')))->fetchField();
$exists = (bool) $this->connection->queryRange('SELECT 1 FROM {users_field_data} WHERE name = :name AND default_langcode = 1', 0, 1, array(':name' => $form_state->getValue('owner_name')))->fetchField();
if (!$exists) {
form_set_error('owner_name', $form_state, t('Enter a valid username.'));
}
......@@ -129,7 +129,7 @@ public function validateConfigurationForm(array &$form, FormStateInterface $form
* {@inheritdoc}
*/
public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
$this->configuration['owner_uid'] = $this->connection->query('SELECT uid from {users} WHERE name = :name', array(':name' => $form_state->getValue('owner_name')))->fetchField();
$this->configuration['owner_uid'] = $this->connection->query('SELECT uid from {users_field_data} WHERE name = :name AND default_langcode = 1', array(':name' => $form_state->getValue('owner_name')))->fetchField();
}
}
......@@ -722,7 +722,7 @@ protected function drupalUserIsLoggedIn($account) {
}
// The session ID is hashed before being stored in the database.
// @see \Drupal\Core\Session\SessionHandler::read()
return (bool) db_query("SELECT sid FROM {users} u INNER JOIN {sessions} s ON u.uid = s.uid WHERE s.sid = :sid", array(':sid' => Crypt::hashBase64($account->session_id)))->fetchField();
return (bool) db_query("SELECT sid FROM {users_field_data} u INNER JOIN {sessions} s ON u.uid = s.uid AND u.default_langcode = 1 WHERE s.sid = :sid", array(':sid' => Crypt::hashBase64($account->session_id)))->fetchField();
}
/**
......
......@@ -119,7 +119,7 @@ function statistics_title_list($dbfield, $dbrows) {
$query = db_select('node_field_data', 'n');
$query->addTag('node_access');
$query->join('node_counter', 's', 'n.nid = s.nid');
$query->join('users', 'u', 'n.uid = u.uid');
$query->join('users_field_data', 'u', 'n.uid = u.uid');
return $query
->fields('n', array('nid', 'title'))
......@@ -129,6 +129,7 @@ function statistics_title_list($dbfield, $dbrows) {
// @todo This should be actually filtering on the desired node status
// field language and just fall back to the default language.
->condition('n.default_langcode', 1)
->condition('u.default_langcode', 1)
->orderBy($dbfield, 'DESC')
->range(0, $dbrows)
->execute();
......
......@@ -51,7 +51,6 @@ public function __construct(SystemManager $systemManager) {
*/
public function status() {
$requirements = $this->systemManager->listRequirements();
$this->systemManager->fixAnonymousUid();
return array('#theme' => 'status_report', '#requirements' => $requirements);
}
......
......@@ -139,21 +139,6 @@ public function listRequirements() {
return $requirements;
}
/**
* Fixes anonymous user on MySQL.
*
* MySQL import might have set the uid of the anonymous user to autoincrement
* value. Let's try fixing it. See http://drupal.org/node/204411
*/
public function fixAnonymousUid() {
$this->database->update('users')
->expression('uid', 'uid - uid')
->condition('name', '')
->condition('pass', '')
->condition('status', 0)
->execute();
}
/**
* Extracts the highest severity from the requirements array.
*
......
......@@ -197,7 +197,7 @@ function testSessionWrite() {
$user = $this->drupalCreateUser(array());
$this->drupalLogin($user);
$sql = 'SELECT u.access, s.timestamp FROM {users} u INNER JOIN {sessions} s ON u.uid = s.uid WHERE u.uid = :uid';
$sql = 'SELECT u.access, s.timestamp FROM {users_field_data} u INNER JOIN {sessions} s ON u.uid = s.uid WHERE u.uid = :uid';
$times1 = db_query($sql, array(':uid' => $user->id()))->fetchObject();
// Before every request we sleep one second to make sure that if the session
......
......@@ -32,8 +32,9 @@ public function buildForm(array $form, FormStateInterface $form_state) {
'status' => array('data' => t('Status'), 'field' => 'u.status'),
);
$query = db_select('users', 'u');
$query = db_select('users_field_data', 'u');
$query->condition('u.uid', 0, '<>');
$query->condition('u.default_langcode', 1);
$count_query = clone $query;
$count_query->addExpression('COUNT(u.uid)');
......
......@@ -190,7 +190,7 @@ display:
provider: user
name:
id: name
table: users
table: users_field_data
field: name
relationship: none
group_type: group
......@@ -244,7 +244,7 @@ display:
provider: user
status:
id: status
table: users
table: users_field_data
field: status
relationship: none
group_type: group
......@@ -350,7 +350,7 @@ display:
provider: user
created:
id: created
table: users
table: users_field_data
field: created
relationship: none
group_type: group
......@@ -403,7 +403,7 @@ display:
provider: views
access:
id: access
table: users
table: users_field_data
field: access
relationship: none
group_type: group
......@@ -565,7 +565,7 @@ display:
plugin_id: dropbutton
mail:
id: mail
table: users
table: users_field_data
field: mail
relationship: none
group_type: group
......@@ -739,7 +739,7 @@ display:
provider: user
status:
id: status
table: users
table: users_field_data
field: status
relationship: none
group_type: group
......@@ -827,7 +827,7 @@ display:
sorts:
created:
id: created
table: users
table: users_field_data
field: created
relationship: none
group_type: group
......
......@@ -54,7 +54,7 @@ display:
fields:
name:
id: name
table: users
table: users_field_data
field: name
label: ''
plugin_id: user_name
......@@ -90,7 +90,7 @@ display:
filters:
status:
value: true
table: users
table: users_field_data
field: status
id: status
expose:
......@@ -99,7 +99,7 @@ display:
plugin_id: boolean
access:
id: access
table: users
table: users_field_data
field: access
relationship: none
group_type: group
......@@ -140,7 +140,7 @@ display:
sorts:
created:
id: created
table: users
table: users_field_data
field: created
relationship: none
group_type: group
......
......@@ -61,7 +61,7 @@ display:
fields:
name:
id: name
table: users
table: users_field_data
field: name
label: ''
plugin_id: user_name
......@@ -97,7 +97,7 @@ display:
filters:
status:
value: true
table: users
table: users_field_data
field: status
id: status
expose:
......@@ -106,7 +106,7 @@ display:
plugin_id: boolean
access:
id: access
table: users
table: users_field_data
field: access
relationship: none
group_type: group
......@@ -149,7 +149,7 @@ display:
sorts:
access:
id: access
table: users
table: users_field_data
field: access
order: DESC
relationship: none
......
......@@ -37,6 +37,7 @@
* },
* admin_permission = "administer user",
* base_table = "users",
* data_table = "users_field_data",
* label_callback = "user_format_name",
* fieldable = TRUE,
* translatable = TRUE,
......@@ -488,7 +489,8 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
// @todo Convert to a text field in https://drupal.org/node/1548204.
$fields['signature'] = BaseFieldDefinition::create('string')
->setLabel(t('Signature'))
->setDescription(t('The signature of this user.'));
->setDescription(t('The signature of this user.'))
->setTranslatable(TRUE);
$fields['signature_format'] = BaseFieldDefinition::create('string')
->setLabel(t('Signature format'))
->setDescription(t('The signature format of this user.'));
......
......@@ -113,9 +113,10 @@ public function execute() {
// Replace wildcards with MySQL/PostgreSQL wildcards.
$keys = preg_replace('!\*+!', '%', $keys);
$query = $this->database
->select('users')
->select('users_field_data', 'users')
->extend('Drupal\Core\Database\Query\PagerSelectExtender');
$query->fields('users', array('uid'));
$query->condition('default_langcode', 1);
if ($this->currentUser->hasPermission('administer users')) {
// Administrators can also search in the otherwise private email field, and
// they don't need to be restricted to only active users.
......
......@@ -106,7 +106,7 @@ public function entityQueryAlter(SelectInterface $query) {
// database.
$conditions = &$query->conditions();
foreach ($conditions as $key => $condition) {
if ($key !== '#conjunction' && is_string($condition['field']) && $condition['field'] === 'users.name') {
if ($key !== '#conjunction' && is_string($condition['field']) && $condition['field'] === 'users_field_data.name') {
// Remove the condition.
unset($conditions[$key]);
......@@ -125,7 +125,7 @@ public function entityQueryAlter(SelectInterface $query) {
$value_part->compile(Database::getConnection(), $query);
$or->condition(db_and()
->where(str_replace('anonymous_name', ':anonymous_name', (string) $value_part), $value_part->arguments() + array(':anonymous_name' => user_format_name(user_load(0))))
->condition('users.uid', 0)
->condition('base_table.uid', 0)
);
$query->condition($or);
}
......
......@@ -50,7 +50,7 @@ class Users extends WizardPluginBase {
protected $filters = array(
'status' => array(
'value' => TRUE,
'table' => 'users',
'table' => 'users_field_data',
'field' => 'status',
'provider' => 'user'
)
......@@ -72,7 +72,7 @@ protected function defaultDisplayOptions() {
/* Field: User: Name */
$display_options['fields']['name']['id'] = 'name';
$display_options['fields']['name']['table'] = 'users';
$display_options['fields']['name']['table'] = 'users_field_data';
$display_options['fields']['name']['field'] = 'name';
$display_options['fields']['name']['provider'] = 'user';
$display_options['fields']['name']['label'] = '';
......
......@@ -105,7 +105,7 @@ function testWhosOnlineBlock() {
* Updates the access column for a user.
*/
private function updateAccess($uid, $access = REQUEST_TIME) {
db_update('users')
db_update('users_field_data')
->condition('uid', $uid)
->fields(array('access' => $access))
->execute();
......
......@@ -78,7 +78,7 @@ function testUserCancelUid1() {
);
// We cannot use $account->save() here, because this would result in the
// password being hashed again.
db_update('users')
db_update('users_field_data')
->fields($account)
->condition('uid', 1)
->execute();
......
......@@ -38,8 +38,10 @@ protected function setUp() {
* Test that the initial users have correct values.
*/
public function testUserInstall() {
$anon = db_query('SELECT * FROM {users} WHERE uid = 0')->fetchObject();
$admin = db_query('SELECT * FROM {users} WHERE uid = 1')->fetchObject();
$result = db_query('SELECT u.uid, u.uuid, u.langcode, uf.status FROM {users} u INNER JOIN {users_field_data} uf ON u.uid=uf.uid ORDER BY u.uid')
->fetchAllAssoc('uid');
$anon = $result[0];
$admin = $result[1];
$this->assertFalse(empty($anon->uuid), 'Anon user has a UUID');
$this->assertFalse(empty($admin->uuid), 'Admin user has a UUID');
......
......@@ -37,7 +37,7 @@ public function setUp() {
// Set the last login time that is used to generate the one-time link so
// that it is definitely over a second ago.
$account->login = REQUEST_TIME - mt_rand(10, 100000);
db_update('users')
db_update('users_field_data')
->fields(array('login' => $account->getLastLoginTime()))
->condition('uid', $account->id())
->execute();
......
......@@ -33,21 +33,21 @@ public function testUserName() {
$view->row_index = 0;
$view->field['name']->options['link_to_user'] = TRUE;
$username = $view->result[0]->users_name = $this->randomMachineName();
$view->result[0]->uid = 1;
$username = $view->result[0]->users_field_data_name = $this->randomMachineName();
$view->result[0]->users_field_data_uid = 1;
$render = $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.');
$view->field['name']->options['link_to_user'] = FALSE;
$username = $view->result[0]->users_name = $this->randomMachineName();
$view->result[0]->uid = 1;
$username = $view->result[0]->users_field_data_name = $this->randomMachineName();
$view->result[0]->users_field_data_uid = 1;
$render = $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.');
$view->result[0]->uid = 0;
$view->result[0]->users_field_data_uid = 0;
$anon_name = \Drupal::config('user.settings')->get('anonymous');
$view->result[0]->users_name = '';
$view->result[0]->users_field_data_name = '';
$render = $view->field['name']->advancedRender($view->result[0]);
$this->assertIdentical($render, $anon_name , 'For user0 it should use the default anonymous name by default.');
......
......@@ -7,15 +7,15 @@
namespace Drupal\user;
use Drupal\Component\Uuid\UuidInterface;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Database\Connection;
use Drupal\Core\Entity\ContentEntityDatabaseStorage;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Password\PasswordInterface;
use Drupal\Core\Database\Connection;
use Drupal\Core\Session\AccountInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Entity\ContentEntityDatabaseStorage;
/**
* Controller class for users.
......@@ -146,7 +146,7 @@ public function deleteUserRoles(array $uids) {
* {@inheritdoc}
*/
public function updateLastLoginTimestamp(UserInterface $account) {
$this->database->update('users')
$this->database->update('users_field_data')
->fields(array('login' => $account->getLastLoginTime()))
->condition('uid', $account->id())
->execute();
......@@ -154,27 +154,42 @@ public function updateLastLoginTimestamp(UserInterface $account) {
$this->resetCache(array($account->id()));
}
/**
* {@inheritdoc}
*/
public function updateLastAccessTimestamp(AccountInterface $account, $timestamp) {
$this->database->update('users_field_data')
->fields(array(
'access' => $timestamp,
))
->condition('uid', $account->id())
->execute();
// Ensure that the entity cache is cleared.
$this->resetCache(array($account->id()));
}
/**
* {@inheritdoc}
*/
public function getSchema() {
$schema = parent::getSchema();
// The "users" table does not use serial identifiers.
$schema['users']['fields']['uid']['type'] = 'int';
// Marking the respective fields as NOT NULL makes the indexes more
// performant.
$schema['users']['fields']['access']['not null'] = TRUE;
$schema['users']['fields']['created']['not null'] = TRUE;
$schema['users']['fields']['name']['not null'] = TRUE;
$schema['users_field_data']['fields']['access']['not null'] = TRUE;
$schema['users_field_data']['fields']['created']['not null'] = TRUE;
$schema['users_field_data']['fields']['name']['not null'] = TRUE;
// The "users" table does not use serial identifiers.
$schema['users']['fields']['uid']['type'] = 'int';
$schema['users']['indexes'] += array(
$schema['users_field_data']['indexes'] += array(
'user__access' => array('access'),
'user__created' => array('created'),
'user__mail' => array('mail'),
);
$schema['users']['unique keys'] += array(
'user__name' => array('name'),
$schema['users_field_data']['unique keys'] += array(
'user__name' => array('name', 'langcode'),
);
$schema['users_roles'] = array(
......
......@@ -7,8 +7,7 @@
namespace Drupal\user;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Session\AccountInterface;
/**
* Defines a common interface for user entity controller classes.
......@@ -42,4 +41,15 @@ public function deleteUserRoles(array $uids);
* @param \Drupal\user\UserInterface $account
*/
public function updateLastLoginTimestamp(UserInterface $account);
/**
* Update the last access timestamp of the user.
*
* @param \Drupal\Core\Session\AccountInterface $account
* The user object.
* @param int $timestamp
* The last access timestamp.
*/
public function updateLastAccessTimestamp(AccountInterface $account, $timestamp);
}
......@@ -17,7 +17,7 @@ display:
name:
field: name
id: name
table: users
table: users_field_data
plugin_id: user_name
provider: user
nid:
......@@ -34,7 +34,7 @@ display:
field: status
group: '1'
id: status
table: users
table: users_field_data
value: '1'
plugin_id: boolean
provider: views
......@@ -68,7 +68,7 @@ display:
field: created
id: created
order: DESC
table: users
table: users_field_data
plugin_id: date
provider: views
style:
......