Commit 1893614c authored by alexpott's avatar alexpott

Issue #2454145 by kgoel, dawehner, adamwhite, rteijeiro, wwhurley: Replace...

Issue #2454145 by kgoel, dawehner, adamwhite, rteijeiro, wwhurley: Replace user_name handler with Field API formatter
parent 8ad93870
......@@ -83,8 +83,6 @@ display:
html: false
hide_empty: false
empty_zero: false
link_to_user: true
overwrite_anonymous: false
relationship: none
group_type: group
admin_label: ''
......@@ -99,9 +97,8 @@ display:
element_default_classes: true
empty: ''
hide_alter_empty: true
anonymous_text: ''
format_username: true
plugin_id: user_name
plugin_id: field
type: user_name
entity_type: user
entity_field: name
contact:
......
......@@ -50,9 +50,8 @@ display:
table: users_field_data
field: name
label: Username
link_to_user: true
format_username: true
plugin_id: user_name
plugin_id: field
type: user_name
entity_type: user
entity_field: name
translation_link:
......
......@@ -254,11 +254,8 @@ display:
hide_empty: false
empty_zero: false
hide_alter_empty: true
link_to_user: true
overwrite_anonymous: false
anonymous_text: ''
format_username: true
plugin_id: user_name
plugin_id: field
type: user_name
entity_type: user
entity_field: name
status:
......
......@@ -185,13 +185,10 @@ display:
hide_empty: false
empty_zero: false
hide_alter_empty: true
link_to_user: true
overwrite_anonymous: false
anonymous_text: ''
format_username: true
entity_type: user
entity_field: name
plugin_id: user_name
plugin_id: field
type: user_name
edit_node:
id: edit_node
table: node
......
......@@ -120,9 +120,9 @@ display:
table: users_field_data
field: name
label: Author
link_to_user: true
relationship: uid
plugin_id: user_name
plugin_id: field
type: user_name
group_type: group
admin_label: ''
exclude: false
......@@ -165,9 +165,6 @@ display:
hide_empty: false
empty_zero: false
hide_alter_empty: true
overwrite_anonymous: false
anonymous_text: ''
format_username: true
entity_type: user
entity_field: name
changed:
......
......@@ -237,11 +237,8 @@ display:
hide_empty: false
empty_zero: false
hide_alter_empty: true
link_to_user: true
overwrite_anonymous: false
anonymous_text: ''
format_username: true
plugin_id: user_name
plugin_id: field
type: user_name
entity_type: user
entity_field: name
status:
......
......@@ -58,7 +58,8 @@ display:
table: users_field_data
field: name
label: ''
plugin_id: user_name
plugin_id: field
type: user_name
alter:
alter_text: false
make_link: false
......@@ -70,8 +71,6 @@ display:
html: false
hide_empty: false
empty_zero: false
link_to_user: true
overwrite_anonymous: false
relationship: none
group_type: group
admin_label: ''
......@@ -86,8 +85,6 @@ display:
element_default_classes: true
empty: ''
hide_alter_empty: true
anonymous_text: ''
format_username: true
entity_type: user
entity_field: name
filters:
......
......@@ -65,7 +65,8 @@ display:
table: users_field_data
field: name
label: ''
plugin_id: user_name
plugin_id: field
type: user_name
alter:
alter_text: false
make_link: false
......@@ -77,8 +78,6 @@ display:
html: false
hide_empty: false
empty_zero: false
link_to_user: true
overwrite_anonymous: false
relationship: none
group_type: group
admin_label: ''
......@@ -93,8 +92,6 @@ display:
element_default_classes: true
empty: ''
hide_alter_empty: true
anonymous_text: ''
format_username: true
entity_type: user
entity_field: name
filters:
......
......@@ -185,3 +185,10 @@ entity_reference_selection.default:user:
include_anonymous:
type: boolean
label: 'Include the anonymous user in the matched entities.'
field.formatter.settings.user_name:
type: mapping
mapping:
link_to_entity:
type: boolean
label: 'Link to the user'
......@@ -83,20 +83,6 @@ views.field.user_link_edit:
type: views.field.user_link
label: 'User edit link'
views.field.user_name:
type: views_field_user
label: 'User name'
mapping:
format_username:
type: boolean
label: 'Use formatted username'
overwrite_anonymous:
type: boolean
label: 'Overwrite the value to display for anonymous users'
anonymous_text:
type: label
label: 'Text to display for anonymous users'
views.field.user_permissions:
type: views.field.prerender_list
label: 'List of permission'
......
<?php
/**
* @file
* Contains \Drupal\user\Plugin\Field\FieldFormatter\UserNameFormatter.
*/
namespace Drupal\user\Plugin\Field\FieldFormatter;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\FormatterBase;
use Drupal\Core\Form\FormStateInterface;
/**
* Plugin implementation of the 'user_name' formatter.
*
* @FieldFormatter(
* id = "user_name",
* label = @Translation("User name"),
* description = @Translation("Display the user or author name."),
* field_types = {
* "string"
* }
* )
*/
class UserNameFormatter extends FormatterBase {
/**
* {@inheritdoc}
*/
public static function defaultSettings() {
$options = parent::defaultSettings();
$options['link_to_entity'] = TRUE;
return $options;
}
/**
* {@inheritdoc}
*/
public function settingsForm(array $form, FormStateInterface $form_state) {
$form = parent::settingsForm($form, $form_state);
$form['link_to_entity'] = [
'#type' => 'checkbox',
'#title' => $this->t('Link to the user'),
'#default_value' => $this->getSetting('link_to_entity'),
];
return $form;
}
/**
* {@inheritdoc}
*/
public function viewElements(FieldItemListInterface $items) {
$elements = [];
foreach ($items as $delta => $item) {
/** @var $user \Drupal\user\UserInterface */
if ($user = $item->getEntity()) {
if ($this->getSetting('link_to_entity')) {
$elements[$delta] = [
'#theme' => 'username',
'#account' => $user,
'#link_options' => ['attributes' => ['rel' => 'user']],
'#cache' => [
'tags' => $user->getCacheTags(),
],
];
}
else {
$elements[$delta] = [
'#markup' => $user->getUsername(),
'#cache' => [
'tags' => $user->getCacheTags(),
],
];
}
}
}
return $elements;
}
/**
* {@inheritdoc}
*/
public static function isApplicable(FieldDefinitionInterface $field_definition) {
return $field_definition->getTargetEntityTypeId() === 'user' && $field_definition->getName() === 'name';
}
}
<?php
/**
* @file
* Definition of Drupal\user\Plugin\views\field\Name.
*/
namespace Drupal\user\Plugin\views\field;
use Drupal\Component\Utility\SafeMarkup;
use Drupal\Core\Form\FormStateInterface;
use Drupal\user\Plugin\views\field\User;
use Drupal\views\Plugin\views\display\DisplayPluginBase;
use Drupal\views\ResultRow;
use Drupal\views\ViewExecutable;
/**
* Field handler to provide simple renderer that allows using a themed user link.
*
* @ingroup views_field_handlers
*
* @ViewsField("user_name")
*/
class Name extends User {
/**
* Overrides \Drupal\user\Plugin\views\field\User::init().
*
* Add uid in the query so we can test for anonymous if needed.
*/
public function init(ViewExecutable $view, DisplayPluginBase $display, array &$options = NULL) {
parent::init($view, $display, $options);
if (!empty($this->options['overwrite_anonymous']) || !empty($this->options['format_username'])) {
$this->additional_fields['uid'] = 'uid';
}
}
protected function defineOptions() {
$options = parent::defineOptions();
$options['overwrite_anonymous'] = array('default' => FALSE);
$options['anonymous_text'] = array('default' => '');
$options['format_username'] = array('default' => TRUE);
return $options;
}
/**
* {@inheritdoc}
*/
public function buildOptionsForm(&$form, FormStateInterface $form_state) {
parent::buildOptionsForm($form, $form_state);
$form['format_username'] = array(
'#title' => $this->t('Use formatted username'),
'#type' => 'checkbox',
'#default_value' => !empty($this->options['format_username']),
'#description' => $this->t('If checked, the username will be formatted by the system. If unchecked, it will be displayed raw.'),
);
$form['overwrite_anonymous'] = array(
'#title' => $this->t('Overwrite the value to display for anonymous users'),
'#type' => 'checkbox',
'#default_value' => !empty($this->options['overwrite_anonymous']),
'#description' => $this->t('Enable to display different text for anonymous users.'),
);
$form['anonymous_text'] = array(
'#title' => $this->t('Text to display for anonymous users'),
'#type' => 'textfield',
'#default_value' => $this->options['anonymous_text'],
'#states' => array(
'visible' => array(
':input[name="options[overwrite_anonymous]"]' => array('checked' => TRUE),
),
),
);
}
/**
* {@inheritdoc}
*/
protected function renderLink($data, ResultRow $values) {
if (!empty($this->options['link_to_user']) || !empty($this->options['overwrite_anonymous']) || !empty($this->options['format_username'])) {
$account = entity_create('user');
$account->uid = $this->getValue($values, 'uid');
$account->name = $this->getValue($values);
if (!empty($this->options['overwrite_anonymous']) && !$account->id()) {
// This is an anonymous user, and we're overwriting the text.
return SafeMarkup::checkPlain($this->options['anonymous_text']);
}
elseif (!empty($this->options['link_to_user'])) {
$account->name = $this->getValue($values);
$username = array(
'#theme' => 'username',
'#account' => $account,
);
return drupal_render($username);
}
// If we want a formatted username, do that.
if (!empty($this->options['format_username'])) {
return user_format_name($account);
}
}
// Otherwise, there's no special handling, so return the data directly.
return $data;
}
}
......@@ -73,9 +73,7 @@ protected function defaultDisplayOptions() {
$display_options['fields']['name']['alter']['html'] = 0;
$display_options['fields']['name']['hide_empty'] = 0;
$display_options['fields']['name']['empty_zero'] = 0;
$display_options['fields']['name']['link_to_user'] = 1;
$display_options['fields']['name']['overwrite_anonymous'] = 0;
$display_options['fields']['name']['plugin_id'] = 'user_name';
$display_options['fields']['name']['plugin_id'] = 'field';
return $display_options;
}
......
<?php
/**
* @file
* Contains \Drupal\user\Tests\Field\UserNameFormatterTest.
*/
namespace Drupal\user\Tests\Field;
use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
use Drupal\Core\Entity\FieldableEntityInterface;
use Drupal\simpletest\KernelTestBase;
use Drupal\user\Entity\User;
/**
* Tests the user_name formatter.
*
* @group field
*/
class UserNameFormatterTest extends KernelTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = ['field', 'user', 'system'];
/**
* @var string
*/
protected $entityType;
/**
* @var string
*/
protected $bundle;
/**
* @var string
*/
protected $fieldName;
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->installConfig(['field']);
$this->installEntitySchema('user');
$this->installSchema('system', ['sequences']);
$this->entityType = 'user';
$this->bundle = $this->entityType;
$this->fieldName = 'name';
}
/**
* Renders fields of a given entity with a given display.
*
* @param \Drupal\Core\Entity\FieldableEntityInterface $entity
* The entity object with attached fields to render.
* @param \Drupal\Core\Entity\Display\EntityViewDisplayInterface $display
* The display to render the fields in.
*
* @return string
* The rendered entity fields.
*/
protected function renderEntityFields(FieldableEntityInterface $entity, EntityViewDisplayInterface $display) {
$content = $display->build($entity);
$content = $this->render($content);
return $content;
}
/**
* Tests the formatter output.
*/
public function testFormatter() {
$user = User::create([
'name' => 'test name',
]);
$user->save();
$result = $user->{$this->fieldName}->view(['type' => 'user_name']);
$this->assertEqual('username', $result[0]['#theme']);
$this->assertEqual(spl_object_hash($user), spl_object_hash($result[0]['#account']));
$result = $user->{$this->fieldName}->view(['type' => 'user_name', 'settings' => ['link_to_entity' => FALSE]]);
$this->assertEqual($user->getUsername(), $result[0]['#markup']);
}
}
......@@ -31,34 +31,29 @@ public function testUserName() {
$view = Views::getView('test_views_handler_field_user_name');
$view->initHandlers();
$view->field['name']->options['link_to_user'] = TRUE;
$view->field['name']->options['type'] = 'user_name';
$view->field['name']->init($view, $view->getDisplay('default'));
$this->executeView($view);
$username = $view->result[0]->users_field_data_name = $this->randomMachineName();
$view->result[0]->uid = 1;
$anon_name = $this->config('user.settings')->get('anonymous');
$render = $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]);
$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_field_data_name = $this->randomMachineName();
$view->result[0]->uid = 1;
$view->field['name']->options['type'] = 'string';
$username = $this->randomMachineName();
$view->result[0]->_entity->setUsername($username);
$view->result[0]->_entity->uid->value = 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;
$anon_name = $this->config('user.settings')->get('anonymous');
$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.');
$view->field['name']->options['overwrite_anonymous'] = TRUE;
$anon_name = $view->field['name']->options['anonymous_text'] = $this->randomMachineName();
$render = $view->field['name']->advancedRender($view->result[0]);
$this->assertIdentical($render, $anon_name , 'For user0 it should use the configured anonymous text if overwrite_anonymous is checked.');
$view->result[0]->uid = 1;
$render = $view->field['name']->advancedRender($view->result[0]);
$this->assertNotIdentical($render, $anon_name , 'For registered user it should not use the configured anonymous text if overwrite_anonymous is checked.');
}
/**
......@@ -68,8 +63,9 @@ public function testNoAdditionalFields() {
$view = Views::getView('test_views_handler_field_user_name');
$this->executeView($view);
$username = $view->result[0]->users_field_data_name = $this->randomMachineName();
$view->result[0]->users_field_data_uid = 1;
$username = $this->randomMachineName();
$view->result[0]->_entity->setUsername($username);
$view->result[0]->_entity->uid->value = 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.');
}
......
......@@ -61,7 +61,7 @@ public function testUserFields() {
$this->assertFieldAccess('user', 'langcode', $user->language()->getName());
$this->assertFieldAccess('user', 'preferred_langcode', 'Spanish');
$this->assertFieldAccess('user', 'preferred_admin_langcode', 'French');
// $this->assertFieldAccess('user', 'name', 'test user');
$this->assertFieldAccess('user', 'name', 'test user');
// $this->assertFieldAccess('user', 'mail', 'druplicon@drop.org');
$this->assertFieldAccess('user', 'timezone', 'ut1');
$this->assertFieldAccess('user', 'status', 'On');
......
......@@ -80,7 +80,7 @@ public function getViewsData() {
);
$data['users_field_data']['name']['help'] = t('The user or author name.');
$data['users_field_data']['name']['field']['id'] = 'user_name';
$data['users_field_data']['name']['field']['default_formatter'] = 'user_name';
$data['users_field_data']['name']['filter']['title'] = t('Name (raw)');
$data['users_field_data']['name']['filter']['help'] = t('The user or author name. This filter does not check if the user exists and allows partial matching. Does not use autocomplete.');
......
......@@ -81,8 +81,8 @@ display:
hide_empty: false
empty_zero: false
hide_alter_empty: true
link_to_user: false
plugin_id: user
plugin_id: field
type: user
entity_type: user
entity_field: uid
permission:
......
......@@ -28,7 +28,8 @@ display:
field: name
id: name
table: users_field_data
plugin_id: user_name
plugin_id: field
type: user_name
entity_type: user
entity_field: name
nid:
......
......@@ -33,7 +33,8 @@ display:
id: name
table: users_field_data
field: name
plugin_id: user_name
plugin_id: field
type: user_name
entity_type: user
entity_field: name
sorts:
......
......@@ -51,9 +51,8 @@ display:
html: false
hide_empty: false
empty_zero: false
link_to_user: true
overwrite_anonymous: false
plugin_id: user_name
plugin_id: field
type: user_name
entity_type: user
entity_field: name
data:
......
......@@ -43,10 +43,9 @@ display:
hide_alter_empty: false
hide_empty: false
id: name
link_to_user: true
overwrite_anonymous: false
table: users_field_data
plugin_id: user_name
plugin_id: field
type: user_name
entity_type: user
entity_field: name
title:
......@@ -89,9 +88,9 @@ display:
hide_alter_empty: false
hide_empty: false
id: uid
link_to_user: true
table: users_field_data
plugin_id: user
plugin_id: field
type: user
entity_type: user
entity_field: uid
pager:
......
......@@ -85,11 +85,8 @@ display:
hide_empty: false
empty_zero: false
hide_alter_empty: true
link_to_user: true
overwrite_anonymous: false
anonymous_text: ''
format_username: true
plugin_id: user_name
plugin_id: field
type: user_name
entity_type: user
entity_field: name
roles_target_id:
......
......@@ -36,11 +36,9 @@ display:
hide_empty: false
id: name
label: ''
link_to_user: false
overwrite_anonymous: false
format_username: false
table: users_field_data
plugin_id: user_name
plugin_id: field
type: user_name
entity_type: user
entity_field: name
pager:
......
......@@ -94,8 +94,10 @@ public function getCacheContexts() {
*
* @param \Drupal\views\Plugin\views\query\QueryPluginBase $query
* The query to alter.
* @param string $relationship