Skip to content
Snippets Groups Projects
Commit a9b2470f authored by Alex Bronstein's avatar Alex Bronstein
Browse files

Issue #2571909 by alexpott, larowlan, stefan.r, Wim Leers, lauriii,...

Issue #2571909 by alexpott, larowlan, stefan.r, Wim Leers, lauriii, effulgentsia, Upchuk, dunix: CommentForm selects using the user formatted name
parent 312e867f
Branches
Tags
2 merge requests!7452Issue #1797438. HTML5 validation is preventing form submit and not fully...,!789Issue #3210310: Adjust Database API to remove deprecated Drupal 9 code in Drupal 10
......@@ -565,26 +565,6 @@ function comment_preview(CommentInterface $comment, FormStateInterface $form_sta
$entity = $comment->getCommentedEntity();
if (!$form_state->getErrors()) {
// Attach the user and time information.
$author_name = $comment->getAuthorName();
if (!empty($author_name)) {
$account = user_load_by_name($author_name);
}
elseif (\Drupal::currentUser()->isAuthenticated() && empty($comment->is_anonymous)) {
$account = \Drupal::currentUser();
}
if (!empty($account) && $account->isAuthenticated()) {
$comment->setOwner($account);
$comment->setAuthorName($account->getUsername());
}
elseif (empty($author_name)) {
$comment->setAuthorName(\Drupal::config('user.settings')->get('anonymous'));
}
$created_time = !is_null($comment->getCreatedTime()) ? $comment->getCreatedTime() : REQUEST_TIME;
$comment->setCreatedTime($created_time);
$comment->changed->value = REQUEST_TIME;
$comment->in_preview = TRUE;
$comment_build = comment_view($comment);
$comment_build['#weight'] = -100;
......
......@@ -121,8 +121,11 @@ public function form(array $form, FormStateInterface $form_state) {
}
// Prepare default values for form elements.
$author = '';
if ($is_admin) {
$author = $comment->getAuthorName();
if (!$comment->getOwnerId()) {
$author = $comment->getAuthorName();
}
$status = $comment->getStatus();
if (empty($comment_preview)) {
$form['#title'] = $this->t('Edit comment %title', array(
......@@ -131,12 +134,6 @@ public function form(array $form, FormStateInterface $form_state) {
}
}
else {
if ($this->currentUser->isAuthenticated()) {
$author = $this->currentUser->getUsername();
}
else {
$author = ($comment->getAuthorName() ? $comment->getAuthorName() : '');
}
$status = ($this->currentUser->hasPermission('skip comment approval') ? CommentInterface::PUBLISHED : CommentInterface::NOT_PUBLISHED);
}
......@@ -145,35 +142,46 @@ public function form(array $form, FormStateInterface $form_state) {
$date = !empty($comment->date) ? $comment->date : DrupalDateTime::createFromTimestamp($comment->getCreatedTime());
}
// Add the author name field depending on the current user.
// The uid field is only displayed when a user with the permission
// 'administer comments' is editing an existing comment from an
// authenticated user.
$owner = $comment->getOwner();
$form['author']['uid'] = [
'#type' => 'entity_autocomplete',
'#target_type' => 'user',
'#default_value' => $owner->isAnonymous() ? NULL : $owner,
// A comment can be made anonymous by leaving this field empty therefore
// there is no need to list them in the autocomplete.
'#selection_settings' => ['include_anonymous' => FALSE],
'#title' => $this->t('Authored by'),
'#description' => $this->t('Leave blank for %anonymous.', ['%anonymous' => $config->get('anonymous')]),
'#access' => $is_admin,
];
// The name field is displayed when an anonymous user is adding a comment or
// when a user with the permission 'administer comments' is editing an
// existing comment from an anonymous user.
$form['author']['name'] = array(
'#type' => 'textfield',
'#title' => $this->t('Your name'),
'#title' => $is_admin ? $this->t('Name for @anonymous', ['@anonymous' => $config->get('anonymous')]) : $this->t('Your name'),
'#default_value' => $author,
'#required' => ($this->currentUser->isAnonymous() && $anonymous_contact == COMMENT_ANONYMOUS_MUST_CONTACT),
'#maxlength' => 60,
'#access' => $this->currentUser->isAnonymous() || $is_admin,
'#size' => 30,
'#attributes'=> [
'data-drupal-default-value' => $config->get('anonymous'),
],
);
if ($is_admin) {
$form['author']['name']['#type'] = 'entity_autocomplete';
$form['author']['name']['#target_type'] = 'user';
$form['author']['name']['#selection_settings'] = ['include_anonymous' => FALSE];
$form['author']['name']['#process_default_value'] = FALSE;
// The user name is validated and processed in static::buildEntity() and
// static::validate().
$form['author']['name']['#element_validate'] = array();
$form['author']['name']['#title'] = $this->t('Authored by');
$form['author']['name']['#description'] = $this->t('Leave blank for %anonymous.', array('%anonymous' => $config->get('anonymous')));
}
elseif ($this->currentUser->isAuthenticated()) {
$form['author']['name']['#type'] = 'item';
$form['author']['name']['#value'] = $form['author']['name']['#default_value'];
$form['author']['name']['#theme'] = 'username';
$form['author']['name']['#account'] = $this->currentUser;
$form['author']['name']['#cache']['contexts'][] = 'user';
}
elseif($this->currentUser->isAnonymous()) {
$form['author']['name']['#attributes']['data-drupal-default-value'] = $config->get('anonymous');
// When editing a comment only display the name textfield if the uid field
// is empty.
$form['author']['name']['#states'] = [
'visible' => [
':input[name="uid"]' => array('empty' => TRUE),
],
];
}
// Add author email and homepage fields depending on the current user.
......@@ -263,22 +271,27 @@ public function buildEntity(array $form, FormStateInterface $form_state) {
else {
$comment->setCreatedTime(REQUEST_TIME);
}
$author_name = $form_state->getValue('name');
if (!$this->currentUser->isAnonymous()) {
// Assign the owner based on the given user name - none means anonymous.
$accounts = $this->entityManager->getStorage('user')
->loadByProperties(array('name' => $author_name));
$account = reset($accounts);
$uid = $account ? $account->id() : 0;
$comment->setOwnerId($uid);
// Empty author ID should revert to anonymous.
$author_id = $form_state->getValue('uid');
if ($comment->id() && $this->currentUser->hasPermission('administer comments')) {
// Admin can leave the author ID blank to revert to anonymous.
$author_id = $author_id ?: 0;
}
// If the comment was posted by an anonymous user and no author name was
// required, use "Anonymous" by default.
if ($comment->getOwnerId() === 0 && (!isset($author_name) || $author_name === '')) {
$comment->setAuthorName($this->config('user.settings')->get('anonymous'));
if (!is_null($author_id)) {
if ($author_id === 0 && $form['author']['name']['#access']) {
// Use the author name value when the form has access to the element and
// the author ID is anonymous.
$comment->setAuthorName($form_state->getValue('name'));
}
else {
// Ensure the author name is not set.
$comment->setAuthorName(NULL);
}
}
else {
$author_id = $this->currentUser->id();
}
$comment->setOwnerId($author_id);
// Validate the comment's subject. If not specified, extract from comment
// body.
......
......@@ -190,16 +190,6 @@ public function viewElements(FieldItemListInterface $items) {
$this->getFieldSetting('comment_type'),
]],
];
// @todo Remove this in https://www.drupal.org/node/2543334. Until
// then, \Drupal\Core\Render\Renderer::hasPoorCacheability() isn't
// integrated with cache context bubbling, so this duplicates the
// contexts added by \Drupal\comment\CommentForm::form().
$output['comment_form']['#cache']['contexts'][] = 'user.permissions';
$output['comment_form']['#cache']['contexts'][] = 'user.roles:authenticated';
if ($this->currentUser->isAuthenticated()) {
$output['comment_form']['#cache']['contexts'][] = 'user';
}
}
}
......
......@@ -101,6 +101,7 @@ function testAnonymous() {
$this->drupalLogin($this->adminUser);
$this->drupalGet('comment/' . $anonymous_comment3->id() . '/edit');
$this->assertRaw($author_name, "The anonymous user's name is correct when editing the comment.");
$this->assertFieldByName('uid', '', 'The author field is empty (i.e. anonymous) when editing the comment.');
$this->assertRaw($author_mail, "The anonymous user's email address is correct when editing the comment.");
// Unpublish comment.
......
......@@ -83,7 +83,7 @@ public function testCommentInterface() {
)));
// Test changing the comment author to "Anonymous".
$comment = $this->postComment(NULL, $comment->comment_body->value, $comment->getSubject(), array('name' => ''));
$comment = $this->postComment(NULL, $comment->comment_body->value, $comment->getSubject(), array('uid' => ''));
$this->assertTrue($comment->getAuthorName() == t('Anonymous') && $comment->getOwnerId() == 0, 'Comment author successfully changed to anonymous.');
// Test changing the comment author to an unverified user.
......@@ -95,7 +95,7 @@ public function testCommentInterface() {
// Test changing the comment author to a verified user.
$this->drupalGet('comment/' . $comment->id() . '/edit');
$comment = $this->postComment(NULL, $comment->comment_body->value, $comment->getSubject(), array('name' => $this->webUser->getUsername()));
$comment = $this->postComment(NULL, $comment->comment_body->value, $comment->getSubject(), array('uid' => $this->webUser->getUsername() . ' (' . $this->webUser->id() . ')'));
$this->assertTrue($comment->getAuthorName() == $this->webUser->getUsername() && $comment->getOwnerId() == $this->webUser->id(), 'Comment author successfully changed to a registered user.');
$this->drupalLogout();
......
......@@ -140,7 +140,7 @@ function testCommentEditPreviewSave() {
$date = new DrupalDateTime('2008-03-02 17:23');
$edit['subject[0][value]'] = $this->randomMachineName(8);
$edit['comment_body[0][value]'] = $this->randomMachineName(16);
$edit['name'] = $web_user->getUsername();
$edit['uid'] = $web_user->getUsername() . ' (' . $web_user->id() . ')';
$edit['date[date]'] = $date->format('Y-m-d');
$edit['date[time]'] = $date->format('H:i:s');
$raw_date = $date->getTimestamp();
......@@ -154,13 +154,13 @@ function testCommentEditPreviewSave() {
$this->assertTitle(t('Preview comment | Drupal'), 'Page title is "Preview comment".');
$this->assertText($edit['subject[0][value]'], 'Subject displayed.');
$this->assertText($edit['comment_body[0][value]'], 'Comment displayed.');
$this->assertText($edit['name'], 'Author displayed.');
$this->assertText($web_user->getUsername(), 'Author displayed.');
$this->assertText($expected_text_date, 'Date displayed.');
// Check that the subject, comment, author and date fields are displayed with the correct values.
$this->assertFieldByName('subject[0][value]', $edit['subject[0][value]'], 'Subject field displayed.');
$this->assertFieldByName('comment_body[0][value]', $edit['comment_body[0][value]'], 'Comment field displayed.');
$this->assertFieldByName('name', $edit['name'], 'Author field displayed.');
$this->assertFieldByName('uid', $edit['uid'], 'Author field displayed.');
$this->assertFieldByName('date[date]', $edit['date[date]'], 'Date field displayed.');
$this->assertFieldByName('date[time]', $edit['date[time]'], 'Time field displayed.');
......@@ -172,7 +172,7 @@ function testCommentEditPreviewSave() {
$this->drupalGet('comment/' . $comment->id() . '/edit');
$this->assertFieldByName('subject[0][value]', $edit['subject[0][value]'], 'Subject field displayed.');
$this->assertFieldByName('comment_body[0][value]', $edit['comment_body[0][value]'], 'Comment field displayed.');
$this->assertFieldByName('name', $edit['name'], 'Author field displayed.');
$this->assertFieldByName('uid', $edit['uid'], 'Author field displayed.');
$this->assertFieldByName('date[date]', $expected_form_date, 'Date field displayed.');
$this->assertFieldByName('date[time]', $expected_form_time, 'Time field displayed.');
......@@ -180,7 +180,7 @@ function testCommentEditPreviewSave() {
$displayed = array();
$displayed['subject[0][value]'] = (string) current($this->xpath("//input[@id='edit-subject-0-value']/@value"));
$displayed['comment_body[0][value]'] = (string) current($this->xpath("//textarea[@id='edit-comment-body-0-value']"));
$displayed['name'] = (string) current($this->xpath("//input[@id='edit-name']/@value"));
$displayed['uid'] = (string) current($this->xpath("//input[@id='edit-uid']/@value"));
$displayed['date[date]'] = (string) current($this->xpath("//input[@id='edit-date-date']/@value"));
$displayed['date[time]'] = (string) current($this->xpath("//input[@id='edit-date-time']/@value"));
$this->drupalPostForm('comment/' . $comment->id() . '/edit', $displayed, t('Save'));
......@@ -188,10 +188,11 @@ function testCommentEditPreviewSave() {
// Check that the saved comment is still correct.
$comment_storage = \Drupal::entityManager()->getStorage('comment');
$comment_storage->resetCache(array($comment->id()));
/** @var \Drupal\comment\CommentInterface $comment_loaded */
$comment_loaded = Comment::load($comment->id());
$this->assertEqual($comment_loaded->getSubject(), $edit['subject[0][value]'], 'Subject loaded.');
$this->assertEqual($comment_loaded->comment_body->value, $edit['comment_body[0][value]'], 'Comment body loaded.');
$this->assertEqual($comment_loaded->getAuthorName(), $edit['name'], 'Name loaded.');
$this->assertEqual($comment_loaded->getOwner()->id(), $web_user->id(), 'Name loaded.');
$this->assertEqual($comment_loaded->getCreatedTime(), $raw_date, 'Date loaded.');
$this->drupalLogout();
......@@ -200,6 +201,8 @@ function testCommentEditPreviewSave() {
$user_edit = array();
$expected_created_time = $comment_loaded->getCreatedTime();
$this->drupalLogin($web_user);
// Web user cannot change the comment author.
unset($edit['uid']);
$this->drupalPostForm('comment/' . $comment->id() . '/edit', $user_edit, t('Save'));
$comment_storage->resetCache(array($comment->id()));
$comment_loaded = Comment::load($comment->id());
......
......@@ -70,6 +70,9 @@ protected function setUp() {
'skip comment approval',
'post comments',
'access comments',
// Usernames aren't shown in comment edit form autocomplete unless this
// permission is granted.
'access user profiles',
'access content',
));
$this->webUser = $this->drupalCreateUser(array(
......
......@@ -41,7 +41,8 @@ class CommentTranslationUITest extends ContentTranslationUITestBase {
'timezone',
'url.query_args:_wrapper_format',
'url.query_args.pagers:0',
'user'
'user.permissions',
'user.roles',
];
/**
......@@ -162,7 +163,7 @@ protected function doTestAuthoringInfo() {
'created' => REQUEST_TIME - mt_rand(0, 1000),
);
$edit = array(
'name' => $user->getUsername(),
'uid' => $user->getUsername() . '(' . $user->id() . ')',
'date[date]' => format_date($values[$langcode]['created'], 'custom', 'Y-m-d'),
'date[time]' => format_date($values[$langcode]['created'], 'custom', 'H:i:s'),
);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment