loadBalancer = $loadBalancer; $this->userNameUtils = $userNameUtils; } /** * Factory method for creating users by name, replacing static User::newFromName * * This is slightly less efficient than newFromId(), so use newFromId() if * you have both an ID and a name handy. * * @note unlike User::newFromName, this returns null instead of false for invalid usernames * * @since 1.35 * @since 1.36 returns null instead of false for invalid user names * * @param string $name Username, validated by Title::newFromText * @param string $validate Validation strategy, one of the RIGOR_* constants. For no * validation, use RIGOR_NONE. * @return ?User User object, or null if the username is invalid (e.g. if it contains * illegal characters or is an IP address). If the username is not present in the database, * the result will be a user object with a name, a user id of 0, and default settings. */ public function newFromName( string $name, string $validate = self::RIGOR_VALID ) : ?User { // RIGOR_* constants are the same here and in the UserNameUtils class $canonicalName = $this->userNameUtils->getCanonical( $name, $validate ); if ( $canonicalName === false ) { return null; } $user = new User(); $user->mName = $canonicalName; $user->mFrom = 'name'; $user->setItemLoaded( 'name' ); return $user; } /** * Returns a new anonymous User based on ip. * * @since 1.35 * * @param string|null $ip IP address * @return User */ public function newAnonymous( $ip = null ) : User { if ( $ip ) { $validIp = $this->userNameUtils->isIP( $ip ); if ( $validIp ) { $user = $this->newFromName( $ip, self::RIGOR_NONE ); } else { throw new InvalidArgumentException( 'Invalid IP address' ); } } else { $user = new User(); } return $user; } /** * Factory method for creation from a given user ID, replacing User::newFromId * * @since 1.35 * * @param int $id Valid user ID * @return User The corresponding User object */ public function newFromId( int $id ) : User { $user = new User(); $user->mId = $id; $user->mFrom = 'id'; $user->setItemLoaded( 'id' ); return $user; } /** * Factory method for creation from a given actor ID, replacing User::newFromActorId * * @since 1.35 * * @param int $actorId * @return User */ public function newFromActorId( int $actorId ) : User { $user = new User(); $user->mActorId = $actorId; $user->mFrom = 'actor'; $user->setItemLoaded( 'actor' ); return $user; } /** * Factory method for creation fom a given UserIdentity, replacing User::newFromIdentity * * @since 1.35 * * @param UserIdentity $userIdentity * @return User */ public function newFromUserIdentity( UserIdentity $userIdentity ) : User { if ( $userIdentity instanceof User ) { return $userIdentity; } return $this->newFromAnyId( $userIdentity->getId() === 0 ? null : $userIdentity->getId(), $userIdentity->getName() === '' ? null : $userIdentity->getName(), $userIdentity->getActorId() === 0 ? null : $userIdentity->getActorId() ); } /** * Factory method for creation from an ID, name, and/or actor ID, replacing User::newFromAnyId * * @note This does not check that the ID, name, and actor ID all correspond to * the same user. * * @since 1.35 * * @param ?int $userId * @param ?string $userName * @param ?int $actorId * @param bool|string $dbDomain * @return User * @throws InvalidArgumentException if none of userId, userName, and actorId are specified */ public function newFromAnyId( ?int $userId, ?string $userName, ?int $actorId, $dbDomain = false ) : User { // Stop-gap solution for the problem described in T222212. // Force the User ID and Actor ID to zero for users loaded from the database // of another wiki, to prevent subtle data corruption and confusing failure modes. if ( $dbDomain !== false ) { $userId = 0; $actorId = 0; } $user = new User; $user->mFrom = 'defaults'; if ( $actorId !== null ) { $user->mActorId = $actorId; if ( $actorId !== 0 ) { $user->mFrom = 'actor'; } $user->setItemLoaded( 'actor' ); } if ( $userName !== null && $userName !== '' ) { $user->mName = $userName; $user->mFrom = 'name'; $user->setItemLoaded( 'name' ); } if ( $userId !== null ) { $user->mId = $userId; if ( $userId !== 0 ) { $user->mFrom = 'id'; } $user->setItemLoaded( 'id' ); } if ( $user->mFrom === 'defaults' ) { throw new InvalidArgumentException( 'Cannot create a user with no name, no ID, and no actor ID' ); } return $user; } /** * Factory method to fetch the user for a given email confirmation code, replacing User::newFromConfirmationCode * * This code is generated when an account is created or its e-mail address has changed. * If the code is invalid or has expired, returns null. * * @since 1.35 * * @param string $confirmationCode * @param int $flags * @return User|null */ public function newFromConfirmationCode( string $confirmationCode, int $flags = self::READ_NORMAL ) { list( $index, $options ) = DBAccessObjectUtils::getDBOptions( $flags ); $db = $this->loadBalancer->getConnectionRef( $index ); $id = $db->selectField( 'user', 'user_id', [ 'user_email_token' => md5( $confirmationCode ), 'user_email_token_expires > ' . $db->addQuotes( $db->timestamp() ), ], __METHOD__, $options ); if ( !$id ) { return null; } return $this->newFromId( (int)$id ); } /** * @see User::newFromRow * * @since 1.36 * * @param stdClass $row A row from the user table * @param array|null $data Further data to load into the object * @return User */ public function newFromRow( $row, $data = null ) { return User::newFromRow( $row, $data ); } /** * @internal for transition from User to Authority as performer concept. * @param Authority $authority * @return User */ public function newFromAuthority( Authority $authority ): User { if ( $authority instanceof User ) { return $authority; } return $this->newFromUserIdentity( $authority->getPerformer() ); } }