Page MenuHomePhabricator

Error: "Call to a member function getId() on string" from UserSystemGifts.php
Closed, ResolvedPublic

Description

Using MW 1.34, the notification that is sent from the Echo extension after receiving an award shows an internal error page when it is clicked.

Here is the full error:

[d102f4e07a02a9fc592f5dc2] /index.php?title=Special:ViewSystemGift&gift_id=2&markasread=1 Error from line 42 of /var/www/html/test/extensions/SocialProfile/SystemGifts/includes/UserSystemGifts.php: Call to a member function getId() on string

Backtrace:

#0 /var/www/html/test/extensions/SocialProfile/SystemGifts/includes/specials/SpecialViewSystemGift.php(49): UserSystemGifts->__construct(string)
#1 /var/www/html/test/includes/specialpage/SpecialPage.php(575): ViewSystemGift->execute(NULL)
#2 /var/www/html/test/includes/specialpage/SpecialPageFactory.php(611): SpecialPage->run(NULL)
#3 /var/www/html/test/includes/MediaWiki.php(296): MediaWiki\Special\SpecialPageFactory->executePath(Title, RequestContext)
#4 /var/www/html/test/includes/MediaWiki.php(900): MediaWiki->performRequest()
#5 /var/www/html/test/includes/MediaWiki.php(527): MediaWiki->main()
#6 /var/www/html/test/index.php(44): MediaWiki->run()
#7 {main}

Event Timeline

Vishkujo renamed this task from Clicking Award from Echo Extension's Notification Shows Error to Error: "Call to a member function getId() on string" from UserSystemGifts.php.Sep 7 2020, 6:26 AM

Is this still a problem in git master? Normally these sort of errors are rather easy to fix but looking at this particular code, I cannot fathom why it'd fail. UserSystemGifts' constructor intentionally accepts both strings (user names) as well as full User objects; assuming a string is provided, User::newFromName() is called on it to turn it into a User object. There is some potential for failure here as the code does not ensure that the aformentioned call to User::newFromName() indeed returns a valid User object, but provided that you're logged in and all, I think it's safe to say your user name is valid at that point.

public function __construct( $user ) {
  if ( $user instanceof User ) {
    $this->user = $user;
  } else {
    $this->user = User::newFromName( $user );
  }
    $this->user_id = $user->getId();
    $this->user_name = $user->getName();
    $this->actorId = $user->getActorId();
  }

If a string is provided as the constructor argument, then throughout this block scope $user variable is of string type, it'll never change to object.

You're only changing the object property $user which is different from the $user variable passed in the constructor.

You need to change all these get* calls to be on the property $this-user->get and not on the potential string variable $user->get.

Alternatively you can also change the else statement to ensure the object is also assigned to a new $user variable (in addition to the $user property), so you can safely do a method call on it and remove the need for altering the get* calls.

$this->user = $user = User::newFromName( $user );

Change 629638 had a related patch set uploaded (by Jack Phoenix; owner: Jack Phoenix):
[mediawiki/extensions/SocialProfile@master] Use the correct variable to prevent fatals

https://gerrit.wikimedia.org/r/629638

ashley claimed this task.
ashley removed a project: Patch-For-Review.

Ah, thanks for the explanation, @Ammarpad! I've submitted & merged a patch which should take care of this, even if I wasn't able to reproduce the issue on my own.

Change 629638 merged by jenkins-bot:
[mediawiki/extensions/SocialProfile@master] Use the correct variable to prevent fatals

https://gerrit.wikimedia.org/r/629638