Updated: Comment #N

Problem/Motivation

We are using drupal_anonymous_user() is quite a few places. Procedural and OO code. If we were creating a user session, we would use new UserSession(). Which drupal_anonymous_user is just a wrapper around. Also, the default values passed in are mostly not needed (exception hostname).

Proposed resolution

Introduce an AnonymousUserSession class, and use that instead of calling drupal_anonymous_user(). Set the hostname in the constructor, as well as not allowing any values to be passed in like UserSession. The anonymous user object should not change.

Remaining tasks

Patch, reviews, agreement

User interface changes

None

API changes

Removal of drupal_anonymous_user(). Although if we *have to*, we could keep the drupal_anonymous_user() to preserve any BC.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

damiankloip’s picture

+++ b/core/lib/Drupal/Core/Session/UserSession.php
@@ -230,4 +237,11 @@ public function getLastAccessedTime() {
+
...
+  public function getHostname() {
...
+  }

Forgot to return anything here, will wait for the bot and add into next patch.

dawehner’s picture

  1. +++ b/core/lib/Drupal/Core/Session/AnonymousUserSession.php
    @@ -0,0 +1,29 @@
    +  public function __construct() {
    +    try {
    +      $this->hostname = \Drupal::request()->getClientIP();
    +    }
    +    catch (RuntimeException $e) {
    ...
    +
    +/**
    + *
    + */
    +class AnonymousUserSession extends UserSession {
    +
    

    Is it just me that I am not convinced with this solution? Why do we have to rely on \Drupal and cannot ask the container to give us a proper anonymous user.

  2. +++ b/core/lib/Drupal/Core/Session/AnonymousUserSession.php
    @@ -0,0 +1,29 @@
    +      // We are not in a request context.
    +    }
    

    Does that mean that creating a session without a request makes sense? It seems to be (and has been part of the old code), though it just feels dirty.

dawehner’s picture

The comment module already uses the request object directly:
$this->hostname->value = \Drupal::request()->getClientIP();
so I really wonder whether we have to keep this functionality on the anonymous object.

damiankloip’s picture

FileSize
17.88 KB
3.41 KB

OK, we spoke about this on IRC, Lets keep the hostname functionality for now, as if we remove it, it needs to go from regular UserSession, session.inc code, and session schema.

Added a quick test for the AnonymousUserSession class.

dawehner’s picture

Status: Needs review » Reviewed & tested by the community
+++ b/core/tests/Drupal/Tests/Core/Session/AnonymousUserSessionTest.php
@@ -7,6 +7,68 @@
+  public function testAnonymousUserSessionWithNoRequest() {
+    $container = new ContainerBuilder();
+
+    // Set a synthetic 'request' definition on the container.
+    $definition = new Definition();
+    $definition->setSynthetic(TRUE);
+
+    $container->setDefinition('request', $definition);
+    \Drupal::setContainer($container);
+
+    $anonymous_user = new AnonymousUserSession();
+
+    $this->assertSame('', $anonymous_user->getHostname());
+  }

WOW!

damiankloip’s picture

Issue tags: +API change
FileSize
18.28 KB
742 bytes

Rerolled and brought back drupal_anonymous_user() but marked as deprecated, as per direction of alexpott.

dawehner’s picture

re-RTBC

penyaskito’s picture

FileSize
699 bytes
18.29 KB
+++ b/core/scripts/generate-d7-content.sh
@@ -261,7 +261,7 @@
+    $GLOBALS['user'] = new \Drupal\Core\Session\AnonymousUserSession();// We should have already allowed anon to vote.

While we are here, let's move the comment according to standards.

Leaving as RTBC.

ianthomas_uk’s picture

Status: Reviewed & tested by the community » Needs review
Issue tags: +@deprecated

The @deprecated needs to be more explict about when it was deprecated and when it will be removed, see #2183187: [META] Remove or document all obsolete APIs before beta, maybe

* @deprecated in Drupal 8.x-dev. Will be removed before Drupal 8.0 by
*   https://drupal.org/node/xxxxxxx. Use
*   new AnonymousUserSession()
*/

However, this is a fairly simple patch. Why not just replace all the calls in core with new AnonymousUserSession(); and remove the function?

damiankloip’s picture

@ianthomas_uk, see #6. alexpott requested that we keep this for now and just mark as deprecated.

ianthomas_uk’s picture

Do you know his reasoning? I'm collating lots of patches like this that remove use of the old functions and need to know if they should remove the functions themselves or not.

Berdir’s picture

+++ b/core/scripts/generate-d7-content.sh
@@ -261,7 +261,8 @@
     $form_state = array();

+++ b/core/modules/user/user.module
@@ -1223,7 +1224,7 @@ function _user_cancel($edit, $account, $method) {
diff --git a/core/scripts/generate-d7-content.sh b/core/scripts/generate-d7-content.sh

diff --git a/core/scripts/generate-d7-content.sh b/core/scripts/generate-d7-content.sh
index 30c61a2..a12138e 100644

index 30c61a2..a12138e 100644
--- a/core/scripts/generate-d7-content.sh

--- a/core/scripts/generate-d7-content.sh
+++ b/core/scripts/generate-d7-content.sh

+++ b/core/scripts/generate-d7-content.sh
+++ b/core/scripts/generate-d7-content.sh
@@ -261,7 +261,8 @@

@@ -261,7 +261,8 @@
   for ($v = 0; $v < ($i % 4); $v++) {
     drupal_static_reset('ip_address');
     $_SERVER['REMOTE_ADDR'] = "127.0.$v.1";
-    $GLOBALS['user'] = drupal_anonymous_user();// We should have already allowed anon to vote.
+    // We should have already allowed anon to vote.
+    $GLOBALS['user'] = new \Drupal\Core\Session\AnonymousUserSession();
     $c = $v % $nbchoices;

I *think* those scripts are supposed to run on a 7.x site, as that's what they generate content for :)

So we shouldn't make changes to them.

That said...
a) The are very likely already completely broken
b) Somewhat useless after https://drupal.org/node/2168011?
c) I also never really understood why the scripts to genreate 6.x and 7.x content are in the 8.x branch...

damiankloip’s picture

FileSize
17.69 KB
1.33 KB

Ok opened #2185315: Remove deprecated drupal_anonymous_user() function and added that to the deprecated doc.

Reverted the change to generate-d7-content.sh, sorry penyaskito :)

Status: Needs review » Needs work

The last submitted patch, 13: 2178581-13.patch, failed testing.

The last submitted patch, 13: 2178581-13.patch, failed testing.

damiankloip’s picture

Status: Needs work » Needs review
FileSize
17.7 KB
damiankloip’s picture

Title: remove drupal_anonymous_user() » Add an AnonymousUserSession object in favour of using drupal_anonymous_user()
dawehner’s picture

+++ b/core/lib/Drupal/Core/Session/AnonymousUserSession.php
@@ -0,0 +1,31 @@
+/**
+ *
+ */

Maybe we could document the purpose of this class.

damiankloip’s picture

FileSize
17.75 KB
492 bytes

Good spot. There we go.

dawehner’s picture

Status: Needs review » Reviewed & tested by the community

thank you!

alexpott’s picture

Issue summary: View changes
Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs reroll

2178581-19.patch no longer applies.


damiankloip’s picture

Issue summary: View changes
Status: Needs work » Needs review
Issue tags: -Needs reroll
FileSize
17.75 KB

Rerolled

xjm’s picture

Issue summary: View changes
damiankloip’s picture

Status: Needs review » Reviewed & tested by the community

That was a pure git reroll - back to RTBC.

damiankloip’s picture

22: 2178581-22.patch queued for re-testing.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 22: 2178581-22.patch, failed testing.

The last submitted patch, 22: 2178581-22.patch, failed testing.

damiankloip’s picture

Status: Needs work » Needs review

22: 2178581-22.patch queued for re-testing.

damiankloip’s picture

Status: Needs review » Reviewed & tested by the community

And the same again.

xjm’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs change record

Draft change records are now required before commit, so this issue needs one before it can be considered RTBC. The new change record should include an issue reference to #1634280: drupal_anonymous_user() should return a User entity as well as this one -- https://drupal.org/node/1941676 is obsoleted by this change and can be unpublished in favor of the new change record upon commit.

damiankloip’s picture

Status: Needs work » Needs review
Issue tags: -Needs change record
xjm’s picture

Status: Needs review » Reviewed & tested by the community

Thanks @damiankloip!

NB: Just re-TBCing; I did not review this patch.

alexpott’s picture

Status: Reviewed & tested by the community » Needs work
  1. +++ b/core/lib/Drupal/Core/Session/AnonymousUserSession.php
    @@ -0,0 +1,31 @@
    +    try {
    +      $this->hostname = \Drupal::request()->getClientIp();
    +    }
    +    catch (RuntimeException $e) {
    +      // We are not in a request context.
    +    }
    

    Maybe try... catch... no longer necessary. We can use \Drupal::has(), no?

  2. +++ b/core/modules/user/lib/Drupal/user/Entity/User.php
    @@ -197,6 +197,13 @@ public function getSessionId() {
    +  public function getHostname() {
    +    return NULL;
    +  }
    

    Really? So this is not useful for logged in users? The function doc says "returns hostname for session" - I think this should behave correctly for logged in users - no?

damiankloip’s picture

Status: Needs work » Needs review
FileSize
18.15 KB
828 bytes

Maybe try... catch... no longer necessary. We can use \Drupal::has(), no?

afaik, No. This is a synthetic service so hasService() will return true. So then trying to actually get that service will fail. So I think we still need the try/catch.

Really? So this is not useful for logged in users? The function doc says "returns hostname for session" - I think this should behave correctly for logged in users - no?

We can add the same functionality as exists in the user session classes, like this?

damiankloip’s picture

FileSize
18.17 KB
2.33 KB

After speaking to @alexpott in IRC; hasRequest() was added in #2194111: Error handler throws exception when service container is not (fully) available yet, so we can now just use that. It already takes into account the has() and synthetic service stuff for us.

damiankloip’s picture

FileSize
18.15 KB

rerolled

dawehner’s picture

Status: Needs review » Reviewed & tested by the community

Note: we could adapt the @covers statements in the test class and us coversDefaultClass, but this is not a blocker for a commit.

damiankloip’s picture

FileSize
18.09 KB
1.27 KB

Let's just do it now! :)

dawehner’s picture

+1

alexpott’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs reroll

2178581-38.patch no longer applies.

error: patch failed: core/modules/user/lib/Drupal/user/Entity/User.php:12
error: core/modules/user/lib/Drupal/user/Entity/User.php: patch does not apply

damiankloip’s picture

Status: Needs work » Needs review
Issue tags: -Needs reroll
FileSize
18.09 KB

Rerolled.

damiankloip’s picture

Status: Needs review » Reviewed & tested by the community

Git resolved all the context issues.

alexpott’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs reroll

2178581-41.patch no longer applies.

error: patch failed: core/modules/simpletest/lib/Drupal/simpletest/TestBase.php:1007
error: core/modules/simpletest/lib/Drupal/simpletest/TestBase.php: patch does not apply

damiankloip’s picture

Rerolling...

Solthun’s picture

Assigned: Unassigned » Solthun
Solthun’s picture

Assigned: Solthun » Unassigned
Status: Needs work » Needs review
Issue tags: -Needs reroll
FileSize
18.01 KB

Rerolled @topdays, hope you don't mind :)

damiankloip’s picture

Status: Needs review » Reviewed & tested by the community

Looks good again, thanks.

alexpott’s picture

Status: Reviewed & tested by the community » Needs work
    // If the node's user uid is not specified manually, use the currently
    // logged in user if available, or else the user running the test.
    if (!isset($settings['uid'])) {
      if ($this->loggedInUser) {
        $settings['uid'] = $this->loggedInUser->id();
      }
      else {
        $user = \Drupal::currentUser() ?: drupal_anonymous_user();
        $settings['uid'] = $user->id();
      }
    }

We still have a usage in Drupal\simpletest\WebTestBase::drupalCreateNode()

damiankloip’s picture

Status: Needs work » Needs review
FileSize
18.36 KB
664 bytes
damiankloip’s picture

FileSize
17.06 KB

Another reroll.

dawehner’s picture

If we remove all instances why don't we just drop it everywhere? This does not seem to be a major API for contrib.

damiankloip’s picture

@alexpott requested to keep drupal_anonymous_user, and remove it in a separate follow-up issue.

RTBC? :)

dawehner’s picture

Status: Needs review » Reviewed & tested by the community

Okay, this seems to be the new way.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 50: 2178581-50.patch, failed testing.

damiankloip’s picture

Status: Needs work » Needs review

50: 2178581-50.patch queued for re-testing.

aspilicious’s picture

Status: Needs review » Reviewed & tested by the community
ParisLiakos’s picture

Status: Reviewed & tested by the community » Needs work
  1. +++ b/core/lib/Drupal/Core/Session/AnonymousUserSession.php
    @@ -0,0 +1,28 @@
    +use Symfony\Component\DependencyInjection\Exception\RuntimeException;
    
    +++ b/core/modules/user/lib/Drupal/user/Entity/User.php
    @@ -14,6 +14,7 @@
    +use Symfony\Component\DependencyInjection\Exception\RuntimeException;
    

    No longer needed, should be removed

  2. +++ b/core/modules/user/lib/Drupal/user/Entity/User.php
    @@ -199,6 +200,15 @@ public function getSessionId() {
    +  public function getHostname() {
    +    if (\Drupal::hasRequest()) {
    +      $this->hostname = \Drupal::request()->getClientIp();
    +    }
    +  }
    

    shouldn't this return the hostname too?

damiankloip’s picture

Status: Needs work » Needs review
FileSize
16.99 KB
470 bytes

1. Remove the use statement. Good spot.
2. This is in line with how it is done when stuff is written for a session, see _drupal_session_write().

damiankloip’s picture

FileSize
17.04 KB
1.05 KB

oops, Paris is right. Misread his comment. We need to actually return something from there.

ParisLiakos’s picture

Status: Needs review » Reviewed & tested by the community

this addressed my concerns!
+1 for registering the property

dawehner’s picture

Awesome!

damiankloip’s picture

FileSize
17.04 KB
alexpott’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs reroll

2178581-59_0.patch no longer applies.

error: patch failed: core/includes/session.inc:18
error: core/includes/session.inc: patch does not apply

damiankloip’s picture

Status: Needs work » Needs review
Issue tags: -Needs reroll
FileSize
17.08 KB

Rerolled, again...

ParisLiakos’s picture

Status: Needs review » Reviewed & tested by the community

  • Commit 13f5d83 on 8.x by catch:
    Issue #2178581 by damiankloip, penyaskito, Solthun: Add an...
catch’s picture

Status: Reviewed & tested by the community » Fixed

Committed/pushed to 8.x, thanks!

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.