Skip to content
This repository has been archived by the owner on Nov 26, 2017. It is now read-only.

JFactory::getUser() #1810

Closed
wants to merge 3 commits into from
Closed

JFactory::getUser() #1810

wants to merge 3 commits into from

Conversation

wilsonge
Copy link

I'm following (with a slight tweak of the foreach statement) example 2 of the JFactory::getUser() docs page here (http://docs.joomla.org/JFactory/getUser)

$users[0]='admin';    //Some user that exists
$users[1]='joeblogs';  // Some user that doesn't exist
foreach($users as $name) {
        $user =& JFactory::getUser( $name );
    if ($user->id == 0) {
            echo 'There is no user '.$name.' registered on this site.';
    } else {
        echo 'User name: ' . $user->username;
        echo 'Real name: ' . $user->name;
        echo 'User ID : ' . $user->id; 
    }
}

Now the docs state when searching for a user that "information about a specific user, with username 'joebloggs', is displayed, regardless of the status of the current user."

So when you run this when logged out you find you get "There is no user admin registered on this site.There is no user joeblogs registered on this site." whereas you actually should see admin does exist as a user. And if you are logged in then you find a JLog (or whatever its called now) is thrown for the joebloggs user of "JUser: :_load: User joeblogs does not exist" and a php warning is also thrown that the line "if ($user->id == 0) {" is "Trying to get property of non-object". And the admin properties display as expected.

This JLog is thrown on line 245 of libraries/joomla/user/user.php : " JLog::add(JText::sprintf('JLIB_USER_ERROR_ID_NOT_EXISTS', $identifier), JLog::WARNING, 'jerror');" in joomla 3.0 (this may have changed since I guess).

Now this is definitely NOT the behavior documented and this needs to be resolved. Personally I prefer the documented behavior (although i guess that's open to you guys).

I'll try and work some commits into this over the next few days to try and swap the behavior back to that expected in the docs - post if you have any better ideas though.

@wilsonge
Copy link
Author

The two pull requests above deal with a blank copy of JUser being returned. This stops the JError being formed when trying to find a user that doesn't exist and gives it an id of 0 by definition. It thus removes the php warning as well therefore.

Still trying to work out why the command is only working when logged in though.

@AmyStephen
Copy link
Contributor

JUser is specifically designed to provide data on the user currently logged in.

@wilsonge
Copy link
Author

That's definitely not whats written in the documentation here http://docs.joomla.org/JFactory/getUser . Example 2 is pretty explicit. But that's in some ways what I'm after - trying to get the code and the docs matched up :) If its definitely not supposed to be used to search for users - then that makes the param

 * @param   integer  $id  The user to load - Can be an integer or string - If string, it is converted to ID automatically.

irrelevant. Because the user logged in is only searched for if this is null.

@AmyStephen
Copy link
Contributor

I am so sorry, I am wrong on that. JFactory creates a static instance of the class, but it has an array of ID values. So, it certainly can be used for more than the current user.

    // Check if the user ID is already cached.
    if (empty(self::$instances[$id]))
    {
        $user = new JUser($id);
        self::$instances[$id] = $user;
    }

As far as how it's used in the CMS, not at all sure since obviously I didn't know this was possible. Thanks for the link, sorry for the confusion.

@elinw
Copy link
Contributor

elinw commented Jan 24, 2013

Please understand that in a CLI context there is no logged in user in general and JUser is designed to return information on ANY user by name or id as is clear in the documentation.

@wilsonge
Copy link
Author

But my part of my point is that it doesn't. For some reason (and this has existed since at least J2.5). If a user isn't logged in - then all that is returned when you search for any user is just a 'new' JUser. No details are passed back at all.

Try running the code I made in my very first post for a user that does exist. If you are logged in then it will return that users details. If you are logged out - it will say the user does't exist.

I had a long look last night though and I cannot for the life of me see what in the code is doing that. This is a separate thing to my commit above though - which is related to what do to if you search for a user and they don't exist.

@wilsonge
Copy link
Author

OK quick update been doing some testing and it turns out that on line 224 of joomla/factory.php and the getUser() function

elseif ($instance->id != $id)

doesn't activate if $id is 0 for some reason - in fact you can write at the end of the get user function

 if($id == $instance->id) { echo 'true for user '.$id; } else { echo 'false for user '.$id; }

and it will actually echo out true when you are logged in and false when you are logged in - when you pass in a active users username.

Anybody got any ideas as to why this is the case?

@wilsonge
Copy link
Author

OK commit above seems to do the trick but don't know whether it has any side effects/is the optimal way of coding for this! Think these 3 commits seem to do the trick and restore the expected behavior from example 2 in the docs

http://joomlacode.org/gf/project/joomla/tracker/?action=TrackerItemEdit&tracker_item_id=29986

@AmyStephen
Copy link
Contributor

I don't know. It sounds like maybe JUser was changed for purposes of the CLI. I have no idea if example 2 is for every application. I can't imagine why, for example, a guest would need to look up IDs.

I would be hesitant to change the behavior of the guest zero ID in JFactory without a platform maintainer's involvement. It's all tied together with the user, session, authentication, etc.

Hopefully, @ianmacl or @eddieajau will weigh in.

Thanks for your work!

@wilsonge
Copy link
Author

@AmyStephen Its not necessary a guest looking up id's. But say I have a list of guest id's in my database and I want to use JFactory::getUser('username')->username. To then retrieve their username from database I want to use JFactory::getUser rather than a database request. However this approach only retrieves the username when someone on the site is logged in at the moment. I'm not changing the behaviour of the guest 0 id. Just adding in a catch so that the request still runs in this scenario.

But thank you for the comments!

@mahagr
Copy link
Contributor

mahagr commented Jan 25, 2013

I might know what's going on in here: $instance may not contain JUser object if user is guest...

If you're not interested to get currently logged user, use JUser::getInstance($username) instead as it's faster anyway.

@AmyStephen
Copy link
Contributor

That's absolutely what's happening. He's now returning an object for a new user but I don't think that's what is needed.

@wilsonge
Copy link
Author

I'm not sure exactly what's needed in all honesty. When I found this I just wanted the code to agree with what's in the documentation. Of course that doesn't mean to say there aren't other ways of achieving this/whether its better to change the documentation!!

Thanks for the advice with JUser::getInstance($username) btw - should have occurred really based on the research I've been doing into this.

@eddieajau
Copy link
Contributor

I'm going to close this one only because the CMS is going to take over maintenance of the Platform. Please resubmit against the CMS repo. Thanks.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants