Пример #1
0
 public static function forItem($groupId, $code)
 {
     # Check again if already in db ( to avoid overload in big clusters )
     $dbr = wfGetDB(DB_SLAVE);
     $res = $dbr->select('groupstats', '*', array('gs_group' => $groupId, 'gs_lang' => $code));
     if ($row = $dbr->fetchRow($res)) {
         // convert to array
         return $row;
     }
     // get group object
     $g = MessageGroups::getGroup($groupId);
     # Calculate if missing and store in the db
     $collection = $g->initCollection($code);
     $collection->filter('optional');
     // Store the count of real messages for later calculation.
     $total = count($collection);
     // Count fuzzy first
     $collection->filter('fuzzy');
     $fuzzy = $total - count($collection);
     // Count the completion percent
     $collection->filter('translated', false);
     $translated = count($collection);
     $data = array('gs_group' => $groupId, 'gs_lang' => $code, 'gs_total' => $total, 'gs_translated' => $translated, 'gs_fuzzy' => $fuzzy);
     # store result in DB
     $dbw = wfGetDB(DB_MASTER);
     $dbw->insert('groupstats', $data, __METHOD__);
     return $data;
 }
 public function testMessage()
 {
     $user = new MockSuperUser();
     $user->setId(123);
     $title = Title::newFromText('MediaWiki:translated/fi');
     $page = WikiPage::factory($title);
     $content = ContentHandler::makeContent('pupuliini', $title);
     $status = $page->doEditContent($content, __METHOD__, 0, false, $user);
     $value = $status->getValue();
     $rev = $value['revision'];
     $revision = $rev->getId();
     $group = MessageGroups::getGroup('test-group');
     $collection = $group->initCollection('fi');
     $collection->loadTranslations();
     /** @var TMessage $translated */
     $translated = $collection['translated'];
     $this->assertInstanceof('TMessage', $translated);
     $this->assertEquals('translated', $translated->key());
     $this->assertEquals('bunny', $translated->definition());
     $this->assertEquals('pupuliini', $translated->translation());
     $this->assertEquals('SuperUser', $translated->getProperty('last-translator-text'));
     $this->assertEquals(123, $translated->getProperty('last-translator-id'));
     $this->assertEquals('translated', $translated->getProperty('status'), 'message status is translated');
     $this->assertEquals($revision, $translated->getProperty('revision'));
     /** @var TMessage $untranslated */
     $untranslated = $collection['untranslated'];
     $this->assertInstanceof('TMessage', $untranslated);
     $this->assertEquals(null, $untranslated->translation(), 'no translation is null');
     $this->assertEquals(false, $untranslated->getProperty('last-translator-text'));
     $this->assertEquals(false, $untranslated->getProperty('last-translator-id'));
     $this->assertEquals('untranslated', $untranslated->getProperty('status'), 'message status is untranslated');
     $this->assertEquals(false, $untranslated->getProperty('revision'));
 }
 public function execute()
 {
     $params = $this->extractRequestParams();
     $title = Title::newFromText($params['title']);
     if (!$title) {
         $this->dieUsage('Invalid title', 'invalidtitle');
     }
     $handle = new MessageHandle($title);
     if (!$handle->isValid()) {
         $this->dieUsage('Title does not correspond to a translatable message', 'nomessagefortitle');
     }
     if (strval($params['group']) !== '') {
         $group = MessageGroups::getGroup($params['group']);
     } else {
         $group = $handle->getGroup();
     }
     if (!$group) {
         $this->dieUsage('Invalid group', 'invalidgroup');
     }
     $data = array();
     $times = array();
     $props = $params['prop'];
     $aggregator = new QueryAggregator();
     // Figure out the intersection of supported and requested aids
     $types = $group->getTranslationAids();
     $props = array_intersect($props, array_keys($types));
     $result = $this->getResult();
     // Create list of aids, populate web services queries
     $aids = array();
     foreach ($props as $type) {
         $class = $types[$type];
         $obj = new $class($group, $handle, $this);
         if ($obj instanceof QueryAggregatorAware) {
             $obj->setQueryAggregator($aggregator);
             $obj->populateQueries();
         }
         $aids[$type] = $obj;
     }
     // Execute all web service queries asynchronously to save time
     $start = microtime(true);
     $aggregator->run();
     $times['query_aggregator'] = round(microtime(true) - $start, 3);
     // Construct the result data structure
     foreach ($aids as $type => $obj) {
         $start = microtime(true);
         try {
             $aid = $obj->getData();
         } catch (TranslationHelperException $e) {
             $aid = array('error' => $e->getMessage());
         }
         if (isset($aid['**'])) {
             $result->setIndexedTagName($aid, $aid['**']);
             unset($aid['**']);
         }
         $data[$type] = $aid;
         $times[$type] = round(microtime(true) - $start, 3);
     }
     $result->addValue(null, 'helpers', $data);
     $result->addValue(null, 'times', $times);
 }
	/**
	 * @param $resultPageSet ApiPageSet
	 */
	private function run( $resultPageSet = null ) {
		$params = $this->extractRequestParams();

		$group = MessageGroups::getGroup( $params['group'] );
		if ( !$group ) {
			$this->dieUsageMsg( array( 'missingparam', 'mcgroup' ) );
		}

		$messages = $group->initCollection( $params['language'] );
		$messages->setInFile( $group->load( $params['language'] ) );

		foreach ( $params['filter'] as $filter ) {
			$value = null;
			if ( strpos( $filter, ':' ) !== false ) {
				list( $filter, $value ) = explode( ':', $filter, 2 );
			}
			/* The filtering params here are swapped wrt MessageCollection.
			 * There (fuzzy) means do not show fuzzy, which is the same as !fuzzy
			 * here and fuzzy here means (fuzzy, false) there. */
			if ( $filter[0] === '!' ) {
				$messages->filter( substr( $filter, 1 ), true, $value );
			} else {
				$messages->filter( $filter, false, $value );
			}
		}

		$messages->slice( $params['offset'], $params['limit'] + 1 );

		$messages->loadTranslations();

		$result = $this->getResult();
		$pages = array();
		$count = 0;

		$props = array_flip( $params['prop'] );
		foreach ( $messages->keys() as $mkey => $title ) {
			if ( ++$count > $params['limit'] ) {
					$this->setContinueEnumParameter( 'offset', $params['offset'] + $count - 1 );
					break;
			}

			if ( is_null( $resultPageSet ) ) {
				$data = $this->extractMessageData( $result, $props, $messages[$mkey] );
				$fit = $result->addValue( array( 'query', $this->getModuleName() ), null, $data );
				if ( !$fit ) {
					$this->setContinueEnumParameter( 'offset', $params['offset'] + $count - 1 );
					break;
				}
			} else {
				$pages[] = $title;
			}
		}

		if ( is_null( $resultPageSet ) ) {
			$result->setIndexedTagName_internal( array( 'query', $this->getModuleName() ), 'message' );
		} else {
			$resultPageSet->populateFromTitles( $pages );
		}

	}
 public function execute()
 {
     $user = $this->getUser();
     $requestParams = $this->extractRequestParams();
     $group = MessageGroups::getGroup($requestParams['group']);
     $code = $requestParams['language'];
     if (!$group || MessageGroups::isDynamic($group)) {
         $this->dieUsageMsg(array('missingparam', 'group'));
     }
     $stateConfig = $group->getMessageGroupStates()->getStates();
     if (!$stateConfig) {
         $this->dieUsage('Message group review not in use', 'disabled');
     }
     if (!$user->isAllowed(self::$right)) {
         $this->dieUsage('Permission denied', 'permissiondenied');
     }
     if ($user->isBlocked()) {
         $this->dieUsage('You have been blocked', 'blocked');
     }
     $requestParams = $this->extractRequestParams();
     $languages = Language::fetchLanguageNames();
     if (!isset($languages[$code])) {
         $this->dieUsageMsg(array('missingparam', 'language'));
     }
     $targetState = $requestParams['state'];
     if (!isset($stateConfig[$targetState])) {
         $this->dieUsage('The requested state is invalid', 'invalidstate');
     }
     if (is_array($stateConfig[$targetState]) && isset($stateConfig[$targetState]['right']) && !$user->isAllowed($stateConfig[$targetState]['right'])) {
         $this->dieUsage('Permission denied', 'permissiondenied');
     }
     self::changeState($group, $code, $targetState, $user);
     $output = array('review' => array('group' => $group->getId(), 'language' => $code, 'state' => $targetState));
     $this->getResult()->addValue(null, $this->getModuleName(), $output);
 }
Пример #6
0
 public function execute()
 {
     global $wgUser, $wgTranslateWorkflowStates;
     if (!$wgTranslateWorkflowStates) {
         $this->dieUsage('Message group review not in use', 'disabled');
     }
     if (!$wgUser->isallowed(self::$right)) {
         $this->dieUsage('Permission denied', 'permissiondenied');
     }
     $requestParams = $this->extractRequestParams();
     $group = MessageGroups::getGroup($requestParams['group']);
     if (!$group) {
         $this->dieUsageMsg(array('missingparam', 'group'));
     }
     $languages = Language::getLanguageNames(false);
     if (!isset($languages[$requestParams['language']])) {
         $this->dieUsageMsg(array('missingparam', 'language'));
     }
     $dbr = wfGetDB(DB_SLAVE);
     $groupid = $group->getId();
     $currentState = $dbr->selectField('translate_groupreviews', 'tgr_state', array('tgr_group' => $groupid, 'tgr_lang' => $requestParams['language']), __METHOD__);
     if ($currentState == $requestParams['state']) {
         $this->dieUsage('The requested state is identical to the current state', 'sameworkflowstate');
     }
     $dbw = wfGetDB(DB_MASTER);
     $table = 'translate_groupreviews';
     $row = array('tgr_group' => $groupid, 'tgr_lang' => $requestParams['language'], 'tgr_state' => $requestParams['state']);
     $index = array('tgr_group', 'tgr_language');
     $res = $dbw->replace($table, array($index), $row, __METHOD__);
     $logger = new LogPage('translationreview');
     $logParams = array($requestParams['language'], $group->getLabel(), $currentState, $requestParams['state']);
     $logger->addEntry('group', SpecialPage::getTitleFor('Translate', $groupid), '', $logParams, $wgUser);
     $output = array('review' => array('group' => $group->getId(), 'language' => $requestParams['language'], 'state' => $requestParams['state']));
     $this->getResult()->addValue(null, $this->getModuleName(), $output);
 }
	/**
	 * Group is either MessageGroup object or group id.
	 * @param $group MessagerGroup|string
	 */
	public function setGroup( $group ) {
		if ( $group instanceof MessageGroup ) {
			$this->group = $group;
		} else {
			$this->group = MessageGroups::getGroup( $group );
		}
	}
	/**
	 * Contructs a new cache object for given group and language code.
	 * @param $group \types{String,FileBasedMessageGroup} Group object or id.
	 * @param $code \string Language code. Default value 'en'.
	 */
	public function __construct( $group, $code = 'en' ) {
		if ( is_object( $group ) ) {
			$this->group = $group;
		} else {
			$this->group = MessageGroups::getGroup( $group );
		}
		$this->code = $code;
	}
	/**
	 * Returns stats for all languages in given group.
	 * @param $id string Group id
	 * @return Array
	 */
	public static function forGroup( $id ) {
		$group = MessageGroups::getGroup( $id );
		if ( $group === null ) {
			return array();
		}
		$stats = self::forGroupInternal( $group );
		return $stats[$id];
	}
 protected function isValidValue($value)
 {
     $group = MessageGroups::getGroup($value);
     if ($group) {
         $this->target = $group->getId();
     }
     return (bool) $group;
 }
 public function testHaveSingleSourceLanguage()
 {
     $this->setMwGlobals(array('wgTranslateGroupFiles' => array(__DIR__ . '/data/MixedSourceLanguageGroups.yaml')));
     MessageGroups::singleton()->recache();
     $enGroup1 = MessageGroups::getGroup('EnglishGroup1');
     $enGroup2 = MessageGroups::getGroup('EnglishGroup2');
     $teGroup1 = MessageGroups::getGroup('TeluguGroup1');
     $this->assertEquals('en', MessageGroups::haveSingleSourceLanguage(array($enGroup1, $enGroup2)));
     $this->assertEquals('', MessageGroups::haveSingleSourceLanguage(array($enGroup1, $enGroup2, $teGroup1)));
 }
Пример #12
0
 /**
  * Tries to determine to which group this message belongs. It tries to get
  * group id from loadgroup GET-paramater, but fallbacks to messageIndex file
  * if no valid group was provided.
  *
  * @return MessageGroup which the key belongs to, or null.
  */
 protected function getMessageGroup(MessageHandle $handle, $groupId)
 {
     $mg = MessageGroups::getGroup($groupId);
     # If we were not given (a valid) group
     if ($mg === null) {
         $groupId = MessageIndex::getPrimaryGroupId($handle);
         $mg = MessageGroups::getGroup($groupId);
     }
     return $mg;
 }
 protected function getData()
 {
     $params = $this->extractRequestParams();
     $group = MessageGroups::getGroup($params['group']);
     if (!$group) {
         $this->dieUsageMsg(array('missingparam', 'mcgroup'));
     } elseif (MessageGroups::isDynamic($group)) {
         $this->dieUsage('Dynamic message groups are not supported here', 'invalidparam');
     }
     return MessageGroupStats::forGroup($group->getId());
 }
 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;
 }
 protected function formatTranslation(StashedTranslation $translation)
 {
     $title = $translation->getTitle();
     $handle = new MessageHandle($title);
     // Prepare for the worst
     $definition = '';
     $comparison = '';
     if ($handle->isValid()) {
         $groupId = MessageIndex::getPrimaryGroupId($handle);
         $group = MessageGroups::getGroup($groupId);
         $key = $handle->getKey();
         $definition = $group->getMessage($key, $group->getSourceLanguage());
         $comparison = $group->getMessage($key, $handle->getCode());
     }
     return array('title' => $title->getPrefixedText(), 'definition' => $definition, 'translation' => $translation->getValue(), 'comparison' => $comparison, 'metadata' => $translation->getMetadata());
 }
 /**
  * @group Broken
  * This tests fails regularly on WMF CI but haven't been able to reproduce locally.
  */
 public function testHooks()
 {
     $user = new MockSuperUser();
     $group = MessageGroups::getGroup('group-trans');
     // In the beginning...
     $currentState = ApiGroupReview::getState($group, 'fi');
     $this->assertEquals(false, $currentState, 'groups start from unset state');
     // First translation
     $title = Title::newFromText('MediaWiki:key1/fi');
     $page = WikiPage::factory($title);
     $content = ContentHandler::makeContent('trans1', $title);
     $status = $page->doEditContent($content, __METHOD__, 0, false, $user);
     self::runJobs();
     $currentState = ApiGroupReview::getState($group, 'fi');
     $this->assertEquals('inprogress', $currentState, 'in progress after first translation');
     // First review
     ApiTranslationReview::doReview($user, self::getRevision($status), __METHOD__);
     self::runJobs();
     $currentState = ApiGroupReview::getState($group, 'fi');
     $this->assertEquals('inprogress', $currentState, 'in progress while untranslated messages');
     // Second translation
     $title = Title::newFromText('MediaWiki:key2/fi');
     $page = WikiPage::factory($title);
     $content = ContentHandler::makeContent('trans2', $title);
     $status = $page->doEditContent($content, __METHOD__, 0, false, $user);
     self::runJobs();
     $currentState = ApiGroupReview::getState($group, 'fi');
     $this->assertEquals('proofreading', $currentState, 'proofreading after second translation');
     // Second review
     ApiTranslationReview::doReview($user, self::getRevision($status), __METHOD__);
     self::runJobs();
     $currentState = ApiGroupReview::getState($group, 'fi');
     $this->assertEquals('ready', $currentState, 'ready when all proofread');
     // Change to translation
     $title = Title::newFromText('MediaWiki:key1/fi');
     $page = WikiPage::factory($title);
     $content = ContentHandler::makeContent('trans1 updated', $title);
     $page->doEditContent($content, __METHOD__, 0, false, $user);
     self::runJobs();
     $currentState = ApiGroupReview::getState($group, 'fi');
     $this->assertEquals('proofreading', $currentState, 'back to proofreading after translation changed');
 }
 public function execute()
 {
     $params = $this->extractRequestParams();
     $group = MessageGroups::getGroup($params['group']);
     if (!$group) {
         $this->dieUsageMsg(array('missingparam', 'mcgroup'));
     }
     MessageGroupStats::setTimeLimit($params['timelimit']);
     $cache = MessageGroupStats::forGroup($group->getId());
     $result = $this->getResult();
     foreach ($cache as $code => $stats) {
         if ($code < $params['offset']) {
             continue;
         }
         list($total, $translated, $fuzzy) = $stats;
         if ($total === null) {
             $this->setContinueEnumParameter('offset', $code);
             break;
         }
         $data = array('code' => $code, 'total' => $total, 'translated' => $translated, 'fuzzy' => $fuzzy);
         $result->addValue(array('query', $this->getModuleName()), null, $data);
     }
     $result->setIndexedTagName_internal(array('query', $this->getModuleName()), 'messagegroupstats');
 }
 public function execute()
 {
     $params = $this->extractRequestParams();
     $filter = $params['filter'];
     $groups = array();
     // Parameter root as all for all pages subgroups
     if ($params['root'] === 'all') {
         $allGroups = MessageGroups::getAllGroups();
         foreach ($allGroups as $group) {
             if ($group instanceof WikiPageMessageGroup) {
                 $groups[] = $group;
             }
         }
     } elseif ($params['format'] === 'flat') {
         if ($params['root'] !== '') {
             $group = MessageGroups::getGroup($params['root']);
             if ($group) {
                 $groups[$params['root']] = $group;
             }
         } else {
             $groups = MessageGroups::getAllGroups();
             foreach (MessageGroups::getDynamicGroups() as $id => $unused) {
                 $groups[$id] = MessageGroups::getGroup($id);
             }
         }
         // Not sorted by default, so do it now
         // Work around php bug: https://bugs.php.net/bug.php?id=50688
         wfSuppressWarnings();
         usort($groups, array('MessageGroups', 'groupLabelSort'));
         wfRestoreWarnings();
     } elseif ($params['root'] !== '') {
         // format=tree from now on, as it is the only other valid option
         $group = MessageGroups::getGroup($params['root']);
         if ($group instanceof AggregateMessageGroup) {
             $groups = MessageGroups::subGroups($group);
             // The parent group is the first, ignore it
             array_shift($groups);
         }
     } else {
         $groups = MessageGroups::getGroupStructure();
         foreach (MessageGroups::getDynamicGroups() as $id => $unused) {
             $groups[$id] = MessageGroups::getGroup($id);
         }
     }
     // Do not list the sandbox group. The code that knows it
     // exists can access it directly.
     if (isset($groups['!sandbox'])) {
         unset($groups['!sandbox']);
     }
     $props = array_flip($params['prop']);
     $result = $this->getResult();
     $matcher = new StringMatcher('', $filter);
     /**
      * @var MessageGroup $mixed
      */
     foreach ($groups as $mixed) {
         if ($filter !== array() && !$matcher->match($mixed->getId())) {
             continue;
         }
         $a = $this->formatGroup($mixed, $props);
         $result->setIndexedTagName($a, 'group');
         // @todo Add a continue?
         $fit = $result->addValue(array('query', $this->getModuleName()), null, $a);
         if (!$fit) {
             $this->setWarning('Could not fit all groups in the resultset.');
             // Even if we're not going to give a continue, no point carrying on
             // if the result is full
             break;
         }
     }
     if (defined('ApiResult::META_CONTENT')) {
         $result->addIndexedTagName(array('query', $this->getModuleName()), 'group');
     } else {
         $result->setIndexedTagName_internal(array('query', $this->getModuleName()), 'group');
     }
 }
Пример #19
0
 public function getGroups()
 {
     if (!isset($this->groups)) {
         $groups = array();
         $ids = (array) $this->conf['GROUPS'];
         $ids = $this->expandWildcards($ids);
         foreach ($ids as $id) {
             // Do not try to include self and go to infinite loop.
             if ($id === $this->getId()) {
                 continue;
             }
             $group = MessageGroups::getGroup($id);
             if ($group === null) {
                 error_log("Invalid group id in {$this->getId()}: {$id}");
                 continue;
             }
             if (MessageGroups::getPriority($group) === 'discouraged') {
                 continue;
             }
             $groups[$id] = $group;
         }
         $this->groups = $groups;
     }
     return $this->groups;
 }
Пример #20
0
 /**
  * Returns group strucuted into sub groups. First group in each subgroup is
  * considered as the main group.
  * @return array
  */
 public static function getGroupStructure()
 {
     global $wgTranslateGroupStructure;
     $groups = self::getAllGroups();
     $structure = array();
     foreach ($groups as $id => $o) {
         if (!MessageGroups::getGroup($id)->exists()) {
             continue;
         }
         foreach ($wgTranslateGroupStructure as $pattern => $hypergroup) {
             if (preg_match($pattern, $id)) {
                 // Emulate deepArraySet, because AFAIK php does not have one
                 self::deepArraySet($structure, $hypergroup, $id, $o);
                 // We need to continue the outer loop, because we have finished this item.
                 continue 2;
             }
         }
         // Does not belong to any subgroup, just shove it into main level.
         $structure[$id] = $o;
     }
     // Sort top-level groups according to labels, not ids
     $labels = array();
     foreach ($structure as $id => $data) {
         // Either it is a group itself, or the first group of the array
         $nid = is_array($data) ? key($data) : $id;
         $labels[$id] = $groups[$nid]->getLabel();
     }
     natcasesort($labels);
     $sorted = array();
     foreach (array_keys($labels) as $id) {
         $sorted[$id] = $structure[$id];
     }
     return $sorted;
 }
Пример #21
0
	/**
	 * Get the primary MessageGroup this message belongs to.
	 * You should check first that the handle is valid.
	 * @return MessageGroup
	 */
	public function getGroup() {
		$ids = $this->getGroupIds();
		return MessageGroups::getGroup( $ids[0] );
	}
Пример #22
0
    $noLocation = '';
}
if (isset($options['no-fuzzy'])) {
    $noFuzzy = true;
} else {
    $noFuzzy = false;
}
$reqLangs = Cli::parseLanguageCodes($options['lang']);
$groups = array();
// @todo FIXME: Code duplication with sync-group.php
if (isset($options['group'])) {
    // Explode parameter
    $groupIds = explode(',', trim($options['group']));
    // Get groups and add groups to array
    foreach ($groupIds as $groupId) {
        $group = MessageGroups::getGroup($groupId);
        if ($group !== null) {
            $groups[$groupId] = $group;
        } else {
            STDERR("Invalid group {$groupId}");
        }
    }
} else {
    // Apparently using option groupprefix. Find groups that match.
    $allGroups = MessageGroups::singleton()->getGroups();
    // Add matching groups to groups array.
    foreach ($allGroups as $groupId => $messageGroup) {
        if (strpos($groupId, $options['groupprefix']) === 0 && !$messageGroup->isMeta()) {
            $groups[$groupId] = $messageGroup;
        }
    }
Пример #23
0
 /**
  * HTML for language statistics
  * Copied and adaped from groupStatistics.php by Nikerabbit
  * @param integer $code A language code (default empty, example: 'en').
  * @param bool $suppressComplete If completely translated groups should be suppressed
  * @return string HTML
  */
 function getGroupStats($code, $suppressComplete = false, $suppressEmpty = false)
 {
     global $wgLang;
     # fetch the actual stats first
     $stats = MessageGroupStatistics::forLanguage($code);
     $out = '';
     # FIXME: provide some sensible header for what is being displayed.
     $out .= '<!-- ' . $code . " -->\n";
     $out .= '<!-- ' . TranslateUtils::getLanguageName($code, false) . " -->\n";
     # Create table header
     $out .= $this->heading();
     $out .= $this->blockstart();
     $out .= $this->element(wfMsg('translate-page-group', true));
     $out .= $this->element(wfMsg('translate-total', true));
     $out .= $this->element(wfMsg('translate-untranslated', true));
     $out .= $this->element(wfMsg('translate-percentage-complete', true));
     $out .= $this->element(wfMsg('translate-percentage-fuzzy', true));
     $out .= $this->blockend();
     # Get statistics for the message groups
     foreach ($stats as $id => $group) {
         $total = $group['gs_total'];
         $fuzzy = $group['gs_fuzzy'];
         $translated = $group['gs_translated'];
         // Skip if $suppressEmpty and no translations
         if ($suppressEmpty && empty($translated)) {
             continue;
         }
         // Skip if $suppressComplete and complete
         if ($suppressComplete && !$fuzzy && $translated == $total) {
             continue;
         }
         $translatedPercentage = wfMsg('percent', $wgLang->formatNum(round(100 * $translated / $total, 2)));
         $fuzzyPercentage = wfMsg('percent', $wgLang->formatNum(round(100 * $fuzzy / $total, 2)));
         $translateTitle = SpecialPage::getTitleFor('Translate');
         $pageParameters = "group=" . $id . "&language=" . $code;
         $g = MessageGroups::getGroup($id);
         $translateGroupLink = RequestContext::getMain()->getSkin()->makeKnownLinkObj($translateTitle, $g->getLabel(), $pageParameters);
         $out .= $this->blockstart();
         $out .= $this->element($translateGroupLink);
         $out .= $this->element($total);
         $out .= $this->element($total - $translated);
         $out .= $this->element($translatedPercentage, false, $this->getBackgroundColour($translated, $total));
         $out .= $this->element($fuzzyPercentage, false, $this->getBackgroundColour($fuzzy, $total, true));
         $out .= $this->blockend();
     }
     $out .= $this->footer();
     return $out;
 }
 protected function groupSelector()
 {
     $groups = MessageGroups::getAllGroups();
     uasort($groups, array('MessageGroups', 'groupLabelSort'));
     $dynamic = MessageGroups::getDynamicGroups();
     $groups = array_keys(array_merge($dynamic, $groups));
     $selected = $this->options['group'];
     $selector = new XmlSelect('group', 'group');
     $selector->setDefault($selected);
     foreach ($groups as $id) {
         $group = MessageGroups::getGroup($id);
         $hide = MessageGroups::getPriority($group) === 'discouraged';
         if (!$group->exists() || $hide && $id !== $selected) {
             continue;
         }
         $selector->addOption($group->getLabel(), $id);
     }
     return $selector->getHTML();
 }
 /**
  * Returns MessageGroup used for translating this page. It may still be empty
  * if the page has not been ever marked.
  * @return WikiPageMessageGroup
  */
 public function getMessageGroup()
 {
     return MessageGroups::getGroup($this->getMessageGroupId());
 }
 /**
  * @param $resultPageSet ApiPageSet
  */
 private function run($resultPageSet = null)
 {
     $params = $this->extractRequestParams();
     $group = MessageGroups::getGroup($params['group']);
     if (!$group) {
         $this->dieUsageMsg(array('missingparam', 'mcgroup'));
     }
     if (MessageGroups::isDynamic($group)) {
         /**
          * @var RecentMessageGroup $group
          */
         $group->setLanguage($params['language']);
     }
     $result = $this->getResult();
     $languages = $group->getTranslatableLanguages();
     if ($languages !== null && !isset($languages[$params['language']])) {
         $this->dieUsage('Translation to this language is disabled', 'translate-language-disabled');
     }
     $messages = $group->initCollection($params['language']);
     foreach ($params['filter'] as $filter) {
         $value = null;
         if (strpos($filter, ':') !== false) {
             list($filter, $value) = explode(':', $filter, 2);
         }
         /* The filtering params here are swapped wrt MessageCollection.
          * There (fuzzy) means do not show fuzzy, which is the same as !fuzzy
          * here and fuzzy here means (fuzzy, false) there. */
         try {
             if ($filter[0] === '!') {
                 $messages->filter(substr($filter, 1), true, $value);
             } else {
                 $messages->filter($filter, false, $value);
             }
         } catch (MWException $e) {
             $this->dieUsage($e->getMessage(), 'invalidfilter');
         }
     }
     $resultSize = count($messages);
     $offsets = $messages->slice($params['offset'], $params['limit']);
     $batchSize = count($messages);
     list(, $forwardsOffset, $startOffset) = $offsets;
     $result->addValue(array('query', 'metadata'), 'state', self::getWorkflowState($group->getId(), $params['language']));
     $result->addValue(array('query', 'metadata'), 'resultsize', $resultSize);
     $result->addValue(array('query', 'metadata'), 'remaining', $resultSize - $startOffset - $batchSize);
     $messages->loadTranslations();
     $pages = array();
     if ($forwardsOffset !== false) {
         $this->setContinueEnumParameter('offset', $forwardsOffset);
     }
     $props = array_flip($params['prop']);
     /** @var Title $title */
     foreach ($messages->keys() as $mkey => $title) {
         if (is_null($resultPageSet)) {
             $data = $this->extractMessageData($result, $props, $messages[$mkey]);
             $data['title'] = $title->getPrefixedText();
             $result->addValue(array('query', $this->getModuleName()), null, $data);
         } else {
             $pages[] = $title;
         }
     }
     if (is_null($resultPageSet)) {
         if (defined('ApiResult::META_CONTENT')) {
             $result->addIndexedTagName(array('query', $this->getModuleName()), 'message');
         } else {
             $result->setIndexedTagName_internal(array('query', $this->getModuleName()), 'message');
         }
     } else {
         $resultPageSet->populateFromTitles($pages);
     }
 }
	public function preQuery( &$tables, &$fields, &$conds, &$type, &$options, $start, $end ) {
		global $wgTranslateMessageNamespaces;

		$db = wfGetDB( DB_SLAVE );

		$tables = array( 'recentchanges' );
		$fields = array( 'rc_timestamp' );

		$conds = array(
			'rc_namespace' => $wgTranslateMessageNamespaces,
			'rc_bot' => 0
		);

		$timeConds = self::makeTimeCondition( 'rc_timestamp', $start, $end );
		$conds = array_merge( $conds, $timeConds );

		$options = array( 'ORDER BY' => 'rc_timestamp' );

		$this->groups = array_filter( array_map( 'trim', explode( ',', $this->opts['group'] ) ) );
		$this->codes = array_filter( array_map( 'trim', explode( ',', $this->opts['language'] ) ) );

		$namespaces = array();
		$languages = array();

		foreach ( $this->groups as $id ) {
			$group = MessageGroups::getGroup( $id );
			if ( $group ) {
				$namespaces[] = $group->getNamespace();
			}
		}

		foreach ( $this->codes as $code ) {
			$languages[] = 'rc_title ' . $db->buildLike( $db->anyString(), "/$code" );
		}

		if ( count( $namespaces ) ) {
			$namespaces = array_unique( $namespaces );
			$conds['rc_namespace'] = $namespaces;
		}

		if ( count( $languages ) ) {
			$languages = array_unique( $languages );
			$conds[] = $db->makeList( $languages, LIST_OR );
		}

		$fields[] = 'rc_title';

		if ( $this->groups ) {
			$fields[] = 'rc_namespace';
		}

		if ( $this->opts['count'] === 'users' ) {
			$fields[] = 'rc_user_text';
		}

		$type .= '-perlang';
	}
Пример #28
0
	/**
	 * @param $changes \array Array of key/langcode => translation.
	 * @param $groupId \string Group ID.
	 * @param $user \string User who makes the edits in wiki.
	 * @param $dryrun \bool Do not do anything that affects the database.
	 */
	public function __construct( $changes, $groupId, $user, $dryrun = true ) {
		$this->changes = $changes;
		$this->dryrun = $dryrun;
		$this->group = MessageGroups::getGroup( $groupId );
		if ( !$this->group ) {
			STDERR( "Group $groupId does not exist." );
			return;
		}

		$this->user = User::newFromName( $user );
		if ( !$this->user->idForName() ) {
			STDERR( "User $user does not exist." );
			return;
		}

		$this->allclear = true;
	}
Пример #29
0
	--nocolor	without colours
EOT
);
	exit( 1 );
}

if ( isset( $options['help'] ) ) {
	showUsage();
}

if ( !isset( $options['group'] ) ) {
	STDERR( "ESG1: Message group id must be supplied with group parameter." );
	exit( 1 );
}

$group = MessageGroups::getGroup( $options['group'] );
if ( $group === null ) {
	if ( $options['group'] === '*' ) {
		$mg = MessageGroups::singleton();
		$groups = $mg->getGroups();
	} else {
		STDERR( "ESG2: Invalid message group was given." );
		exit( 1 );
	}
} else {
	$groups = array( $group );
}

if ( !isset( $options['lang'] ) || strval( $options['lang'] ) === '' ) {
	STDERR( "ESG3: List of language codes must be supplied with lang parameter." );
	exit( 1 );
 protected function processSubmit()
 {
     $req = $this->getRequest();
     $out = $this->getOutput();
     $jobs = array();
     $jobs[] = MessageIndexRebuildJob::newJob();
     $changefile = TranslateUtils::cacheFile(self::CHANGEFILE);
     $reader = CdbReader::open($changefile);
     $groups = unserialize($reader->get('#keys'));
     $postponed = array();
     foreach ($groups as $groupId) {
         $group = MessageGroups::getGroup($groupId);
         $changes = unserialize($reader->get($groupId));
         foreach ($changes as $code => $subchanges) {
             foreach ($subchanges as $type => $messages) {
                 foreach ($messages as $index => $params) {
                     $id = self::changeId($groupId, $code, $type, $params['key']);
                     if ($req->getVal($id) === null) {
                         // We probably hit the limit with number of post parameters.
                         $postponed[$groupId][$code][$type][$index] = $params;
                         continue;
                     }
                     if ($type === 'deletion' || $req->getCheck("i/{$id}")) {
                         continue;
                     }
                     $fuzzy = $req->getCheck("f/{$id}") ? 'fuzzy' : false;
                     $key = $params['key'];
                     $title = Title::makeTitleSafe($group->getNamespace(), "{$key}/{$code}");
                     $jobs[] = MessageUpdateJob::newJob($title, $params['content'], $fuzzy);
                 }
             }
             if (!isset($postponed[$groupId][$code])) {
                 $cache = new MessageGroupCache($groupId, $code);
                 $cache->create();
             }
         }
     }
     JobQueueGroup::singleton()->push($jobs);
     $reader->close();
     rename($changefile, $changefile . '-' . wfTimestamp());
     if (count($postponed)) {
         $changefile = TranslateUtils::cacheFile(self::CHANGEFILE);
         $writer = CdbWriter::open($changefile);
         $keys = array_keys($postponed);
         $writer->set('#keys', serialize($keys));
         foreach ($postponed as $groupId => $changes) {
             $writer->set($groupId, serialize($changes));
         }
         $writer->close();
         $this->showChanges(true, $this->getLimit());
     } else {
         $out->addWikiMsg('translate-smg-submitted');
     }
 }