MediaWiki  master
UserFactory.php
Go to the documentation of this file.
1 <?php
23 namespace MediaWiki\User;
24 
26 use IDBAccessObject;
27 use InvalidArgumentException;
29 use stdClass;
30 use User;
32 
39 
46  private $loadBalancer;
47 
49  private $userNameUtils;
50 
52  private $lastUserFromIdentity = null;
53 
58  public function __construct(
59  ILoadBalancer $loadBalancer,
60  UserNameUtils $userNameUtils
61  ) {
62  $this->loadBalancer = $loadBalancer;
63  $this->userNameUtils = $userNameUtils;
64  }
65 
84  public function newFromName(
85  string $name,
86  string $validate = self::RIGOR_VALID
87  ): ?User {
88  // RIGOR_* constants are the same here and in the UserNameUtils class
89  $canonicalName = $this->userNameUtils->getCanonical( $name, $validate );
90  if ( $canonicalName === false ) {
91  return null;
92  }
93 
94  $user = new User();
95  $user->mName = $canonicalName;
96  $user->mFrom = 'name';
97  $user->setItemLoaded( 'name' );
98  return $user;
99  }
100 
109  public function newAnonymous( ?string $ip = null ): User {
110  if ( $ip ) {
111  if ( !$this->userNameUtils->isIP( $ip ) ) {
112  throw new InvalidArgumentException( 'Invalid IP address' );
113  }
114  $user = new User();
115  $user->setName( $ip );
116  } else {
117  $user = new User();
118  }
119  return $user;
120  }
121 
130  public function newFromId( int $id ): User {
131  $user = new User();
132  $user->mId = $id;
133  $user->mFrom = 'id';
134  $user->setItemLoaded( 'id' );
135  return $user;
136  }
137 
146  public function newFromActorId( int $actorId ): User {
147  $user = new User();
148  $user->mActorId = $actorId;
149  $user->mFrom = 'actor';
150  $user->setItemLoaded( 'actor' );
151  return $user;
152  }
153 
162  public function newFromUserIdentity( UserIdentity $userIdentity ): User {
163  if ( $userIdentity instanceof User ) {
164  return $userIdentity;
165  }
166 
167  $id = $userIdentity->getId();
168  $name = $userIdentity->getName();
169  // Cache the $userIdentity we converted last. This avoids redundant conversion
170  // in cases where we would be converting the same UserIdentity over and over,
171  // for instance because we need to access data preferences when formatting
172  // timestamps in a listing.
173  if (
174  $this->lastUserFromIdentity
175  && $this->lastUserFromIdentity->getId() === $id
176  && $this->lastUserFromIdentity->getName() === $name
177  ) {
178  return $this->lastUserFromIdentity;
179  }
180 
181  $this->lastUserFromIdentity = $this->newFromAnyId(
182  $id === 0 ? null : $id,
183  $name === '' ? null : $name,
184  null
185  );
186 
187  return $this->lastUserFromIdentity;
188  }
189 
205  public function newFromAnyId(
206  ?int $userId,
207  ?string $userName,
208  ?int $actorId = null,
209  $dbDomain = false
210  ): User {
211  // Stop-gap solution for the problem described in T222212.
212  // Force the User ID and Actor ID to zero for users loaded from the database
213  // of another wiki, to prevent subtle data corruption and confusing failure modes.
214  if ( $dbDomain !== false ) {
215  $userId = 0;
216  $actorId = 0;
217  }
218 
219  $user = new User;
220  $user->mFrom = 'defaults';
221 
222  if ( $actorId !== null ) {
223  $user->mActorId = $actorId;
224  if ( $actorId !== 0 ) {
225  $user->mFrom = 'actor';
226  }
227  $user->setItemLoaded( 'actor' );
228  }
229 
230  if ( $userName !== null && $userName !== '' ) {
231  $user->mName = $userName;
232  $user->mFrom = 'name';
233  $user->setItemLoaded( 'name' );
234  }
235 
236  if ( $userId !== null ) {
237  $user->mId = $userId;
238  if ( $userId !== 0 ) {
239  $user->mFrom = 'id';
240  }
241  $user->setItemLoaded( 'id' );
242  }
243 
244  if ( $user->mFrom === 'defaults' ) {
245  throw new InvalidArgumentException(
246  'Cannot create a user with no name, no ID, and no actor ID'
247  );
248  }
249 
250  return $user;
251  }
252 
265  public function newFromConfirmationCode(
266  string $confirmationCode,
267  int $flags = self::READ_NORMAL
268  ) {
269  list( $index, $options ) = DBAccessObjectUtils::getDBOptions( $flags );
270 
271  $db = $this->loadBalancer->getConnectionRef( $index );
272 
273  $id = $db->selectField(
274  'user',
275  'user_id',
276  [
277  'user_email_token' => md5( $confirmationCode ),
278  'user_email_token_expires > ' . $db->addQuotes( $db->timestamp() ),
279  ],
280  __METHOD__,
281  $options
282  );
283 
284  if ( !$id ) {
285  return null;
286  }
287 
288  return $this->newFromId( (int)$id );
289  }
290 
300  public function newFromRow( $row, $data = null ) {
301  return User::newFromRow( $row, $data );
302  }
303 
309  public function newFromAuthority( Authority $authority ): User {
310  if ( $authority instanceof User ) {
311  return $authority;
312  }
313  return $this->newFromUserIdentity( $authority->getUser() );
314  }
315 
324  public function newTempPlaceholder() {
325  $user = new User();
326  $user->setName( $this->userNameUtils->getTempPlaceholder() );
327  return $user;
328  }
329 
337  public function newUnsavedTempUser( string $name ) {
338  $user = new User();
339  $user->setName( $name );
340  return $user;
341  }
342 }
if(!defined('MW_SETUP_CALLBACK'))
The persistent session ID (if any) loaded at startup.
Definition: WebStart.php:82
Helper class for DAO classes.
static getDBOptions( $bitfield)
Get an appropriate DB index, options, and fallback DB index for a query.
Creates User objects.
Definition: UserFactory.php:38
newFromId(int $id)
Factory method for creation from a given user ID, replacing User::newFromId.
newFromAuthority(Authority $authority)
newFromName(string $name, string $validate=self::RIGOR_VALID)
Factory method for creating users by name, replacing static User::newFromName.
Definition: UserFactory.php:84
newAnonymous(?string $ip=null)
Returns a new anonymous User based on ip.
newFromRow( $row, $data=null)
newFromAnyId(?int $userId, ?string $userName, ?int $actorId=null, $dbDomain=false)
Factory method for creation from an ID, name, and/or actor ID, replacing User::newFromAnyId.
newFromUserIdentity(UserIdentity $userIdentity)
Factory method for creation fom a given UserIdentity, replacing User::newFromIdentity.
__construct(ILoadBalancer $loadBalancer, UserNameUtils $userNameUtils)
Definition: UserFactory.php:58
newTempPlaceholder()
Create a placeholder user for an anonymous user who will be upgraded to a temporary user.
newUnsavedTempUser(string $name)
Create an unsaved temporary user with a previously acquired name.
newFromActorId(int $actorId)
Factory method for creation from a given actor ID, replacing User::newFromActorId.
newFromConfirmationCode(string $confirmationCode, int $flags=self::READ_NORMAL)
Factory method to fetch the user for a given email confirmation code, replacing User::newFromConfirma...
UserNameUtils service.
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
Definition: User.php:70
static newFromRow( $row, $data=null)
Create a new user object from a user row.
Definition: User.php:760
setItemLoaded( $item)
Set that an item has been loaded.
Definition: User.php:1101
Interface for database access objects.
This interface represents the authority associated the current execution context, such as a web reque...
Definition: Authority.php:37
Interface for objects representing user identity.
getId( $wikiId=self::LOCAL)
Shared interface for rigor levels when dealing with User methods.
Create and track the database connections and transactions for a given database cluster.