Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 38 |
|
0.00% |
0 / 5 |
CRAP | |
0.00% |
0 / 1 |
MessageGroupSubscriptionStore | |
0.00% |
0 / 38 |
|
0.00% |
0 / 5 |
90 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
addSubscription | |
0.00% |
0 / 9 |
|
0.00% |
0 / 1 |
2 | |||
getSubscriptions | |
0.00% |
0 / 14 |
|
0.00% |
0 / 1 |
20 | |||
removeSubscriptions | |
0.00% |
0 / 10 |
|
0.00% |
0 / 1 |
2 | |||
getGroupIdForDatabase | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
6 |
1 | <?php |
2 | declare( strict_types = 1 ); |
3 | |
4 | namespace MediaWiki\Extension\Translate\MessageGroupProcessing; |
5 | |
6 | use Wikimedia\Rdbms\IConnectionProvider; |
7 | use Wikimedia\Rdbms\IResultWrapper; |
8 | |
9 | /** |
10 | * Store service for looking up and storing user subscriptions to message group |
11 | * @since 2024.04 |
12 | * @license GPL-2.0-or-later |
13 | * @author Abijeet Patro |
14 | */ |
15 | class MessageGroupSubscriptionStore { |
16 | private const TABLE_NAME = 'translate_message_group_subscriptions'; |
17 | /** @var int Match field tmgs_group byte length */ |
18 | private const MAX_GROUP_LENGTH = 200; |
19 | private IConnectionProvider $connectionProvider; |
20 | |
21 | public function __construct( IConnectionProvider $connectionProvider ) { |
22 | $this->connectionProvider = $connectionProvider; |
23 | } |
24 | |
25 | public function addSubscription( string $groupId, int $userId ): void { |
26 | $this->connectionProvider->getPrimaryDatabase()->replace( |
27 | self::TABLE_NAME, |
28 | [ [ 'tmgs_group', 'tmgs_user_id' ] ], |
29 | [ |
30 | 'tmgs_group' => self::getGroupIdForDatabase( $groupId ), |
31 | 'tmgs_user_id' => $userId, |
32 | ], |
33 | __METHOD__ |
34 | ); |
35 | } |
36 | |
37 | public function getSubscriptions( ?array $groupIds, ?int $userId ): IResultWrapper { |
38 | $queryBuilder = $this->connectionProvider |
39 | ->getReplicaDatabase() |
40 | ->newSelectQueryBuilder() |
41 | ->select( [ 'tmgs_group', 'tmgs_user_id' ] ) |
42 | ->from( self::TABLE_NAME ) |
43 | ->caller( __METHOD__ ); |
44 | |
45 | if ( $groupIds !== null ) { |
46 | $dbGroupIds = []; |
47 | foreach ( $groupIds as $groupId ) { |
48 | $dbGroupIds[] = self::getGroupIdForDatabase( $groupId ); |
49 | } |
50 | $queryBuilder->where( [ 'tmgs_group' => $dbGroupIds ] ); |
51 | } |
52 | |
53 | if ( $userId !== null ) { |
54 | $queryBuilder->andWhere( [ 'tmgs_user_id' => $userId ] ); |
55 | } |
56 | |
57 | return $queryBuilder->fetchResultSet(); |
58 | } |
59 | |
60 | public function removeSubscriptions( string $groupId, int $userId ): void { |
61 | $conditions = [ |
62 | 'tmgs_group' => $groupId, |
63 | 'tmgs_user_id' => $userId |
64 | ]; |
65 | |
66 | $this->connectionProvider->getPrimaryDatabase() |
67 | ->delete( |
68 | self::TABLE_NAME, |
69 | $conditions, |
70 | __METHOD__ |
71 | ); |
72 | } |
73 | |
74 | private static function getGroupIdForDatabase( string $groupId ): string { |
75 | // Check if length is more than 200 bytes |
76 | if ( strlen( $groupId ) <= self::MAX_GROUP_LENGTH ) { |
77 | return $groupId; |
78 | } |
79 | |
80 | $hash = hash( 'md5', $groupId ); |
81 | // We take 160 bytes of the original string and append the md5 hash (32 bytes) |
82 | return mb_strcut( $groupId, 0, 160 ) . '||' . $hash; |
83 | } |
84 | } |