Translate extension for MediaWiki
 
Loading...
Searching...
No Matches
MessageGroupSubscriptionStore.php
1<?php
2declare( strict_types = 1 );
3
4namespace MediaWiki\Extension\Translate\MessageGroupProcessing;
5
7use Wikimedia\Rdbms\IConnectionProvider;
8
16 private const VIRTUAL_DOMAIN = 'virtual-translate';
17 private const TABLE_NAME = 'translate_message_group_subscriptions';
19 private const MAX_GROUP_LENGTH = 200;
20
21 public function __construct(
22 private readonly IConnectionProvider $dbProvider,
23 ) {
24 }
25
26 public function addSubscription( string $groupId, int $userId ): void {
27 $this->dbProvider->getPrimaryDatabase( self::VIRTUAL_DOMAIN )
28 ->newReplaceQueryBuilder()
29 ->replaceInto( self::TABLE_NAME )
30 ->uniqueIndexFields( [ 'tmgs_group', 'tmgs_user_id' ] )
31 ->row( [
32 'tmgs_group' => self::getGroupIdForDatabase( $groupId ),
33 'tmgs_user_id' => $userId,
34 ] )
35 ->caller( __METHOD__ )
36 ->execute();
37 }
38
44 public function getSubscriptions( ?array $groupIds, ?int $userId ): array {
45 $queryBuilder = $this->dbProvider
46 ->getReplicaDatabase( self::VIRTUAL_DOMAIN )
47 ->newSelectQueryBuilder()
48 ->select( [ 'tmgs_group', 'tmgs_user_id' ] )
49 ->from( self::TABLE_NAME )
50 ->caller( __METHOD__ );
51
52 if ( $groupIds ) {
53 $dbGroupIds = array_map( self::getGroupIdForDatabase( ... ), $groupIds );
54 $queryBuilder->where( [ 'tmgs_group' => $dbGroupIds ] );
55 }
56
57 if ( $userId ) {
58 $queryBuilder->andWhere( [ 'tmgs_user_id' => $userId ] );
59 }
60
61 $subscriptions = [];
62 foreach ( $queryBuilder->fetchResultSet() as $row ) {
63 $subscriptions[$row->tmgs_group][] = (int)$row->tmgs_user_id;
64 }
65 return $subscriptions;
66 }
67
72 public function getSubscriptionByGroupUnion( array $groupIds ): array {
73 $userIds = $this->dbProvider
74 ->getReplicaDatabase( self::VIRTUAL_DOMAIN )
75 ->newSelectQueryBuilder()
76 ->select( 'tmgs_user_id' )
77 ->from( self::TABLE_NAME )
78 ->where( [ 'tmgs_group' => $groupIds ] )
79 ->having( 'COUNT(tmgs_group) = ' . count( $groupIds ) )
80 ->caller( __METHOD__ )
81 ->fetchFieldValues();
82 return array_map( intval( ... ), $userIds );
83 }
84
85 public function removeSubscriptions( string $groupId, int $userId ): void {
86 $this->dbProvider->getPrimaryDatabase( self::VIRTUAL_DOMAIN )
87 ->newDeleteQueryBuilder()
88 ->deleteFrom( self::TABLE_NAME )
89 ->where( [
90 'tmgs_group' => $groupId,
91 'tmgs_user_id' => $userId
92 ] )
93 ->caller( __METHOD__ )
94 ->execute();
95 }
96
97 public static function getGroupIdForDatabase( MessageGroup|string $groupId ): string {
98 if ( $groupId instanceof MessageGroup ) {
99 $groupId = $groupId->getId();
100 }
101
102 return strlen( $groupId ) > self::MAX_GROUP_LENGTH ?
103 // Note: mb_strcut operates on bytes but leaves multi-byte characters intact
104 mb_strcut( $groupId, 0, 160 ) . '||' . md5( $groupId ) :
105 $groupId;
106 }
107}
Store service for looking up and storing user subscriptions to message group.
Interface for message groups.