From a9b2470f6f014738e3dc7ea42183b252fbd95a38 Mon Sep 17 00:00:00 2001 From: effulgentsia <alex.bronstein@acquia.com> Date: Fri, 25 Sep 2015 23:32:08 -0700 Subject: [PATCH] Issue #2571909 by alexpott, larowlan, stefan.r, Wim Leers, lauriii, effulgentsia, Upchuk, dunix: CommentForm selects using the user formatted name --- core/modules/comment/comment.module | 20 ---- core/modules/comment/src/CommentForm.php | 97 +++++++++++-------- .../CommentDefaultFormatter.php | 10 -- .../src/Tests/CommentAnonymousTest.php | 1 + .../src/Tests/CommentInterfaceTest.php | 4 +- .../comment/src/Tests/CommentPreviewTest.php | 15 +-- .../comment/src/Tests/CommentTestBase.php | 3 + .../src/Tests/CommentTranslationUITest.php | 5 +- 8 files changed, 73 insertions(+), 82 deletions(-) diff --git a/core/modules/comment/comment.module b/core/modules/comment/comment.module index 825cfc4e72fb..d72772f21187 100644 --- a/core/modules/comment/comment.module +++ b/core/modules/comment/comment.module @@ -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; diff --git a/core/modules/comment/src/CommentForm.php b/core/modules/comment/src/CommentForm.php index c96202bd5d08..15d1ece46f3a 100644 --- a/core/modules/comment/src/CommentForm.php +++ b/core/modules/comment/src/CommentForm.php @@ -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. diff --git a/core/modules/comment/src/Plugin/Field/FieldFormatter/CommentDefaultFormatter.php b/core/modules/comment/src/Plugin/Field/FieldFormatter/CommentDefaultFormatter.php index adacf9d092f4..5aa5f4f14787 100644 --- a/core/modules/comment/src/Plugin/Field/FieldFormatter/CommentDefaultFormatter.php +++ b/core/modules/comment/src/Plugin/Field/FieldFormatter/CommentDefaultFormatter.php @@ -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'; - } } } diff --git a/core/modules/comment/src/Tests/CommentAnonymousTest.php b/core/modules/comment/src/Tests/CommentAnonymousTest.php index fd813f73d5b1..60e243bf03df 100644 --- a/core/modules/comment/src/Tests/CommentAnonymousTest.php +++ b/core/modules/comment/src/Tests/CommentAnonymousTest.php @@ -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. diff --git a/core/modules/comment/src/Tests/CommentInterfaceTest.php b/core/modules/comment/src/Tests/CommentInterfaceTest.php index 113681167fa7..0dc5ea294c8b 100644 --- a/core/modules/comment/src/Tests/CommentInterfaceTest.php +++ b/core/modules/comment/src/Tests/CommentInterfaceTest.php @@ -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(); diff --git a/core/modules/comment/src/Tests/CommentPreviewTest.php b/core/modules/comment/src/Tests/CommentPreviewTest.php index 644f89b5727e..2a9b1973f496 100644 --- a/core/modules/comment/src/Tests/CommentPreviewTest.php +++ b/core/modules/comment/src/Tests/CommentPreviewTest.php @@ -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()); diff --git a/core/modules/comment/src/Tests/CommentTestBase.php b/core/modules/comment/src/Tests/CommentTestBase.php index 12ea894ecdcb..b487fd525066 100644 --- a/core/modules/comment/src/Tests/CommentTestBase.php +++ b/core/modules/comment/src/Tests/CommentTestBase.php @@ -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( diff --git a/core/modules/comment/src/Tests/CommentTranslationUITest.php b/core/modules/comment/src/Tests/CommentTranslationUITest.php index 6397c69a4d9f..88c1d2fc1f01 100644 --- a/core/modules/comment/src/Tests/CommentTranslationUITest.php +++ b/core/modules/comment/src/Tests/CommentTranslationUITest.php @@ -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'), ); -- GitLab