public function getGroups() { if (!isset($this->groups)) { $groups = array(); $ids = (array) $this->conf['GROUPS']; $ids = MessageGroups::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; }
/** * @param AggregateMessageGroup $parent * @return string */ protected function listSubgroups(AggregateMessageGroup $parent) { $out = ''; $id = $this->htmlIdForGroup($parent, 'mw-tpa-grouplist-'); $out = Html::openElement('ol', array('id' => $id)); // Not calling $parent->getGroups() because it has done filtering already $subgroupIds = TranslateMetadata::getSubgroups($parent->getId()); // Get the respective groups and sort them $subgroups = MessageGroups::getGroupsById($subgroupIds); uasort($subgroups, array('MessageGroups', 'groupLabelSort')); // Add missing invalid group ids back, not returned by getGroupsById foreach ($subgroupIds as $id) { if (!isset($subgroups[$id])) { $subgroups[$id] = null; } } foreach ($subgroups as $id => $group) { $remove = ''; if ($this->hasPermission) { $remove = Html::element('span', array('class' => 'tp-aggregate-remove-button', 'data-groupid' => $id)); } if ($group) { $text = Linker::linkKnown($group->getTitle()); $note = MessageGroups::getPriority($id); } else { $text = htmlspecialchars($id); $note = $this->msg('tpt-aggregategroup-invalid-group')->escaped(); } $out .= Html::rawElement('li', array(), "{$text}{$remove} {$note}"); } $out .= Html::closeElement('ol'); 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(); }
/** * @param $group * @param $cache * @param $parent bool * @return string */ protected function makeGroupRow( $group, $cache, $parent = false ) { $groupId = $group->getId(); if ( $this->table->isBlacklisted( $groupId, $this->target ) !== null ) { return ''; } # These are hidden, and the code in MessageGroupStats makes sure that # these are not counted in the aggregate groups they may belong. if ( MessageGroups::getPriority( $group ) === 'discouraged' ) { return ''; } $stats = $cache[$groupId]; list( $total, $translated, $fuzzy ) = $stats; if ( $total === null ) { $this->incomplete = true; $extra = array(); } else { if ( $this->noComplete && $fuzzy === 0 && $translated === $total ) { return ''; } if ( $this->noEmpty && $translated === 0 && $fuzzy === 0 ) { return ''; } if ( $translated === $total ) { $extra = array( 'task' => 'reviewall' ); } else { $extra = array(); } } if ( !$group instanceof AggregateMessageGroup ) { $this->totals = MessageGroupStats::multiAdd( $this->totals, $stats ); } $rowParams = array(); $rowParams['data-groupid'] = $groupId; if ( is_string( $parent ) ) { $rowParams['data-parentgroups'] = $parent; } elseif ( $parent === true ) { $rowParams['data-ismeta'] = '1'; } $out = "\t" . Html::openElement( 'tr', $rowParams ); $out .= "\n\t\t" . Html::rawElement( 'td', array(), $this->table->makeGroupLink( $group, $this->target, $extra ) ); $out .= $this->table->makeNumberColumns( $fuzzy, $translated, $total ); $out .= $this->getWorkflowStateCell( $groupId ); $out .= "\n\t" . Html::closeElement( 'tr' ) . "\n"; return $out; }
/** * @param array|MessageGroup $mixed * @param array $props List of props as the array keys * @param int $depth * @return array */ protected function formatGroup($mixed, $props, $depth = 0) { $params = $this->extractRequestParams(); // Default $g = $mixed; $subgroups = array(); // Format = tree and has subgroups if (is_array($mixed)) { $g = array_shift($mixed); $subgroups = $mixed; } wfProfileIn(__METHOD__ . '-' . get_class($g)); $a = array(); $groupId = $g->getId(); wfProfileIn(__METHOD__ . '-basic'); if (isset($props['id'])) { $a['id'] = $groupId; } if (isset($props['label'])) { $a['label'] = $g->getLabel(); } if (isset($props['description'])) { $a['description'] = $g->getDescription(); } if (isset($props['class'])) { $a['class'] = get_class($g); } if (isset($props['namespace'])) { $a['namespace'] = $g->getNamespace(); } wfProfileOut(__METHOD__ . '-basic'); wfProfileIn(__METHOD__ . '-exists'); if (isset($props['exists'])) { $a['exists'] = $g->exists(); } wfProfileOut(__METHOD__ . '-exists'); wfProfileIn(__METHOD__ . '-icon'); if (isset($props['icon'])) { $formats = TranslateUtils::getIcon($g, $params['iconsize']); if ($formats) { $a['icon'] = $formats; } } wfProfileOut(__METHOD__ . '-icon'); wfProfileIn(__METHOD__ . '-priority'); if (isset($props['priority'])) { $priority = MessageGroups::getPriority($g); $a['priority'] = $priority ?: 'default'; } if (isset($props['prioritylangs'])) { $prioritylangs = TranslateMetadata::get($groupId, 'prioritylangs'); $a['prioritylangs'] = $prioritylangs ? explode(',', $prioritylangs) : false; } if (isset($props['priorityforce'])) { $a['priorityforce'] = TranslateMetadata::get($groupId, 'priorityforce') === 'on'; } wfProfileOut(__METHOD__ . '-priority'); wfProfileIn(__METHOD__ . '-workflowstates'); if (isset($props['workflowstates'])) { $a['workflowstates'] = $this->getWorkflowStates($g); } wfProfileOut(__METHOD__ . '-workflowstates'); Hooks::run('TranslateProcessAPIMessageGroupsProperties', array(&$a, $props, $params, $g)); wfProfileOut(__METHOD__ . '-' . get_class($g)); // Depth only applies to tree format if ($depth >= $params['depth'] && $params['format'] === 'tree') { $a['groupcount'] = count($subgroups); // Prevent going further down in the three return $a; } // Always empty array for flat format, only sometimes for tree format if ($subgroups !== array()) { foreach ($subgroups as $sg) { $a['groups'][] = $this->formatGroup($sg, $props); } $result = $this->getResult(); $result->setIndexedTagName($a['groups'], 'group'); } return $a; }
protected static function forItemInternal( &$stats, $group, $code ) { $id = $group->getId(); if ( self::$timeStart !== null && ( microtime( true ) - self::$timeStart ) > self::$limit ) { return $stats[$id][$code] = array( null, null, null ); } if ( $group instanceof AggregateMessageGroup ) { $ids = array_unique( self::expandAggregates( $group ) ); $res = self::selectRowsIdLang( $ids, $code ); $stats = self::extractResults( $res, $stats ); $aggregates = array( 0, 0, 0 ); foreach ( $group->getGroups() as $sid => $subgroup ) { # Discouraged groups may belong to a another group, usually if there # is a aggregate group for all translatable pages. In that case # calculate and store the statistics, but don't count them as part of # the aggregate group, so that the numbers in Special:LanguageStats # add up. The statistics for discouraged groups can still be viewed # through Special:MessageGroupStats. if ( !isset( $stats[$sid][$code] ) ) { $stats[$sid][$code] = self::forItemInternal( $stats, $subgroup, $code ); } if ( MessageGroups::getPriority( $subgroup ) !== 'discouraged' ) { $aggregates = self::multiAdd( $aggregates, $stats[$sid][$code] ); } } $stats[$id][$code] = $aggregates; } else { $aggregates = self::calculateGroup( $group, $code ); } list( $total, $translated, $fuzzy ) = $aggregates; // Don't add nulls to the database, causes annoying warnings if ( $total === null ) { return $aggregates; } $data = array( 'tgs_group' => $id, 'tgs_lang' => $code, 'tgs_total' => $total, 'tgs_translated' => $translated, 'tgs_fuzzy' => $fuzzy, ); $dbw = wfGetDB( DB_MASTER ); $errors = $dbw->ignoreErrors( true ); $dbw->insert( self::TABLE, $data, __METHOD__ ); $dbw->ignoreErrors( $errors ); return $aggregates; }
/** * @param array $in * @return array */ protected function classifyPages(array $in) { $out = array('proposed' => array(), 'active' => array(), 'broken' => array(), 'discouraged' => array()); foreach ($in as $index => $page) { if (!isset($page['tp:mark'])) { // Never marked, check that the latest version is ready if ($page['tp:tag'] === $page['latest']) { $out['proposed'][$index] = $page; } // Otherwise ignore such pages } elseif ($page['tp:tag'] === $page['latest']) { // Marked and latest version if fine $out['active'][$index] = $page; } else { // Marked but latest version if not fine $out['broken'][$index] = $page; } } // broken and proposed take preference over discouraged status foreach ($out['active'] as $index => $page) { $id = TranslatablePage::getMessageGroupIdFromTitle($page['title']); $group = MessageGroups::getGroup($id); if (MessageGroups::getPriority($group) === 'discouraged') { $out['discouraged'][$index] = $page; unset($out['active'][$index]); } } return $out; }
public function formatGroupInformation($blocks, $level = 2) { global $wgLang; if (is_array($blocks)) { foreach ($blocks as $i => $block) { if (!is_array($block) && MessageGroups::getPriority($block) === 'discouraged') { unset($blocks[$i]); } } $block = array_shift($blocks); } else { $block = $blocks; if (MessageGroups::getPriority($block) === 'discouraged') { return ''; } } $id = $block->getId(); $title = $this->getTitle(); $code = $this->options['language']; $queryParams = array('group' => $id, 'language' => $code); $linker = class_exists('DummyLinker') ? new DummyLinker() : new Linker(); $label = $linker->link($title, htmlspecialchars($block->getLabel()), array(), $queryParams); $desc = $this->getGroupDescription($block); $hasSubblocks = is_array($blocks) && count($blocks); $subid = Sanitizer::escapeId("mw-subgroup-{$id}"); if ($hasSubblocks) { $msg = wfMessage('translate-showsub', $wgLang->formatNum(count($blocks)))->text(); $target = TranslationHelpers::jQueryPathId($subid); $desc .= Html::element('a', array('onclick' => "jQuery({$target}).toggle()", 'class' => 'mw-sp-showmore'), $msg); } $out = "\n<tr><td>{$label}</td>\n<td>{$desc}</td></tr>\n"; if ($hasSubblocks) { $out .= "<tr><td></td><td>\n"; $tableParams = array('id' => $subid, 'style' => 'display:none;', 'class' => "mw-sp-translate-subgroup depth-{$level}"); $out .= Html::openElement('table', $tableParams); foreach ($blocks as $subBlock) { $out .= $this->formatGroupInformation($subBlock, $level + 1); } $out .= '</table></td></tr>'; } return $out; }
public static function hideDiscouragedFromStats($id, $code) { // Return true to keep, false to exclude return MessageGroups::getPriority($id) !== 'discouraged'; }