Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 50 |
|
0.00% |
0 / 10 |
CRAP | |
0.00% |
0 / 1 |
GlobalUserSelectQueryBuilder | |
0.00% |
0 / 50 |
|
0.00% |
0 / 10 |
306 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
2 | |||
init | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
6 | |||
whereGlobalUserIds | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
2 | |||
whereUserNames | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
2 | |||
whereLocked | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
whereRegisteredTimestamp | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
6 | |||
named | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
6 | |||
temp | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
6 | |||
fetchCentralAuthUsers | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
6 | |||
fetchLocalUserIdentitites | |
0.00% |
0 / 11 |
|
0.00% |
0 / 1 |
12 |
1 | <?php |
2 | |
3 | namespace MediaWiki\Extension\CentralAuth\User; |
4 | |
5 | use EmptyIterator; |
6 | use Iterator; |
7 | use MediaWiki\User\ActorStore; |
8 | use MediaWiki\User\TempUser\TempUserConfig; |
9 | use MediaWiki\User\UserIdentity; |
10 | use MediaWiki\User\UserNameUtils; |
11 | use Wikimedia\Assert\Assert; |
12 | use Wikimedia\Rdbms\IExpression; |
13 | use Wikimedia\Rdbms\IReadableDatabase; |
14 | use Wikimedia\Rdbms\SelectQueryBuilder; |
15 | |
16 | /** |
17 | * @stable |
18 | */ |
19 | class GlobalUserSelectQueryBuilder extends SelectQueryBuilder { |
20 | |
21 | /** @var ActorStore for the local wiki */ |
22 | private ActorStore $actorStore; |
23 | |
24 | private UserNameUtils $userNameUtils; |
25 | private TempUserConfig $tempUserConfig; |
26 | |
27 | /** @var bool */ |
28 | private bool $initRan = false; |
29 | |
30 | /** |
31 | * @param IReadableDatabase $db |
32 | * @param ActorStore $actorStore |
33 | * @param UserNameUtils $userNameUtils |
34 | * @param TempUserConfig $tempUserConfig |
35 | */ |
36 | public function __construct( |
37 | IReadableDatabase $db, |
38 | ActorStore $actorStore, |
39 | UserNameUtils $userNameUtils, |
40 | TempUserConfig $tempUserConfig |
41 | ) { |
42 | parent::__construct( $db ); |
43 | $this->actorStore = $actorStore; |
44 | $this->userNameUtils = $userNameUtils; |
45 | $this->tempUserConfig = $tempUserConfig; |
46 | } |
47 | |
48 | /** |
49 | * Init the SelectQueryBuilder |
50 | * |
51 | * Should be called by ::fetch* methods. |
52 | */ |
53 | private function init(): void { |
54 | if ( $this->initRan ) { |
55 | return; |
56 | } |
57 | |
58 | // HACK: SelectQueryBuilder::queryInfo expects join conditions to be at the join_conds |
59 | // key, but CentralAuthUser::selectQueryInfo exposes them as joinConds |
60 | $queryInfo = CentralAuthUser::selectQueryInfo(); |
61 | $queryInfo['join_conds'] = $queryInfo['joinConds']; |
62 | $this->queryInfo( $queryInfo ); |
63 | |
64 | $this->initRan = true; |
65 | } |
66 | |
67 | /** |
68 | * Find by provided global user IDs |
69 | * |
70 | * @param int|int[] $globalUserIds |
71 | * @return $this |
72 | */ |
73 | public function whereGlobalUserIds( $globalUserIds ): self { |
74 | Assert::parameterType( 'integer|array', $globalUserIds, '$globalUserIds' ); |
75 | |
76 | $this->conds( [ 'gu_id' => $globalUserIds ] ); |
77 | return $this; |
78 | } |
79 | |
80 | /** |
81 | * Find by provided usernames |
82 | * |
83 | * @param string|string[] $userNames |
84 | * @return $this |
85 | */ |
86 | public function whereUserNames( $userNames ): self { |
87 | Assert::parameterType( 'string|array', $userNames, '$userIds' ); |
88 | |
89 | $userNames = array_map( function ( $name ) { |
90 | return $this->userNameUtils->getCanonical( (string)$name ); |
91 | }, (array)$userNames ); |
92 | |
93 | $this->conds( [ 'gu_name' => $userNames ] ); |
94 | return $this; |
95 | } |
96 | |
97 | /** |
98 | * @param bool $isLocked |
99 | * @return $this |
100 | */ |
101 | public function whereLocked( bool $isLocked ): self { |
102 | $this->conds( [ 'gu_locked' => $isLocked ] ); |
103 | return $this; |
104 | } |
105 | |
106 | /** |
107 | * Return users registered before/after $timestamp |
108 | * |
109 | * @param string $timestamp |
110 | * @param bool $before Direction flag (if true, user_registration must be before $timestamp) |
111 | * @return self |
112 | */ |
113 | public function whereRegisteredTimestamp( string $timestamp, bool $before ): self { |
114 | $this->conds( |
115 | $this->db->expr( 'gu_registration', $before ? '<' : '>', |
116 | $this->db->timestamp( $timestamp ) ) |
117 | ); |
118 | return $this; |
119 | } |
120 | |
121 | /** |
122 | * Only return named accounts |
123 | * |
124 | * @return $this |
125 | */ |
126 | public function named(): self { |
127 | if ( !$this->tempUserConfig->isEnabled() ) { |
128 | // nothing to do: getMatchCondition throws if temp accounts aren't enabled |
129 | return $this; |
130 | } |
131 | $this->conds( $this->tempUserConfig->getMatchCondition( $this->db, 'gu_name', IExpression::NOT_LIKE ) ); |
132 | return $this; |
133 | } |
134 | |
135 | /** |
136 | * Only return temporary accounts |
137 | * |
138 | * @return $this |
139 | */ |
140 | public function temp(): self { |
141 | if ( !$this->tempUserConfig->isEnabled() ) { |
142 | // nothing to do: getMatchCondition throws if temp accounts aren't enabled |
143 | return $this; |
144 | } |
145 | $this->conds( $this->tempUserConfig->getMatchCondition( $this->db, 'gu_name', IExpression::LIKE ) ); |
146 | return $this; |
147 | } |
148 | |
149 | /** |
150 | * Fetch CentralAuthUsers for the specified query |
151 | * |
152 | * @return Iterator<CentralAuthUser> |
153 | */ |
154 | public function fetchCentralAuthUsers(): Iterator { |
155 | $this->init(); |
156 | |
157 | $result = $this->fetchResultSet(); |
158 | foreach ( $result as $row ) { |
159 | yield CentralAuthUser::newFromRow( $row, [] ); |
160 | } |
161 | $result->free(); |
162 | } |
163 | |
164 | /** |
165 | * Fetch UserIdentities for the current wiki |
166 | * |
167 | * @return Iterator<UserIdentity> |
168 | */ |
169 | public function fetchLocalUserIdentitites(): Iterator { |
170 | $this->init(); |
171 | $this->field( 'lu_local_id' ); |
172 | |
173 | $result = $this->fetchResultSet(); |
174 | $localUserIds = []; |
175 | foreach ( $result as $row ) { |
176 | $localUserIds[] = $row->lu_local_id; |
177 | } |
178 | |
179 | if ( $localUserIds === [] ) { |
180 | return new EmptyIterator(); |
181 | } |
182 | |
183 | return $this->actorStore->newSelectQueryBuilder() |
184 | ->whereUserIds( $localUserIds ) |
185 | ->fetchUserIdentities(); |
186 | } |
187 | } |