loadBalancer = $loadBalancer; $this->userFactory = $userFactory; $this->userNameUtils = $userNameUtils; } /** * Do a prefix search of user names and return a list of matching user names. * * @param string|UserIdentity|Authority $audience Either AUDIENCE_PUBLIC or a user to * show the search for, providing a UserIdentity is deprecated since 1.37 * @param string $search * @param int $limit * @param int $offset How many results to offset from the beginning * @return string[] * @throws InvalidArgumentException if $audience is invalid */ public function search( $audience, string $search, int $limit, int $offset = 0 ): array { if ( $audience instanceof UserIdentity && !( $audience instanceof Authority ) ) { wfDeprecated( __METHOD__ . ' with a UserIdentity', '1.37' ); $audience = $this->userFactory->newFromUserIdentity( $audience ); } if ( $audience !== self::AUDIENCE_PUBLIC && !( $audience instanceof Authority ) ) { throw new InvalidArgumentException( '$audience must be AUDIENCE_PUBLIC or an Authority object' ); } // Invalid user names are treated as empty strings $prefix = $this->userNameUtils->getCanonical( $search ) ?: ''; $dbr = $this->loadBalancer->getConnectionRef( DB_REPLICA ); $tables = [ 'user' ]; $conds = [ 'user_name ' . $dbr->buildLike( $prefix, $dbr->anyString() ) ]; $joinConds = []; // Filter out hidden user names if ( $audience === self::AUDIENCE_PUBLIC || !$audience->isAllowed( 'hideuser' ) ) { $tables[] = 'ipblocks'; $conds['ipb_deleted'] = [ 0, null ]; $joinConds['ipblocks'] = [ 'LEFT JOIN', 'user_id=ipb_user' ]; } $res = $dbr->selectFieldValues( $tables, 'user_name', $conds, __METHOD__, [ 'LIMIT' => $limit, 'ORDER BY' => 'user_name', 'OFFSET' => $offset ], $joinConds ); return $res; } }