2declare( strict_types = 1 );
4namespace MediaWiki\Extension\Translate\MessageGroupProcessing;
7use MediaWiki\Page\PageIdentity;
8use Wikimedia\Rdbms\IConnectionProvider;
9use Wikimedia\Rdbms\SelectQueryBuilder;
30 private IConnectionProvider $dbProvider;
31 private array $tagCache = [];
33 public function __construct( IConnectionProvider $dbProvider ) {
34 $this->dbProvider = $dbProvider;
39 PageIdentity $identity,
44 if ( !$identity->exists() ) {
48 $articleId = $identity->getId();
50 $dbw = $this->dbProvider->getPrimaryDatabase();
52 'rt_page' => $articleId,
55 $dbw->newDeleteQueryBuilder()
56 ->deleteFrom(
'revtag' )
57 ->where( $conditions )
58 ->caller( __METHOD__ )
61 if ( $value !==
null ) {
62 $conditions[
'rt_value'] = serialize( implode(
'|', $value ) );
65 $conditions[
'rt_revision'] = $revisionId;
66 $dbw->newInsertQueryBuilder()
67 ->insertInto(
'revtag' )
69 ->caller( __METHOD__ )
72 $this->tagCache[$articleId][$tag] = $revisionId;
75 public function getLatestRevisionWithTag( PageIdentity $identity,
string $tag ): ?int {
76 $response = $this->getLatestRevisionsForTags( $identity, $tag );
77 return $response[$tag] ??
null;
82 if ( !$identity->exists() ) {
86 $articleId = $identity->getId();
92 foreach ( $tags as $tag ) {
93 if ( isset( $this->tagCache[$articleId][$tag] ) ) {
94 $response[$tag] = $this->tagCache[$articleId][$tag];
96 $remainingTags[] = $tag;
100 if ( !$remainingTags ) {
105 $dbr = Utilities::getSafeReadDB();
106 $results = $dbr->newSelectQueryBuilder()
107 ->select( [
'rt_revision' =>
'MAX(rt_revision)',
'rt_type' ] )
110 'rt_page' => $articleId,
111 'rt_type' => $remainingTags
113 ->groupBy(
'rt_type' )
114 ->caller( __METHOD__ )
117 foreach ( $results as $row ) {
118 $response[$row->rt_type] = (int)$row->rt_revision;
124 public function removeTags( PageIdentity $identity,
string ...$tag ): void {
125 if ( !$identity->exists() ) {
129 $articleId = $identity->getId();
131 $dbw = $this->dbProvider->getPrimaryDatabase();
132 $dbw->newDeleteQueryBuilder()
133 ->deleteFrom(
'revtag' )
135 'rt_page' => $articleId,
138 ->caller( __METHOD__ )
141 unset( $this->tagCache[$articleId] );
144 public function isRevIdFuzzy(
int $articleId,
int $revisionId ): bool {
145 $dbw = $this->dbProvider->getPrimaryDatabase();
146 $res = $dbw->newSelectQueryBuilder()
147 ->select(
'rt_type' )
150 'rt_page' => $articleId,
151 'rt_type' => self::FUZZY_TAG,
152 'rt_revision' => $revisionId
154 ->caller( __METHOD__ )
157 return $res !==
false;
172 public function getTransver( PageIdentity $identity, ?
int $revid =
null ): ?int {
174 $query = $db->newSelectQueryBuilder()
175 ->select(
'rt_value' )
178 'rt_page' => $identity->getId(),
179 'rt_type' => self::TRANSVER_PROP,
181 if ( $revid !==
null ) {
182 $query->where( $db->expr(
'rt_revision',
'<=', $revid ) );
185 ->orderBy(
'rt_revision', SelectQueryBuilder::SORT_DESC )
186 ->caller( __METHOD__ )
188 if ( $result ===
false ) {
205 public function setTransver( PageIdentity $identity,
int $translationRevision,
int $transver ) {
206 $dbw = $this->dbProvider->getPrimaryDatabase();
209 'rt_page' => $identity->getId(),
210 'rt_type' => self::TRANSVER_PROP,
211 'rt_revision' => $translationRevision,
212 'rt_value' => $transver,
214 $dbw->newReplaceQueryBuilder()
215 ->replaceInto(
'revtag' )
216 ->uniqueIndexFields( [
'rt_type',
'rt_page',
'rt_revision' ] )
218 ->caller( __METHOD__ )
225 $res = $dbr->newSelectQueryBuilder()
226 ->select(
'rt_page' )
231 [
'rt_page = page_id',
'rt_revision = page_latest',
'rt_type' => $revTags ]
233 ->groupBy(
'rt_page' )
234 ->caller( __METHOD__ )
237 foreach ( $res as $row ) {
238 $results[] = (int)$row->rt_page;