public static function getGroupsWithTransitions(MessageHandle $handle)
 {
     $listeners = array();
     foreach ($handle->getGroupIds() as $id) {
         $group = MessageGroups::getGroup($id);
         // No longer exists?
         if (!$group) {
             continue;
         }
         $conds = $group->getMessageGroupStates()->getConditions();
         if ($conds) {
             $listeners[$id] = $conds;
         }
     }
     return $listeners;
 }
 public function execute()
 {
     $target = $this->getOption('target');
     if (!is_writable($target)) {
         $this->error("Target directory is not writable ({$target}).", 1);
     }
     $threshold = $this->getOption('threshold');
     $noFuzzy = $this->hasOption('no-fuzzy');
     $noLocation = '';
     if ($this->hasOption('no-location')) {
         $noLocation = '--no-location ';
     }
     $skip = array();
     if ($this->hasOption('skip')) {
         $skip = array_map('trim', explode(',', $this->getOption('skip')));
     }
     $reqLangs = TranslateUtils::parseLanguageCodes($this->getOption('lang'));
     $reqLangs = array_flip($reqLangs);
     foreach ($skip as $skipLang) {
         unset($reqLangs[$skipLang]);
     }
     $reqLangs = array_flip($reqLangs);
     $codemapOnly = $this->hasOption('codemaponly');
     $groupIds = explode(',', trim($this->getOption('group')));
     $groupIds = MessageGroups::expandWildcards($groupIds);
     $groups = MessageGroups::getGroupsById($groupIds);
     /** @var FileBasedMessageGroup $group */
     foreach ($groups as $groupId => $group) {
         if ($group->isMeta()) {
             $this->output("Skipping meta message group {$groupId}.\n");
             unset($groups[$groupId]);
             continue;
         }
         if (!$group instanceof FileBasedMessageGroup) {
             $this->output("EE2: Unexportable message group {$groupId}.\n");
             unset($groups[$groupId]);
             continue;
         }
     }
     if (!count($groups)) {
         $this->error("EE1: No valid message groups identified.", 1);
     }
     $changeFilter = false;
     $hours = $this->getOption('hours');
     if ($hours) {
         $namespaces = array();
         /** @var FileBasedMessageGroup $group */
         foreach ($groups as $group) {
             $namespaces[$group->getNamespace()] = true;
         }
         $namespaces = array_keys($namespaces);
         $bots = true;
         $changeFilter = array();
         $rows = TranslateUtils::translationChanges($hours, $bots, $namespaces);
         foreach ($rows as $row) {
             $title = Title::makeTitle($row->rc_namespace, $row->rc_title);
             $handle = new MessageHandle($title);
             $code = $handle->getCode();
             if (!$code) {
                 continue;
             }
             $groupIds = $handle->getGroupIds();
             foreach ($groupIds as $groupId) {
                 $changeFilter[$groupId][$code] = true;
             }
         }
     }
     $skipGroups = array();
     if ($this->hasOption('skipgroup')) {
         $skipGroups = array_map('trim', explode(',', $this->getOption('skipgroup')));
     }
     foreach ($groups as $groupId => $group) {
         if (in_array($groupId, $skipGroups)) {
             $this->output("Group {$groupId} is in skipgroup.\n");
             continue;
         }
         // No changes to this group at all
         if (is_array($changeFilter) && !isset($changeFilter[$groupId])) {
             $this->output("No recent changes to {$groupId}.\n");
             continue;
         }
         $langs = $reqLangs;
         if ($codemapOnly) {
             foreach ($langs as $index => $code) {
                 if ($group->mapCode($code) === $code) {
                     unset($langs[$index]);
                 }
             }
         }
         if ($threshold) {
             $stats = MessageGroupStats::forGroup($groupId);
             foreach ($langs as $index => $code) {
                 if (!isset($stats[$code])) {
                     unset($langs[$index]);
                     continue;
                 }
                 $total = $stats[$code][MessageGroupStats::TOTAL];
                 $translated = $stats[$code][MessageGroupStats::TRANSLATED];
                 if ($translated / $total * 100 < $threshold) {
                     unset($langs[$index]);
                 }
             }
         }
         // Filter out unchanged languages from requested languages
         if (is_array($changeFilter)) {
             $langs = array_intersect($langs, array_keys($changeFilter[$groupId]));
         }
         if (!count($langs)) {
             continue;
         }
         $this->output("Exporting {$groupId}...\n");
         $ffs = $group->getFFS();
         $ffs->setWritePath($target);
         $sourceLanguage = $group->getSourceLanguage();
         $collection = $group->initCollection($sourceLanguage);
         $definitionFile = false;
         if ($this->hasOption('ppgettext') && $ffs instanceof GettextFFS) {
             global $wgMaxShellMemory, $wgTranslateGroupRoot;
             // Need more shell memory for msgmerge.
             $wgMaxShellMemory = 402400;
             $path = $group->getSourceFilePath($sourceLanguage);
             $definitionFile = str_replace($wgTranslateGroupRoot, $this->getOption('ppgettext'), $path);
         }
         $whitelist = $group->getTranslatableLanguages();
         foreach ($langs as $lang) {
             // Do not export languges that are blacklisted (or not whitelisted).
             // Also check that whitelist is not null, which means that all
             // languages are allowed for translation and export.
             if (is_array($whitelist) && !isset($whitelist[$lang])) {
                 continue;
             }
             $collection->resetForNewLanguage($lang);
             $collection->loadTranslations();
             // Don't export ignored, unless it is the source language
             // or message documentation
             global $wgTranslateDocumentationLanguageCode;
             if ($lang !== $wgTranslateDocumentationLanguageCode && $lang !== $sourceLanguage) {
                 $collection->filter('ignored');
             }
             if ($noFuzzy) {
                 $collection->filter('fuzzy');
             }
             $ffs->write($collection);
             // Do post processing if requested.
             if ($definitionFile) {
                 if (is_file($definitionFile)) {
                     $targetFileName = $ffs->getWritePath() . "/" . $group->getTargetFilename($collection->code);
                     $cmd = "msgmerge --quiet " . $noLocation . "--output-file=" . $targetFileName . ' ' . $targetFileName . ' ' . $definitionFile;
                     wfShellExec($cmd, $ret);
                     // Report on errors.
                     if ($ret) {
                         $this->error("ERROR: {$ret}");
                     }
                 } else {
                     $this->error("{$definitionFile} does not exist.", 1);
                 }
             }
         }
     }
 }
예제 #3
0
 /**
  * Returns the message groups this message group is part of.
  * @since 2011-12-25
  * @return array
  */
 public static function getParentGroups(MessageGroup $group)
 {
     // Take the first message, get a handle for it and check
     // if that message belongs to other groups. Those are the
     // parent aggregate groups. Ideally we loop over all keys,
     // but this should be enough.
     $keys = array_keys($group->getDefinitions());
     $title = Title::makeTitle($group->getNamespace(), $keys[0]);
     $handle = new MessageHandle($title);
     $ids = $handle->getGroupIds();
     foreach ($ids as $index => $id) {
         if ($id === $group->getId()) {
             unset($ids[$index]);
         }
     }
     return $ids;
 }
 /**
  * Prevent editing of restricted languages.
  * Hook: getUserPermissionsErrorsExpensive
  * @since 2012-03-01
  */
 public static function preventRestrictedTranslations(Title $title, User $user, $action, &$result)
 {
     global $wgTranslateDocumentationLanguageCode;
     // Preventing editing (includes creation) should be enough
     if ($action !== 'edit') {
         return true;
     }
     $handle = new MessageHandle($title);
     if (!$handle->isValid()) {
         return true;
     }
     // Get the primary group id
     $ids = $handle->getGroupIds();
     $groupId = $ids[0];
     // Check if anything is prevented for the group in the first place
     $force = TranslateMetadata::get($groupId, 'priorityforce');
     if ($force !== 'on') {
         return true;
     }
     // Allow adding message documentation even when translation is restricted
     if ($handle->getCode() === $wgTranslateDocumentationLanguageCode) {
         return true;
     }
     // And finally check whether the language is not included in whitelist
     $languages = TranslateMetadata::get($groupId, 'prioritylangs');
     $filter = array_flip(explode(',', $languages));
     if (!isset($filter[$handle->getCode()])) {
         // @todo Default reason if none provided
         $reason = TranslateMetadata::get($groupId, 'priorityreason');
         $result = array('tpt-translation-restricted', $reason);
         return false;
     }
     return true;
 }
	public static function update( MessageHandle $handle, $changes = array() ) {
		$dbw = wfGetDB( DB_MASTER );
		$conds = array(
			'tgs_group' => $handle->getGroupIds(),
			'tgs_lang' => $handle->getCode(),
		);

		$values = array();
		foreach ( array( 'total', 'translated', 'fuzzy' ) as $type ) {
			if ( !isset( $changes[$type] ) ) {
				$values[] = "tgs_$type=tgs_$type" .
					self::stringifyNumber( $changes[$type] );
			}
		}

		$dbw->update( self::TABLE, $values, $conds, __METHOD__ );
	}
 /**
  * @see schema.xml
  */
 protected function createDocument(MessageHandle $handle, $text, $revId)
 {
     $language = $handle->getCode();
     $translationTitle = $handle->getTitle();
     $title = Title::makeTitle($handle->getTitle()->getNamespace(), $handle->getKey());
     $wiki = wfWikiId();
     $messageid = $title->getPrefixedText();
     $globalid = "{$wiki}-{$messageid}-{$revId}/{$language}";
     $doc = new Solarium_Document_ReadWrite();
     $doc->wiki = $wiki;
     $doc->uri = $translationTitle->getCanonicalUrl();
     $doc->messageid = $messageid;
     $doc->globalid = $globalid;
     $doc->language = $language;
     $doc->content = $text;
     $doc->setField('group', $handle->getGroupIds());
     return $doc;
 }
 /**
  * @return \Elastica\Document
  */
 protected function createDocument(MessageHandle $handle, $text, $revId)
 {
     $language = $handle->getCode();
     $localid = $handle->getTitleForBase()->getPrefixedText();
     $wiki = wfWikiId();
     $globalid = "{$wiki}-{$localid}-{$revId}/{$language}";
     $data = array('wiki' => $wiki, 'uri' => $handle->getTitle()->getCanonicalUrl(), 'localid' => $localid, 'language' => $language, 'content' => $text, 'group' => $handle->getGroupIds());
     return new \Elastica\Document($globalid, $data);
 }