32 Title $target,
string $content, $fuzzy =
false
35 'content' => $content,
39 $job =
new self( $target, $params );
60 array $otherLangContents = []
63 'target' => $targetStr,
64 'replacement' => $replacement,
67 'content' => $content,
68 'otherLangs' => $otherLangContents
71 $job =
new self( $target, $params );
81 parent::__construct( __CLASS__, $title, $params );
84 public function run() {
85 $params = $this->params;
86 $user = FuzzyBot::getUser();
87 $flags = EDIT_FORCE_BOT;
88 $isRename = $params[
'rename'] ??
false;
89 $isFuzzy = $params[
'fuzzy'] ??
false;
90 $otherLangs = $params[
'otherLangs'] ?? [];
91 $originalTitle = Title::newFromLinkTarget( $this->title->getTitleValue(), Title::NEW_CLONE );
94 $this->title = $this->handleRename( $params[
'target'], $params[
'replacement'], $user );
95 if ( $this->title ===
null ) {
98 'Rename process could not find the source title.',
100 'replacement' => $params[
'replacement'],
101 'target' => $params[
'target']
105 $this->removeFromCache( $originalTitle );
110 $title = $this->title;
111 $wikiPage = MediaWikiServices::getInstance()->getWikiPageFactory()->newFromTitle( $title );
112 $summary = wfMessage(
'translate-manage-import-summary' )
113 ->inContentLanguage()->plain();
114 $content = ContentHandler::makeContent( $params[
'content'], $title );
115 $editStatus = $wikiPage->doUserEditContent(
121 if ( !$editStatus->isOK() ) {
123 'Failed to update content for source message',
125 'content' => $content,
126 'errors' => $editStatus->getErrors()
133 $this->processTranslationChanges(
134 $otherLangs, $params[
'replacement'], $params[
'namespace'], $summary, $flags, $user
139 $this->handleFuzzy( $title );
142 $this->removeFromCache( $originalTitle );
153 private function handleRename( $target, $replacement, User $user ) {
154 $newSourceTitle =
null;
157 $movableTitles = TranslateReplaceTitle::getTitlesForMove( $sourceMessageHandle, $replacement );
159 if ( $movableTitles === [] ) {
161 'No moveable titles found with target text.',
163 'title' => $this->title->getPrefixedText(),
164 'replacement' => $replacement,
171 $renameSummary = wfMessage(
'translate-manage-import-rename-summary' )
172 ->inContentLanguage()->plain();
174 foreach ( $movableTitles as [ $sourceTitle, $replacementTitle ] ) {
175 $mv = MediaWikiServices::getInstance()
176 ->getMovePageFactory()
177 ->newMovePage( $sourceTitle, $replacementTitle );
179 $status = $mv->move( $user, $renameSummary,
false );
180 if ( !$status->isOK() ) {
182 'Error moving message',
184 'target' => $sourceTitle->getPrefixedText(),
185 'replacement' => $replacementTitle->getPrefixedText(),
186 'errors' => $status->getErrors()
192 if ( !$newSourceTitle && $sourceMessageHandle->getCode() === $targetCode ) {
193 $newSourceTitle = $replacementTitle;
197 if ( $newSourceTitle ) {
198 return $newSourceTitle;
203 'Source title was not in the list of moveable titles.',
204 [
'title' => $this->title->getPrefixedText() ]
214 private function handleFuzzy( Title $title ) {
215 global $wgTranslateDocumentationLanguageCode;
221 unset( $languages[$wgTranslateDocumentationLanguageCode] );
222 $languages = array_keys( $languages );
224 $dbw = wfGetDB( DB_PRIMARY );
225 $fields = [
'page_id',
'page_latest' ];
226 $conds = [
'page_namespace' => $title->getNamespace() ];
229 foreach ( $languages as $code ) {
230 $otherTitle = $handle->getTitleForLanguage( $code );
231 $pages[$otherTitle->getDBkey()] =
true;
235 unset( $pages[$title->getDBkey()] );
237 if ( $pages === [] ) {
241 $conds[
'page_title'] = array_keys( $pages );
243 $res = $dbw->select(
'page', $fields, $conds, __METHOD__ );
245 foreach ( $res as $row ) {
247 'rt_type' => RevTagStore::FUZZY_TAG,
248 'rt_page' => $row->page_id,
249 'rt_revision' => $row->page_latest,
253 if ( $inserts === [] ) {
259 [ [
'rt_type',
'rt_page',
'rt_revision' ] ],
274 private function processTranslationChanges(
275 array $langChanges, $baseTitle, $groupNamespace, $summary, $flags, User $user
277 $wikiPageFactory = MediaWikiServices::getInstance()->getWikiPageFactory();
278 foreach ( $langChanges as $code => $contentStr ) {
280 $title = Title::newFromText( $titleStr, $groupNamespace );
281 $wikiPage = $wikiPageFactory->newFromTitle( $title );
282 $content = ContentHandler::makeContent( $contentStr, $title );
283 $status = $wikiPage->doUserEditContent(
289 if ( !$status->isOK() ) {
291 'Failed to update content for non-source message',
293 'title' => $title->getPrefixedText(),
294 'errors' => $status->getErrors()
301 private function removeFromCache( Title $title ): void {
302 $config = MediaWikiServices::getInstance()->getMainConfig();
304 if ( !$config->get(
'TranslateGroupSynchronizationCache' ) ) {
308 $currentTitle = $title;
311 if ( $this->title && $this->title->getPrefixedDBkey() !== $title->getPrefixedDBkey() ) {
312 $currentTitle = $this->title;
316 $groupIds = $sourceMessageHandle->getGroupIds();
319 "Could not find group Id for message title: {$currentTitle->getPrefixedDBkey()}",
325 $groupId = $groupIds[0];
332 $groupSyncCache = Services::getInstance()->getGroupSynchronizationCache();
333 $messageKey = $title->getPrefixedDBkey();
335 if ( $groupSyncCache->isMessageBeingProcessed( $groupId, $messageKey ) ) {
336 $groupSyncCache->removeMessages( $groupId, $messageKey );
337 $groupSyncCache->extendGroupExpiryTime( $groupId );
340 "Did not find key: $messageKey; in group: $groupId in group sync cache",