Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
100.00% |
28 / 28 |
|
100.00% |
2 / 2 |
CRAP | |
100.00% |
1 / 1 |
HideUserUtils | |
100.00% |
28 / 28 |
|
100.00% |
2 / 2 |
3 | |
100.00% |
1 / 1 |
getExpression | |
100.00% |
14 / 14 |
|
100.00% |
1 / 1 |
2 | |||
addFieldToBuilder | |
100.00% |
14 / 14 |
|
100.00% |
1 / 1 |
1 |
1 | <?php |
2 | |
3 | namespace MediaWiki\Block; |
4 | |
5 | use Wikimedia\Rdbms\IReadableDatabase; |
6 | use Wikimedia\Rdbms\SelectQueryBuilder; |
7 | |
8 | /** |
9 | * Helpers for building queries that determine whether a user is hidden |
10 | * @since 1.42 |
11 | */ |
12 | class HideUserUtils { |
13 | /** |
14 | * Select users that are not hidden |
15 | */ |
16 | public const SHOWN_USERS = 1; |
17 | |
18 | /** |
19 | * Select users that are hidden |
20 | */ |
21 | public const HIDDEN_USERS = 2; |
22 | |
23 | /** |
24 | * Get an SQL expression suitable for use in WHERE clause which will be |
25 | * true for either hidden or non-hidden users as specified. |
26 | * |
27 | * The expression will contain a subquery. |
28 | * |
29 | * @param IReadableDatabase $dbr |
30 | * @param string $userIdField The field to be used as the user_id when |
31 | * joining on block. Defaults to "user_id". |
32 | * @param int $status Either self::SHOWN_USERS or self::HIDDEN_USERS |
33 | * depending on what sort of user you want to match. |
34 | * @return string |
35 | */ |
36 | public function getExpression( |
37 | IReadableDatabase $dbr, |
38 | string $userIdField = 'user_id', |
39 | $status = self::SHOWN_USERS |
40 | ) { |
41 | // Use a scalar subquery, not IN/EXISTS, to avoid materialization (T360160) |
42 | return '(' . |
43 | $dbr->newSelectQueryBuilder() |
44 | ->select( '1' ) |
45 | // $userIdField may be e.g. block_target.bt_user so an inner table |
46 | // alias is necessary to ensure that that refers to the outer copy |
47 | // of the block_target table. |
48 | ->from( 'block_target', 'hu_block_target' ) |
49 | ->join( 'block', 'hu_block', 'hu_block.bl_target=hu_block_target.bt_id' ) |
50 | ->where( [ "hu_block_target.bt_user=$userIdField", 'hu_block.bl_deleted' => 1 ] ) |
51 | ->limit( 1 ) |
52 | ->caller( __METHOD__ ) |
53 | ->getSQL() . |
54 | ') ' . |
55 | ( $status === self::HIDDEN_USERS ? 'IS NOT NULL' : 'IS NULL' ); |
56 | } |
57 | |
58 | /** |
59 | * Add a field and related joins to the query builder. The field in the |
60 | * query result will be true if the user is hidden or false otherwise. |
61 | * |
62 | * @param SelectQueryBuilder $qb The query builder to be modified |
63 | * @param string $userIdField The name of the user_id field to use in the join |
64 | * @param string $deletedFieldAlias The field alias which will be true if the user is hidden. |
65 | */ |
66 | public function addFieldToBuilder( |
67 | SelectQueryBuilder $qb, |
68 | $userIdField = 'user_id', |
69 | $deletedFieldAlias = 'hu_deleted' |
70 | ) { |
71 | $cond = '(' . |
72 | $qb->newSubquery() |
73 | ->select( '1' ) |
74 | // $userIdField may be e.g. block_target.bt_user so an inner table |
75 | // alias is necessary to ensure that that refers to the outer copy |
76 | // of the block_target table. |
77 | ->from( 'block_target', 'hu_block_target' ) |
78 | ->join( 'block', 'hu_block', 'hu_block.bl_target=hu_block_target.bt_id' ) |
79 | ->where( [ "hu_block_target.bt_user=$userIdField", 'hu_block.bl_deleted' => 1 ] ) |
80 | ->limit( 1 ) |
81 | ->caller( __METHOD__ ) |
82 | ->getSQL() . |
83 | ') IS NOT NULL'; |
84 | $qb->select( [ $deletedFieldAlias => $cond ] ); |
85 | } |
86 | } |