/** * @param $authors array * @param $code string * @return array */ protected function filterAuthors( array $authors, $code ) { global $wgTranslateAuthorBlacklist; $groupId = $this->group->getId(); foreach ( $authors as $i => $v ) { $hash = "$groupId;$code;$v"; $blacklisted = false; foreach ( $wgTranslateAuthorBlacklist as $rule ) { list( $type, $regex ) = $rule; if ( preg_match( $regex, $hash ) ) { if ( $type === 'white' ) { $blacklisted = false; break; } else { $blacklisted = true; } } } if ( $blacklisted ) { unset( $authors[$i] ); } } return $authors; }
/** * MediaWiki extensions all should have key in their i18n files * describing them. This override method implements the logic * to retrieve them. Also URLs are included if available. * Needs the Configure extension. * @param IContextSource $context * @return string */ public function getDescription(IContextSource $context = null) { $language = $this->getSourceLanguage(); if ($context) { $language = $context->getLanguage()->getCode(); } $msgkey = $this->getFromConf('BASIC', 'descriptionmsg'); $desc = ''; if ($msgkey) { $desc = $this->getMessage($msgkey, $language); if (strval($desc) === '') { $desc = $this->getMessage($msgkey, $this->getSourceLanguage()); } } if (strval($desc) === '') { // That failed, default to 'description' $desc = parent::getDescription($context); } $url = $this->getFromConf('BASIC', 'extensionurl'); if ($url) { $desc .= "\n\n{$url}"; } return $desc; }
/** * This is the detective novel. We have three sources of information: * - current message state in the file * - current message state in the wiki * - cached message state since cache was last build * (usually after export from wiki) * * Now we must try to guess what in earth has driven the file state and * wiki state out of sync. Then we must compile list of events that would * bring those to sync. Types of events are addition, deletion, (content) * change and possible rename in the future. After that the list of events * are stored for later processing of a translation administrator, who can * decide what actions to take on those events to bring the state more or * less in sync. * * @param FileBasedMessageGroup $group * @param string $code Language code. * @param int $reason * @param MessageGroupCache $cache * @throws MWException */ protected function addMessageUpdateChanges(FileBasedMessageGroup $group, $code, $reason, $cache) { /* This throws a warning if message definitions are not yet * cached and will read the file for definitions. */ wfSuppressWarnings(); $wiki = $group->initCollection($code); wfRestoreWarnings(); $wiki->filter('hastranslation', false); $wiki->loadTranslations(); $wikiKeys = $wiki->getMessageKeys(); // By-pass cached message definitions /** @var FFS $ffs */ $ffs = $group->getFFS(); if ($code === $group->getSourceLanguage() && !$ffs->exists($code)) { $path = $group->getSourceFilePath($code); throw new MWException("Source message file for {$group->getId()} does not exist: {$path}"); } $file = $ffs->read($code); // Does not exist if ($file === false) { return; } // Something went wrong if (!isset($file['MESSAGES'])) { $id = $group->getId(); $ffsClass = get_class($ffs); error_log("{$id} has an FFS ({$ffsClass}) - it didn't return cake for {$code}"); return; } $fileKeys = array_keys($file['MESSAGES']); $common = array_intersect($fileKeys, $wikiKeys); $supportsFuzzy = $ffs->supportsFuzzy(); foreach ($common as $key) { $sourceContent = $file['MESSAGES'][$key]; /** @var TMessage $wikiMessage */ $wikiMessage = $wiki[$key]; $wikiContent = $wikiMessage->translation(); // If FFS doesn't support it, ignore fuzziness as difference $wikiContent = str_replace(TRANSLATE_FUZZY, '', $wikiContent); // But if it does, ensure we have exactly one fuzzy marker prefixed if ($supportsFuzzy === 'yes' && $wikiMessage->hasTag('fuzzy')) { $wikiContent = TRANSLATE_FUZZY . $wikiContent; } if (self::compareContent($sourceContent, $wikiContent)) { // File and wiki stage agree, nothing to do continue; } // Check against interim cache to see whether we have changes // in the wiki, in the file or both. if ($reason !== MessageGroupCache::NO_CACHE) { $cacheContent = $cache->get($key); /* We want to ignore the common situation that the string * in the wiki has been changed since the last export. * Hence we check that source === cache && cache !== wiki * and if so we skip this string. */ if (!self::compareContent($wikiContent, $cacheContent) && self::compareContent($sourceContent, $cacheContent)) { continue; } } $this->addChange('change', $code, $key, $sourceContent); } $added = array_diff($fileKeys, $wikiKeys); foreach ($added as $key) { $sourceContent = $file['MESSAGES'][$key]; if (trim($sourceContent) === '') { continue; } $this->addChange('addition', $code, $key, $sourceContent); } /* Should the cache not exist, don't consider the messages * missing from the file as deleted - they probably aren't * yet exported. For example new language translations are * exported the first time. */ if ($reason !== MessageGroupCache::NO_CACHE) { $deleted = array_diff($wikiKeys, $fileKeys); foreach ($deleted as $key) { if ($cache->get($key) === false) { /* This message has never existed in the cache, so it * must be a newly made in the wiki. */ continue; } $this->addChange('deletion', $code, $key, null); } } }
public function mapCode($code) { return ucfirst(str_replace('-', '_', parent::mapCode($code))); }
public function output() { if (MessageGroups::isDynamic($this->group)) { return 'Not supported'; } $ffs = null; if ($this->group instanceof FileBasedMessageGroup) { $ffs = $this->group->getFFS(); } if (!$ffs instanceof GettextFFS) { $group = FileBasedMessageGroup::newFromMessageGroup($this->group); $ffs = new GettextFFS($group); } $ffs->setOfflineMode('true'); $code = $this->options['language']; $id = $this->group->getID(); $filename = "{$id}_{$code}.po"; header("Content-Disposition: attachment; filename=\"{$filename}\""); return $ffs->writeIntoVariable($this->collection); }