34 Title $target,
string $content, $fuzzy =
false
37 'content' => $content,
41 $job =
new self( $target, $params );
62 array $otherLangContents = []
65 'target' => $targetStr,
66 'replacement' => $replacement,
69 'content' => $content,
70 'otherLangs' => $otherLangContents
73 $job =
new self( $target, $params );
83 parent::__construct( __CLASS__, $title, $params );
86 public function run() {
87 $params = $this->params;
88 $user = FuzzyBot::getUser();
89 $flags = EDIT_FORCE_BOT;
90 $isRename = $params[
'rename'] ??
false;
91 $isFuzzy = $params[
'fuzzy'] ??
false;
92 $otherLangs = $params[
'otherLangs'] ?? [];
93 $originalTitle = Title::newFromLinkTarget( $this->title->getTitleValue(), Title::NEW_CLONE );
96 $this->title = $this->handleRename( $params[
'target'], $params[
'replacement'], $user );
97 if ( $this->title ===
null ) {
100 'Rename process could not find the source title.',
102 'replacement' => $params[
'replacement'],
103 'target' => $params[
'target']
107 $this->removeFromCache( $originalTitle );
112 $title = $this->title;
113 $wikiPage = MediaWikiServices::getInstance()->getWikiPageFactory()->newFromTitle( $title );
114 $summary = wfMessage(
'translate-manage-import-summary' )
115 ->inContentLanguage()->plain();
116 $content = ContentHandler::makeContent( $params[
'content'], $title );
117 $editStatus = $wikiPage->doUserEditContent(
123 if ( !$editStatus->isOK() ) {
125 'Failed to update content for source message',
127 'content' => $content,
128 'errors' => $editStatus->getErrors()
135 $this->processTranslationChanges(
136 $otherLangs, $params[
'replacement'], $params[
'namespace'], $summary, $flags, $user
141 $this->handleFuzzy( $title );
144 $this->removeFromCache( $originalTitle );
155 private function handleRename( $target, $replacement, User $user ) {
156 $newSourceTitle =
null;
159 $movableTitles = TranslateReplaceTitle::getTitlesForMove( $sourceMessageHandle, $replacement );
161 if ( $movableTitles === [] ) {
163 'No moveable titles found with target text.',
165 'title' => $this->title->getPrefixedText(),
166 'replacement' => $replacement,
173 $renameSummary = wfMessage(
'translate-manage-import-rename-summary' )
174 ->inContentLanguage()->plain();
176 foreach ( $movableTitles as [ $sourceTitle, $replacementTitle ] ) {
177 $mv = MediaWikiServices::getInstance()
178 ->getMovePageFactory()
179 ->newMovePage( $sourceTitle, $replacementTitle );
181 $status = $mv->move( $user, $renameSummary,
false );
182 if ( !$status->isOK() ) {
184 'Error moving message',
186 'target' => $sourceTitle->getPrefixedText(),
187 'replacement' => $replacementTitle->getPrefixedText(),
188 'errors' => $status->getErrors()
193 [ , $targetCode ] = Utilities::figureMessage( $replacementTitle->getText() );
194 if ( !$newSourceTitle && $sourceMessageHandle->getCode() === $targetCode ) {
195 $newSourceTitle = $replacementTitle;
199 if ( $newSourceTitle ) {
200 return $newSourceTitle;
205 'Source title was not in the list of moveable titles.',
206 [
'title' => $this->title->getPrefixedText() ]
216 private function handleFuzzy( Title $title ) {
217 global $wgTranslateDocumentationLanguageCode;
220 $languages = Utilities::getLanguageNames(
'en' );
223 unset( $languages[$wgTranslateDocumentationLanguageCode] );
224 $languages = array_keys( $languages );
227 foreach ( $languages as $code ) {
228 $otherTitle = $handle->getTitleForLanguage( $code );
229 $pages[$otherTitle->getDBkey()] =
true;
233 unset( $pages[$title->getDBkey()] );
235 if ( $pages === [] ) {
239 $dbw = MediaWikiServices::getInstance()
240 ->getDBLoadBalancer()
241 ->getMaintenanceConnectionRef( DB_PRIMARY );
242 $fields = [
'page_id',
'page_latest' ];
243 $conds = [
'page_namespace' => $title->getNamespace() ];
244 $conds[
'page_title'] = array_keys( $pages );
246 $res = $dbw->select(
'page', $fields, $conds, __METHOD__ );
248 foreach ( $res as $row ) {
250 'rt_type' => RevTagStore::FUZZY_TAG,
251 'rt_page' => $row->page_id,
252 'rt_revision' => $row->page_latest,
256 if ( $inserts === [] ) {
262 [ [
'rt_type',
'rt_page',
'rt_revision' ] ],
277 private function processTranslationChanges(
278 array $langChanges, $baseTitle, $groupNamespace, $summary, $flags, User $user
280 $wikiPageFactory = MediaWikiServices::getInstance()->getWikiPageFactory();
281 foreach ( $langChanges as $code => $contentStr ) {
282 $titleStr = Utilities::title( $baseTitle, $code, $groupNamespace );
283 $title = Title::newFromText( $titleStr, $groupNamespace );
284 $wikiPage = $wikiPageFactory->newFromTitle( $title );
285 $content = ContentHandler::makeContent( $contentStr, $title );
286 $status = $wikiPage->doUserEditContent(
292 if ( !$status->isOK() ) {
294 'Failed to update content for non-source message',
296 'title' => $title->getPrefixedText(),
297 'errors' => $status->getErrors()
304 private function removeFromCache( Title $title ): void {
305 $config = MediaWikiServices::getInstance()->getMainConfig();
307 if ( !$config->get(
'TranslateGroupSynchronizationCache' ) ) {
311 $currentTitle = $title;
314 if ( $this->title && $this->title->getPrefixedDBkey() !== $title->getPrefixedDBkey() ) {
315 $currentTitle = $this->title;
319 $groupIds = $sourceMessageHandle->getGroupIds();
322 "Could not find group Id for message title: {$currentTitle->getPrefixedDBkey()}",
328 $groupId = $groupIds[0];
329 $group = MessageGroups::getGroup( $groupId );
335 $groupSyncCache = Services::getInstance()->getGroupSynchronizationCache();
336 $messageKey = $title->getPrefixedDBkey();
338 if ( $groupSyncCache->isMessageBeingProcessed( $groupId, $messageKey ) ) {
339 $groupSyncCache->removeMessages( $groupId, $messageKey );
340 $groupSyncCache->extendGroupExpiryTime( $groupId );
343 "Did not find key: $messageKey; in group: $groupId in group sync cache",