public function getMessageParameters() { $params = parent::getMessageParameters(); $type = $this->entry->getFullType(); if ($type === 'translationreview/message') { $targetPage = $this->makePageLink($this->entry->getTarget(), array('oldid' => $params[3])); $params[2] = Message::rawParam($targetPage); } elseif ($type === 'translationreview/group') { /* * - 3: language code * - 4: label of the message group * - 5: old state * - 6: new state */ $uiLanguage = $this->context->getLanguage(); $language = $params[3]; $targetPage = $this->makePageLinkWithText($this->entry->getTarget(), $params[4], array('language' => $language)); $params[2] = Message::rawParam($targetPage); $params[3] = TranslateUtils::getLanguageName($language, $uiLanguage->getCode()); $params[5] = $this->formatStateMessage($params[5]); $params[6] = $this->formatStateMessage($params[6]); } elseif ($type === 'translatorsandbox/rejected') { // No point linking to the user page which cannot have existed $params[2] = $this->entry->getTarget()->getText(); } elseif ($type === 'translatorsandbox/promoted') { // Gender for the target $params[3] = User::newFromId($params[3])->getName(); } return $params; }
protected function doHeader( MessageCollection $collection ) { global $wgSitename, $wgTranslateDocumentationLanguageCode; $code = $collection->code; $name = TranslateUtils::getLanguageName( $code ); $native = TranslateUtils::getLanguageName( $code, true ); if ( $wgTranslateDocumentationLanguageCode ) { $docu = "\n * See the $wgTranslateDocumentationLanguageCode 'language' for message documentation incl. usage of parameters"; } else { $docu = ''; } $authors = $this->doAuthors( $collection ); $output = <<<PHP /** $name ($native) * $docu * To improve a translation please visit http://$wgSitename * * @ingroup Language * @file * $authors */ PHP; return $output; }
protected function doHeader(MessageCollection $collection) { global $wgSitename; $code = $collection->code; $name = TranslateUtils::getLanguageName($code); $native = TranslateUtils::getLanguageName($code, $code); $output = "# Messages for {$name} ({$native})\n"; $output .= "# Exported from {$wgSitename}\n\n"; return $output; }
/** * @param $collection MessageCollection * @return string */ protected function doHeader(MessageCollection $collection) { global $wgSitename; global $wgTranslateYamlLibrary; $code = $collection->code; $name = TranslateUtils::getLanguageName($code); $native = TranslateUtils::getLanguageName($code, $code); $output = "# Messages for {$name} ({$native})\n"; $output .= "# Exported from {$wgSitename}\n"; if (isset($wgTranslateYamlLibrary)) { $output .= "# Export driver: {$wgTranslateYamlLibrary}\n"; } return $output; }
public function getMessageParameters() { $params = parent::getMessageParameters(); $legacy = $this->entry->getParameters(); $type = $this->entry->getFullType(); switch ($type) { case 'pagetranslation/mark': $revision = $legacy['revision']; $targetPage = $this->makePageLink($this->entry->getTarget(), array('oldid' => $revision)); $params[2] = Message::rawParam($targetPage); break; case 'pagetranslation/moveok': case 'pagetranslation/movenok': case 'pagetranslation/deletefnok': case 'pagetranslation/deletelnok': $target = $legacy['target']; $moveTarget = $this->makePageLink(Title::newFromText($target)); $params[3] = Message::rawParam($moveTarget); break; case 'pagetranslation/prioritylanguages': $params[3] = $legacy['force']; $languages = $legacy['languages']; if ($languages !== false) { $lang = $this->context->getLanguage(); $languages = array_map('trim', preg_split('/,/', $languages, -1, PREG_SPLIT_NO_EMPTY)); $languages = array_map(function ($code) use($lang) { return TranslateUtils::getLanguageName($code, $lang->getCode()); }, $languages); $params[4] = $lang->listToText($languages); } break; case 'pagetranslation/associate': case 'pagetranslation/dissociate': $params[3] = $legacy['aggregategroup']; break; } return $params; }
/** * Replace the normal save button with one that says if you are editing * message documentation to try to avoid accidents. * Hook: EditPageBeforeEditButtons */ static function buttonHack(EditPage $editpage, &$buttons, $tabindex) { $handle = new MessageHandle($editpage->getTitle()); if (!$handle->isValid()) { return true; } $context = $editpage->getArticle()->getContext(); if ($handle->isDoc()) { $langCode = $context->getLanguage()->getCode(); $name = TranslateUtils::getLanguageName($handle->getCode(), $langCode); $accessKey = $context->msg('accesskey-save')->plain(); $temp = array('id' => 'wpSave', 'name' => 'wpSave', 'type' => 'submit', 'tabindex' => ++$tabindex, 'value' => $context->msg('translate-save', $name)->text(), 'accesskey' => $accessKey, 'title' => $context->msg('tooltip-save')->text() . ' [' . $accessKey . ']'); $buttons['save'] = Xml::element('input', $temp, ''); } try { $supportUrl = SupportAid::getSupportUrl($handle->getTitle()); } catch (TranslationHelperException $e) { return true; } $temp = array('id' => 'wpSupport', 'name' => 'wpSupport', 'type' => 'button', 'tabindex' => ++$tabindex, 'value' => $context->msg('translate-js-support')->text(), 'title' => $context->msg('translate-js-support-title')->text(), 'data-load-url' => $supportUrl, 'onclick' => "window.open( jQuery(this).attr('data-load-url') );"); $buttons['ask'] = Html::element('input', $temp, ''); return true; }
/** * @param $collection MessageCollection * @return string */ protected function doHeader(MessageCollection $collection) { if (isset($this->extra['header'])) { $output = $this->extra['header']; } else { global $wgSitename; $code = $collection->code; $name = TranslateUtils::getLanguageName($code); $native = TranslateUtils::getLanguageName($code, $code); $output = "# Messages for {$name} ({$native})\n"; $output .= "# Exported from {$wgSitename}\n"; } return $output; }
/** * Output something helpful to guide the confused user. */ protected function outputIntroduction() { global $wgOut, $wgLang, $wgUser; $linker = class_exists( 'DummyLinker' ) ? new DummyLinker : new Linker; $languageName = TranslateUtils::getLanguageName( $this->target, false, $wgLang->getCode() ); $rcInLangLink = $linker->link( SpecialPage::getTitleFor( 'Translate', '!recent' ), wfMsgHtml( 'languagestats-recenttranslations' ), array(), array( 'task' => $wgUser->isAllowed( 'translate-messagereview' ) ? 'acceptqueue' : 'reviewall', 'language' => $this->target ) ); $out = wfMessage( 'languagestats-stats-for', $languageName )->rawParams( $rcInLangLink )->parseAsBlock(); $wgOut->addHTML( $out ); }
/** * Builds a table with all translations of $title. * * @param $title Title (default: null) * @return void */ function showTranslations(Title $title) { global $wgOut, $wgUser, $wgLang; $sk = $wgUser->getSkin(); $namespace = $title->getNamespace(); $message = $title->getDBkey(); $inMessageGroup = TranslateUtils::messageKeyToGroup($title->getNamespace(), $title->getText()); if (!$inMessageGroup) { $wgOut->addWikiMsg('translate-translations-no-message', $title->getPrefixedText()); return; } $dbr = wfGetDB(DB_SLAVE); $res = $dbr->select('page', array('page_namespace', 'page_title'), array('page_namespace' => $namespace, 'page_title ' . $dbr->buildLike("{$message}/", $dbr->anyString())), __METHOD__, array('ORDER BY' => 'page_title', 'USE INDEX' => 'name_title')); if (!$res->numRows()) { $wgOut->addWikiMsg('translate-translations-no-message', $title->getPrefixedText()); return; } else { $wgOut->addWikiMsg('translate-translations-count', $wgLang->formatNum($res->numRows())); } // Normal output. $titles = array(); foreach ($res as $s) { $titles[] = $s->page_title; } $pageInfo = TranslateUtils::getContents($titles, $namespace); $tableheader = Xml::openElement('table', array('class' => 'mw-sp-translate-table sortable')); $tableheader .= Xml::openElement('tr'); $tableheader .= Xml::element('th', null, wfMsg('allmessagesname')); $tableheader .= Xml::element('th', null, wfMsg('allmessagescurrent')); $tableheader .= Xml::closeElement('tr'); // Adapted version of TranslateUtils:makeListing() by Nikerabbit. $out = $tableheader; $canTranslate = $wgUser->isAllowed('translate'); $ajaxPageList = array(); $historyText = " <sup>" . wfMsgHtml('translate-translations-history-short') . "</sup> "; foreach ($res as $s) { $key = $s->page_title; $tTitle = Title::makeTitle($s->page_namespace, $key); $ajaxPageList[] = $tTitle->getPrefixedDBkey(); $code = $this->getCode($s->page_title); $text = TranslateUtils::getLanguageName($code, false, $wgLang->getCode()) . " ({$code})"; $text = htmlspecialchars($text); if ($canTranslate) { $tools['edit'] = TranslationHelpers::ajaxEditLink($tTitle, $text); } else { $tools['edit'] = $sk->link($tTitle, $text); } $tools['history'] = $sk->link($tTitle, $historyText, array('action', 'title' => wfMsg('history-title', $tTitle->getPrefixedDBkey())), array('action' => 'history')); if (TranslateEditAddons::isFuzzy($tTitle)) { $class = 'orig'; } else { $class = 'def'; } $leftColumn = $tools['history'] . $tools['edit']; $out .= Xml::tags('tr', array('class' => $class), Xml::tags('td', null, $leftColumn) . Xml::tags('td', array('lang' => $code, 'dir' => Language::factory($code)->getDir()), TranslateUtils::convertWhiteSpaceToHTML($pageInfo[$key][0]))); } $out .= Xml::closeElement('table'); $wgOut->addHTML($out); $vars = array('trlKeys' => $ajaxPageList); $wgOut->addScript(Skin::makeVariablesScript($vars)); }
/** * Set a subtitle like "Manage > FreeCol (open source game) > German" * based on group and language code. The language part is not shown if * it is 'en', and all three possible parts of the subtitle are linked. * * @param $group MessageGroup * @param $code \string Language code. */ protected function setSubtitle($group, $code) { global $wgLang; $links[] = $this->skin->link($this->getTitle(), wfMsgHtml('translate-manage-subtitle')); $links[] = $this->skin->link($this->getTitle(), htmlspecialchars($group->getLabel()), array(), array('group' => $group->getId())); // Do not show language part for English. if ($code !== 'en') { $langname = TranslateUtils::getLanguageName($code, false, $wgLang->getCode()); $links[] = $this->skin->link($this->getTitle(), htmlspecialchars($langname), array(), array('group' => $group->getId(), 'language' => $code)); } $this->out->setSubtitle(implode(' > ', $links)); }
protected function messageSelector() { $nondefaults = $this->opts->getChangedValues(); $output = Html::openElement('div', array('class' => 'row tux-messagetable-header')); $output .= Html::openElement('div', array('class' => 'nine columns')); $output .= Html::openElement('ul', array('class' => 'row tux-message-selector')); $tabs = array('default' => '', 'translated' => 'translated', 'untranslated' => 'untranslated'); $ellipsisOptions = array('outdated' => 'fuzzy'); $selected = $this->opts->getValue('filter'); $keys = array_keys($tabs); if (in_array($selected, array_values($ellipsisOptions))) { $key = $keys[count($keys) - 1]; $ellipsisOptions = array($key => $tabs[$key]); // Remove the last tab unset($tabs[$key]); $tabs = array_merge($tabs, array('outdated' => $selected)); } elseif (!in_array($selected, array_values($tabs))) { $selected = ''; } $container = Html::openElement('ul', array('class' => 'column tux-message-selector')); foreach ($ellipsisOptions as $optKey => $optValue) { $container .= $this->ellipsisSelector($optKey, $optValue); } $sourcelanguage = $this->opts->getValue('sourcelanguage'); $sourcelanguage = TranslateUtils::getLanguageName($sourcelanguage); foreach ($tabs as $tab => $filter) { // Messages for grepping: // tux-sst-default // tux-sst-translated // tux-sst-untranslated // tux-sst-outdated $tabClass = "tux-sst-{$tab}"; $taskParams = array('filter' => $filter) + $nondefaults; ksort($taskParams); $href = $this->getTitle()->getLocalUrl($taskParams); if ($tab === 'default') { $link = Html::element('a', array('href' => $href), $this->msg($tabClass)->text()); } else { $link = Html::element('a', array('href' => $href), $this->msg($tabClass, $sourcelanguage)->text()); } if ($selected === $filter) { $tabClass = $tabClass . ' selected'; } $output .= Html::rawElement('li', array('class' => array('column', $tabClass), 'data-filter' => $filter, 'data-title' => $tab), $link); } // More column $output .= Html::openElement('li', array('class' => 'column more')) . '...' . $container . Html::closeElement('li'); $output .= Html::closeElement('ul'); $output .= Html::closeElement('div'); $output .= Html::closeElement('div'); return $output; }
/** * @param $data * @param $params * @param $parser Parser * @return string */ public static function languages($data, $params, $parser) { $currentTitle = $parser->getTitle(); // Check if this is a source page or a translation page $page = TranslatablePage::newFromTitle($currentTitle); if ($page->getMarkedTag() === false) { $page = TranslatablePage::isTranslationPage($currentTitle); } if ($page === false || $page->getMarkedTag() === false) { return ''; } $status = $page->getTranslationPercentages(); if (!$status) { return ''; } // If priority languages have been set always show those languages $priorityLangs = TranslateMetadata::get($page->getMessageGroupId(), 'prioritylangs'); $priorityForce = TranslateMetadata::get($page->getMessageGroupId(), 'priorityforce'); $filter = null; if (strlen($priorityLangs) > 0) { $filter = array_flip(explode(',', $priorityLangs)); } if ($filter !== null) { // If translation is restricted to some languages, only show them if ($priorityForce === 'on') { // Do not filter the source language link $filter[$page->getMessageGroup()->getSourceLanguage()] = true; $status = array_intersect_key($status, $filter); } foreach ($filter as $langCode => $value) { if (!isset($status[$langCode])) { // We need to show all priority languages even if no translation started $status[$langCode] = 0; } } } // Fix title $pageTitle = $page->getTitle(); // Sort by language code, which seems to be the only sane method ksort($status); // This way the parser knows to fragment the parser cache by language code $userLangCode = $parser->getOptions()->getUserLang(); $userLangDir = $parser->getOptions()->getUserLangObj()->getDir(); // Should call $page->getMessageGroup()->getSourceLanguage(), but // group is sometimes null on WMF during page moves, reason unknown. // This should do the same thing for now. $sourceLanguage = $pageTitle->getPageLanguage()->getCode(); $languages = array(); foreach ($status as $code => $percent) { // Get autonyms $name = TranslateUtils::getLanguageName($code, $code); $name = htmlspecialchars($name); // Unlikely, but better safe // Add links to other languages $suffix = $code === $sourceLanguage ? '' : "/{$code}"; $targetTitleString = $pageTitle->getDBkey() . $suffix; $subpage = Title::makeTitle($pageTitle->getNamespace(), $targetTitleString); $classes = array(); if ($code === $userLangCode) { $classes[] = 'mw-pt-languages-ui'; } if ($currentTitle->equals($subpage)) { $classes[] = 'mw-pt-languages-selected'; $classes = array_merge($classes, self::tpProgressIcon($percent)); $name = Html::rawElement('span', array('class' => $classes), $name); } elseif ($subpage->isKnown()) { $pagename = $page->getPageDisplayTitle($code); if (!is_string($pagename)) { $pagename = $subpage->getPrefixedText(); } $classes = array_merge($classes, self::tpProgressIcon($percent)); $title = wfMessage('tpt-languages-nonzero')->params($pagename)->numParams(100 * $percent)->text(); $attribs = array('title' => $title, 'class' => $classes); $name = Linker::linkKnown($subpage, $name, $attribs); } else { /* When language is included because it is a priority language, * but translation does not yet exists, link directly to the * translation view. */ $specialTranslateTitle = SpecialPage::getTitleFor('Translate'); $params = array('group' => $page->getMessageGroupId(), 'language' => $code, 'task' => 'view'); $classes[] = 'new'; // For red link color $attribs = array('title' => wfMessage('tpt-languages-zero')->text(), 'class' => $classes); $name = Linker::link($specialTranslateTitle, $name, $attribs, $params); } $languages[] = $name; } // dirmark (rlm/lrm) is added, because languages with RTL names can // mess the display $lang = Language::factory($userLangCode); $sep = wfMessage('tpt-languages-separator')->inLanguage($lang)->escaped(); $sep .= $lang->getDirMark(); $languages = implode($sep, $languages); $out = Html::openElement('div', array('class' => 'mw-pt-languages noprint', 'lang' => $userLangCode, 'dir' => $userLangDir)); $out .= Html::rawElement('div', array('class' => 'mw-pt-languages-label'), wfMessage('tpt-languages-legend')->escaped()); $out .= Html::rawElement('div', array('class' => 'mw-pt-languages-list autonym'), $languages); $out .= Html::closeElement('div'); return $out; }
/** * @param $code string * @param $authors array * @return string */ protected function header($code, $authors) { global $wgSitename; $name = TranslateUtils::getLanguageName($code); $native = TranslateUtils::getLanguageName($code, $code); $authorsList = $this->authorsList($authors); /** @cond doxygen_bug */ return <<<EOT /** Messages for {$name} ({$native}) * Exported from {$wgSitename} * {$authorsList} */ var I18n = { EOT; /** @endcond */ }
/** * @param $data * @param $params * @param $parser Parser * @return string */ public static function languages($data, $params, $parser) { $title = $parser->getTitle(); // Check if this is a source page or a translation page $page = TranslatablePage::newFromTitle($title); if ($page->getMarkedTag() === false) { $page = TranslatablePage::isTranslationPage($title); } if ($page === false || $page->getMarkedTag() === false) { return ''; } $status = $page->getTranslationPercentages(); if (!$status) { return ''; } // Fix title $title = $page->getTitle(); // Sort by language code, which seems to be the only sane method ksort($status); $options = $parser->getOptions(); if (method_exists($options, 'getUserLang')) { $userLangCode = $options->getUserLang(); } else { // Backward compat for MediaWiki 1.17 global $wgLang; $userLangCode = $wgLang->getCode(); } // BC for <1.19 $linker = class_exists('DummyLinker') ? new DummyLinker() : new Linker(); $languages = array(); foreach ($status as $code => $percent) { $name = TranslateUtils::getLanguageName($code, false, $userLangCode); $name = htmlspecialchars($name); // Unlikely, but better safe /* Percentages are too accurate and take more * space than simple images */ $percent *= 100; if ($percent < 20) { $image = 1; } elseif ($percent < 40) { $image = 2; } elseif ($percent < 60) { $image = 3; } elseif ($percent < 80) { $image = 4; } else { $image = 5; } $percent = Xml::element('img', array('src' => TranslateUtils::assetPath("resources/images/prog-{$image}.png"), 'alt' => "{$percent}%", 'title' => "{$percent}%", 'width' => '9', 'height' => '9')); // Add links to other languages $suffix = $code === 'en' ? '' : "/{$code}"; $_title = Title::makeTitle($title->getNamespace(), $title->getDBkey() . $suffix); if ($parser->getTitle()->getText() === $_title->getText()) { $name = Html::rawElement('span', array('class' => 'mw-pt-languages-selected'), $name); $languages[] = "{$name} {$percent}"; } else { if ($code === $userLangCode) { $name = Html::rawElement('span', array('class' => 'mw-pt-languages-ui'), $name); } $languages[] = $linker->linkKnown($_title, "{$name} {$percent}"); } } $legend = wfMsg('tpt-languages-legend'); $languages = implode(wfMsg('tpt-languages-separator'), $languages); return <<<FOO <div class="mw-pt-languages"> <table><tbody> <tr valign="top"> <td class="mw-pt-languages-label"><b>{$legend}</b></td> <td class="mw-pt-languages-list">{$languages}</td></tr> </tbody></table> </div> FOO; }
/** * @param MessageCollection $collection * @return string */ protected function writeReal(MessageCollection $collection) { $mangler = $this->group->getMangler(); $code = $collection->getLanguage(); $block = $this->generateMessageBlock($collection, $mangler); if ($block === false) { return ''; } // Ugly code, relies on side effects // Avoid parsing stuff with fake language code // Premature optimization $this->read('mul'); $filename = $this->group->getSourceFilePath($code); $cache =& self::$cache[$filename]; // Generating authors if (isset($cache['sections'][$code])) { // More premature optimization $fromFile = self::parseAuthorsFromString($cache['sections'][$code]); $collection->addCollectionAuthors($fromFile); } $authors = $collection->getAuthors(); $authors = $this->filterAuthors($authors, $code); $authorList = ''; foreach ($authors as $author) { $authorList .= "\n * @author {$author}"; } // And putting all together $name = TranslateUtils::getLanguageName($code); $native = TranslateUtils::getLanguageName($code, $code); $section = <<<PHP /** {$name} ({$native}){$authorList} */ \$messages['{$code}'] = array({$block}); PHP; // Store the written part, so that when next language is called, // the new version will be used (instead of the old parsed version $cache['sections'][$code] = $section; // Make a copy we can alter $sections = $cache['sections']; $priority = array(); global $wgTranslateDocumentationLanguageCode; $codes = array(0, $this->group->getSourceLanguage(), $wgTranslateDocumentationLanguageCode); foreach ($codes as $pcode) { if (isset($sections[$pcode])) { $priority[] = $sections[$pcode]; unset($sections[$pcode]); } } ksort($sections); return implode("\n\n", $priority) . "\n\n" . implode("\n\n", $sections) . "\n"; }
/** * Fetches and preprocesses graph data that can be fed to graph drawer. * @param $opts FormOptions * @return \arrayof{String,Array} Data indexed by their date labels. */ protected function getData(FormOptions $opts) { global $wgLang; $dbr = wfGetDB(DB_SLAVE); if ($opts['count'] === 'registrations') { $so = new TranslateRegistrationStats($opts); } else { $so = new TranslatePerLanguageStats($opts); } $start = mktime('00', '00', '00', $opts->getValue('startmonth'), $opts->getValue('startday'), $opts->getValue('startyear')); $end = mktime('23', '59', '59', $opts->getValue('endmonth'), $opts->getValue('endday'), $opts->getValue('endyear')); /* Ensure that the first item in the graph has full data even * if it doesn't align with the given 'days' boundary */ /* $cutoff = $now - ( 3600 * 24 * $opts->getValue( 'days' ) ); if ( $opts['scale'] === 'hours' ) { $cutoff -= ( $cutoff % 3600 ); } elseif ( $opts['scale'] === 'days' ) { $cutoff -= ( $cutoff % 86400 ); } elseif ( $opts['scale'] === 'weeks' ) { /* Here we assume that week starts on monday, which does not * always hold true. Go backwards day by day until we are on monday */ /*while ( date( 'D', $cutoff ) !== "Mon" ) { $cutoff -= 86400; } $cutoff -= ( $cutoff % 86400 ); } elseif ( $opts['scale'] === 'months' ) { // Go backwards day by day until we are on the first day of the month while ( date( 'j', $cutoff ) !== "1" ) { $cutoff -= 86400; } $cutoff -= ( $cutoff % 86400 ); }*/ $tables = array(); $fields = array(); $conds = array(); $type = __METHOD__; $options = array(); $so->preQuery($tables, $fields, $conds, $type, $options, $start, $end); $res = $dbr->select($tables, $fields, $conds, $type, $options); wfDebug(__METHOD__ . "-queryend\n"); // Start processing the data $dateFormat = $so->getDateFormat(); $increment = self::getIncrement($opts['scale']); $labels = $so->labels(); $keys = array_keys($labels); $values = array_pad(array(), count($labels), 0); $defaults = array_combine($keys, $values); $data = array(); // Allow 10 seconds in the future for processing time while ($start <= $end) { $date = $wgLang->sprintfDate($dateFormat, wfTimestamp(TS_MW, $start)); $start += $increment; $data[$date] = $defaults; } // Processing $labelToIndex = array_flip($labels); foreach ($res as $row) { $indexLabels = $so->indexOf($row); if ($indexLabels === false) { continue; } foreach ((array) $indexLabels as $i) { if (!isset($labelToIndex[$i])) { continue; } $date = $wgLang->sprintfDate($dateFormat, $so->getTimestamp($row)); // Ignore values outside range if (!isset($data[$date])) { continue; } $data[$date][$labelToIndex[$i]]++; } } // Don't display dummy label if (count($labels) === 1 && $labels[0] === 'all') { $labels = array(); } foreach ($labels as &$label) { if (strpos($label, '@') === false) { continue; } list($groupId, $code) = explode('@', $label, 2); if ($code && $groupId) { $code = TranslateUtils::getLanguageName($code, false, $wgLang->getCode()) . " ({$code})"; $group = MessageGroups::getGroup($groupId); $group = $group ? $group->getLabel() : $groupId; $label = "{$group} @ {$code}"; } elseif ($code) { $label = TranslateUtils::getLanguageName($code, false, $wgLang->getCode()) . " ({$code})"; } elseif ($groupId) { $group = MessageGroups::getGroup($groupId); $label = $group ? $group->getLabel() : $groupId; } } $last = array_splice($data, -1, 1); $data[key($last) . '*'] = current($last); return array($labels, $data); }
protected function doGettextHeader(MessageCollection $collection, $template, &$pluralCount) { global $wgSitename; $code = $collection->code; $name = TranslateUtils::getLanguageName($code); $native = TranslateUtils::getLanguageName($code, $code); $authors = $this->doAuthors($collection); if (isset($this->extra['header'])) { $extra = "# --\n" . $this->extra['header']; } else { $extra = ''; } $output = <<<PHP # Translation of {$this->group->getLabel()} to {$name} ({$native}) # Exported from {$wgSitename} # {$authors}{$extra} PHP; // Make sure there is no empty line before msgid $output = trim($output) . "\n"; $specs = isset($template['HEADERS']) ? $template['HEADERS'] : array(); $timestamp = wfTimestampNow(); $specs['PO-Revision-Date'] = self::formatTime($timestamp); if ($this->offlineMode) { $specs['POT-Creation-Date'] = self::formatTime($timestamp); } elseif ($this->group instanceof MessageGroupBase) { $specs['X-POT-Import-Date'] = self::formatTime(wfTimestamp(TS_MW, $this->getPotTime())); } $specs['Content-Type'] = 'text/plain; charset=UTF-8'; $specs['Content-Transfer-Encoding'] = '8bit'; $specs['Language'] = wfBCP47($this->group->mapCode($code)); Hooks::run('Translate:GettextFFS:headerFields', array(&$specs, $this->group, $code)); $specs['X-Generator'] = $this->getGenerator(); if ($this->offlineMode) { $specs['X-Language-Code'] = $code; $specs['X-Message-Group'] = $this->group->getId(); } $plural = self::getPluralRule($code); if ($plural) { $specs['Plural-Forms'] = $plural; } elseif (!isset($specs['Plural-Forms'])) { $specs['Plural-Forms'] = 'nplurals=2; plural=(n != 1);'; } $match = array(); preg_match('/nplurals=(\\d+);/', $specs['Plural-Forms'], $match); $pluralCount = $match[1]; $output .= 'msgid ""' . "\n"; $output .= 'msgstr ""' . "\n"; $output .= '""' . "\n"; foreach ($specs as $k => $v) { $output .= self::escape("{$k}: {$v}\n") . "\n"; } $output .= "\n"; return $output; }
protected function getLanguageNames( $code ) { $name = TranslateUtils::getLanguageName( $code ); $native = TranslateUtils::getLanguageName( $code, true ); return array( $name, $native ); }
/** * 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; }
public function getOtherLanguagesBox() { $code = $this->handle->getCode(); $page = $this->handle->getKey(); $ns = $this->handle->getTitle()->getNamespace(); $boxes = array(); foreach (self::getFallbacks($code) as $fbcode) { $text = TranslateUtils::getMessageContent($page, $fbcode, $ns); if ($text === null) { continue; } $context = RequestContext::getMain(); $label = TranslateUtils::getLanguageName($fbcode, $context->getLanguage()->getCode()) . $context->msg('word-separator')->text() . $context->msg('parentheses', wfBCP47($fbcode))->text(); $target = Title::makeTitleSafe($ns, "{$page}/{$fbcode}"); if ($target) { $label = self::ajaxEditLink($target, htmlspecialchars($label)); } $dialogID = $this->dialogID(); $id = Sanitizer::escapeId("other-{$fbcode}-{$dialogID}"); $params = array('class' => 'mw-translate-edit-item'); $display = TranslateUtils::convertWhiteSpaceToHTML($text); $display = Html::rawElement('div', array('lang' => $fbcode, 'dir' => Language::factory($fbcode)->getDir()), $display); $contents = self::legend($label) . "\n" . $this->adder($id, $fbcode) . $display . self::clear(); $boxes[] = Html::rawElement('div', $params, $contents) . $this->wrapInsert($id, $text); } if (count($boxes)) { $sep = Html::element('hr', array('class' => 'mw-translate-sep')); return TranslateUtils::fieldset(wfMessage('translate-edit-in-other-languages', $page)->escaped(), implode("{$sep}\n", $boxes), array('class' => 'mw-sp-translate-edit-inother')); } return null; }
/** * @param $msg string * @param $code string * @param $title Title * @param $makelink * @return string */ protected function doBox($msg, $code, $title = false, $makelink = false) { global $wgUser, $wgLang; $name = TranslateUtils::getLanguageName($code, false, $wgLang->getCode()); $code = wfBCP47($code); $skin = $wgUser->getSkin(); $attributes = array(); if (!$title) { $attributes['class'] = 'mw-sp-translate-in-other-big'; } elseif ($code === 'en') { $attributes['class'] = 'mw-sp-translate-edit-definition'; } else { $attributes['class'] = 'mw-sp-translate-edit-committed'; } if (mb_strlen($msg) < 100 && !$title) { $attributes['class'] = 'mw-sp-translate-in-other-small'; } $msg = TranslateUtils::convertWhiteSpaceToHTML($msg); if (!$title) { $title = "{$name} ({$code})"; } if ($makelink) { $linkTitle = Title::newFromText($makelink); $title = $skin->link($linkTitle, htmlspecialchars($title), array(), array('action' => 'edit')); } return TranslateUtils::fieldset($title, Html::element('span', null, $msg), $attributes); }
public function execute( $messages ) { global $wgOut, $wgLang; $this->out = $wgOut; // Set up diff engine $diff = new DifferenceEngine; $diff->showDiffStyle(); $diff->setReducedLineNumbers(); // Check whether we do processing $process = $this->allowProcess(); // Initialise collection $group = $this->getGroup(); $code = $this->getCode(); $collection = $group->initCollection( $code ); $collection->loadTranslations(); $this->out->addHTML( $this->doHeader() ); // Determine changes $alldone = $process; $changed = array(); foreach ( $messages as $key => $value ) { $fuzzy = $old = false; if ( isset( $collection[$key] ) ) { $old = $collection[$key]->translation(); } // No changes at all, ignore if ( strval( $old ) === strval( $value ) ) { continue; } if ( $old === false ) { $name = wfMsgHtml( 'translate-manage-import-new', '<code style="font-weight:normal;">' . htmlspecialchars( $key ) . '</code>' ); $text = TranslateUtils::convertWhiteSpaceToHTML( $value ); $changed[] = self::makeSectionElement( $name, 'new', $text ); } else { $diff->setText( $old, $value ); $text = $diff->getDiff( '', '' ); $type = 'changed'; global $wgRequest; $action = $wgRequest->getVal( self::escapeNameForPHP( "action-$type-$key" ) ); if ( $process ) { if ( !count( $changed ) ) { $changed[] = '<ul>'; } if ( $action === null ) { $message = wfMsgExt( 'translate-manage-inconsistent', 'parseinline', wfEscapeWikiText( "action-$type-$key" ) ); $changed[] = "<li>$message</li></ul>"; $process = false; } else { // Check processing time if ( !isset( $this->time ) ) { $this->time = wfTimestamp(); } $message = self::doAction( $action, $group, $key, $code, $value ); $key = array_shift( $message ); $params = $message; $message = wfMsgExt( $key, 'parseinline', $params ); $changed[] = "<li>$message</li>"; if ( $this->checkProcessTime() ) { $process = false; $duration = $wgLang->formatNum( $this->processingTime ); $message = wfMsgExt( 'translate-manage-toolong', 'parseinline', $duration ); $changed[] = "<li>$message</li></ul>"; } continue; } } $alldone = false; $actions = $this->getActions(); $defaction = $this->getDefaultAction( $fuzzy, $action ); $act = array(); foreach ( $actions as $action ) { $label = wfMsg( "translate-manage-action-$action" ); $name = self::escapeNameForPHP( "action-$type-$key" ); $id = Sanitizer::escapeId( "action-$key-$action" ); $act[] = Xml::radioLabel( $label, $name, $action, $id, $action === $defaction ); } $name = wfMsg( 'translate-manage-import-diff', '<code style="font-weight:normal;">' . htmlspecialchars( $key ) . '</code>', implode( ' ', $act ) ); $changed[] = self::makeSectionElement( $name, $type, $text ); } } if ( !$process ) { $collection->filter( 'hastranslation', false ); $keys = $collection->getMessageKeys(); $diff = array_diff( $keys, array_keys( $messages ) ); foreach ( $diff as $s ) { // @todo FIXME: Use CSS file. $name = wfMsgHtml( 'translate-manage-import-deleted', '<code style="font-weight:normal;">' . htmlspecialchars( $s ) . '</code>' ); $text = TranslateUtils::convertWhiteSpaceToHTML( $collection[$s]->translation() ); $changed[] = self::makeSectionElement( $name, 'deleted', $text ); } } if ( $process || ( !count( $changed ) && $code !== 'en' ) ) { if ( !count( $changed ) ) { $this->out->addWikiMsg( 'translate-manage-nochanges-other' ); } if ( !count( $changed ) || strpos( $changed[count( $changed ) - 1], '<li>' ) !== 0 ) { $changed[] = '<ul>'; } $message = wfMsgExt( 'translate-manage-import-done', 'parseinline' ); $changed[] = "<li>$message</li></ul>"; $this->out->addHTML( implode( "\n", $changed ) ); } else { // END if ( count( $changed ) ) { if ( $code === 'en' ) { $this->out->addWikiMsg( 'translate-manage-intro-en' ); } else { $lang = TranslateUtils::getLanguageName( $code, false, $wgLang->getCode() ); $this->out->addWikiMsg( 'translate-manage-intro-other', $lang ); } $this->out->addHTML( Html::hidden( 'language', $code ) ); $this->out->addHTML( implode( "\n", $changed ) ); $this->out->addHTML( Xml::submitButton( wfMsg( 'translate-manage-submit' ) ) ); } else { $this->out->addWikiMsg( 'translate-manage-nochanges' ); } } $this->out->addHTML( $this->doFooter() ); return $alldone; }
/** * Replace the normal save button with one that says if you are editing * message documentation to try to avoid accidents. * Hook: EditPageBeforeEditButtons */ static function buttonHack( EditPage $editpage, &$buttons, $tabindex ) { global $wgLang; $handle = new MessageHandle( $editpage->mTitle ); if ( !$handle->isValid() ) { return true; } if ( $handle->isDoc() ) { $name = TranslateUtils::getLanguageName( $handle->getCode(), false, $wgLang->getCode() ); $temp = array( 'id' => 'wpSave', 'name' => 'wpSave', 'type' => 'submit', 'tabindex' => ++$tabindex, 'value' => wfMsg( 'translate-save', $name ), 'accesskey' => wfMsg( 'accesskey-save' ), 'title' => wfMsg( 'tooltip-save' ) . ' [' . wfMsg( 'accesskey-save' ) . ']', ); $buttons['save'] = Xml::element( 'input', $temp, '' ); } global $wgTranslateSupportUrl; if ( !$wgTranslateSupportUrl ) { return true; } $supportTitle = Title::newFromText( $wgTranslateSupportUrl['page'] ); if ( !$supportTitle ) { return true; } $supportParams = $wgTranslateSupportUrl['params']; foreach ( $supportParams as &$value ) { $value = str_replace( '%MESSAGE%', $handle->getTitle()->getPrefixedText(), $value ); } $temp = array( 'id' => 'wpSupport', 'name' => 'wpSupport', 'type' => 'button', 'tabindex' => ++$tabindex, 'value' => wfMsg( 'translate-js-support' ), 'title' => wfMsg( 'translate-js-support-title' ), 'data-load-url' => $supportTitle->getLocalUrl( $supportParams ), 'onclick' => "window.open( jQuery(this).attr('data-load-url') );", ); $buttons['ask'] = Html::element( 'input', $temp, '' ); return true; }
/** * @param string $code * @param array $authors * @return string */ private function header($code, $authors) { global $wgSitename; $name = TranslateUtils::getLanguageName($code); $authorsList = $this->authorsList($authors); return <<<EOT /** * Messages for {$name} * Exported from {$wgSitename} * {$authorsList} */ define( EOT; }
protected function doGettextHeader( MessageCollection $collection, $template, &$pluralCount ) { global $wgSitename, $wgServer, $wgCanonicalServer; $code = $collection->code; $name = TranslateUtils::getLanguageName( $code ); $native = TranslateUtils::getLanguageName( $code, true ); $authors = $this->doAuthors( $collection ); if ( isset( $this->extra['header'] ) ) { $extra = "# --\n" . $this->extra['header']; } else { $extra = ''; } $output = <<<PHP # Translation of {$this->group->getLabel()} to $name ($native) # Exported from $wgSitename # $authors$extra PHP; // Make sure there is no empty line before msgid $output = trim( $output ) . "\n"; // @todo portal is twn specific // BC for MW <1.18 if ( method_exists( 'Title', 'getCanonicalUrl' ) ) { $portal = Title::makeTitle( NS_PORTAL, $code )->getCanonicalUrl(); $server = $wgCanonicalServer; } else { $portal = Title::makeTitle( NS_PORTAL, $code )->getFullUrl(); $server = $wgServer; } $specs = isset( $template['HEADERS'] ) ? $template['HEADERS'] : array(); $timestamp = wfTimestampNow(); $specs['Project-Id-Version'] = $this->group->getLabel(); $specs['Report-Msgid-Bugs-To'] = $wgSitename; $specs['PO-Revision-Date'] = self::formatTime( $timestamp ); if ( $this->offlineMode ) { $specs['POT-Creation-Date'] = self::formatTime( $timestamp ); } elseif ( $this->group instanceof MessageGroupBase ) { $specs['X-POT-Import-Date'] = self::formatTime( wfTimestamp( TS_MW, $this->getPotTime() ) ); } $specs['Language-Team'] = "$name <$portal>"; $specs['Content-Type'] = 'text/plain; charset=UTF-8'; $specs['Content-Transfer-Encoding'] = '8bit'; $specs['X-Generator'] = $this->getGenerator(); $specs['X-Translation-Project'] = "$wgSitename at $server"; $specs['X-Language-Code'] = $code; if ( $this->offlineMode ) { $specs['X-Message-Group'] = $this->group->getId(); } else { // Prepend # so that message import does not think this is a file it can import $specs['X-Message-Group'] = '#' . $this->group->getId(); } $plural = self::getPluralRule( $code ); if ( $plural ) { $specs['Plural-Forms'] = $plural; } elseif ( !isset( $specs['Plural-Forms'] ) ) { $specs['Plural-Forms'] = 'nplurals=2; plural=(n != 1);'; } $match = array(); preg_match( '/nplurals=(\d+);/', $specs['Plural-Forms'], $match ); $pluralCount = $match[1]; $output .= 'msgid ""' . "\n"; $output .= 'msgstr ""' . "\n"; $output .= '""' . "\n"; foreach ( $specs as $k => $v ) { $output .= self::escape( "$k: $v\n" ) . "\n"; } $output .= "\n"; return $output; }
/** * Output something helpful to guide the confused user. */ protected function outputIntroduction() { $languageName = TranslateUtils::getLanguageName($this->target, $this->getLanguage()->getCode()); $rcInLangLink = Linker::link(SpecialPage::getTitleFor('Translate', '!recent'), $this->msg('languagestats-recenttranslations')->escaped(), array(), array('action' => 'proofread', 'language' => $this->target)); $out = $this->msg('languagestats-stats-for', $languageName)->rawParams($rcInLangLink)->parseAsBlock(); $this->getOutput()->addHTML($out); }
/** * Fetches and preprocesses graph data that can be fed to graph drawer. * @param $opts FormOptions * @return \arrayof{String,Array} Data indexed by their date labels. */ protected function getData( FormOptions $opts ) { global $wgLang; $dbr = wfGetDB( DB_SLAVE ); if ( $opts['count'] === 'registrations' ) { $so = new TranslateRegistrationStats( $opts ); } else { $so = new TranslatePerLanguageStats( $opts ); } $fixedStart = $opts->getValue( 'start' ) !== ''; $now = time(); $period = 3600 * 24 * $opts->getValue( 'days' ); if ( $fixedStart ) { $cutoff = wfTimestamp( TS_UNIX, $opts->getValue( 'start' ) ); } else { $cutoff = $now - $period; } $cutoff = self::roundTimestampToCutoff( $opts['scale'], $cutoff, 'earlier' ); $start = $cutoff; if ( $fixedStart ) { $end = self::roundTimestampToCutoff( $opts['scale'], $start + $period, 'later' ) -1; } else { $end = null; } $tables = array(); $fields = array(); $conds = array(); $type = __METHOD__; $options = array(); $so->preQuery( $tables, $fields, $conds, $type, $options, $start, $end ); $res = $dbr->select( $tables, $fields, $conds, $type, $options ); wfDebug( __METHOD__ . "-queryend\n" ); // Start processing the data $dateFormat = $so->getDateFormat(); $increment = self::getIncrement( $opts['scale'] ); $labels = $so->labels(); $keys = array_keys( $labels ); $values = array_pad( array(), count( $labels ), 0 ); $defaults = array_combine( $keys, $values ); $data = array(); // Allow 10 seconds in the future for processing time $lastValue = $end !== null ? $end : $now + 10; while ( $cutoff <= $lastValue ) { $date = $wgLang->sprintfDate( $dateFormat, wfTimestamp( TS_MW, $cutoff ) ); $cutoff += $increment; $data[$date] = $defaults; } // Processing $labelToIndex = array_flip( $labels ); foreach ( $res as $row ) { $indexLabels = $so->indexOf( $row ); if ( $indexLabels === false ) { continue; } foreach ( (array) $indexLabels as $i ) { if ( !isset( $labelToIndex[$i] ) ) { continue; } $date = $wgLang->sprintfDate( $dateFormat, $so->getTimestamp( $row ) ); // Ignore values outside range if ( !isset( $data[$date] ) ) { continue; } $data[$date][$labelToIndex[$i]]++; } } // Don't display dummy label if ( count( $labels ) === 1 && $labels[0] === 'all' ) { $labels = array(); } foreach ( $labels as &$label ) { if ( strpos( $label, '@' ) === false ) continue; list( $groupId, $code ) = explode( '@', $label, 2 ); if ( $code && $groupId ) { $code = TranslateUtils::getLanguageName( $code, false, $wgLang->getCode() ) . " ($code)"; $group = MessageGroups::getGroup( $groupId ); $group = $group ? $group->getLabel() : $groupId; $label = "$group @ $code"; } elseif ( $code ) { $label = TranslateUtils::getLanguageName( $code, false, $wgLang->getCode() ) . " ($code)"; } elseif ( $groupId ) { $group = MessageGroups::getGroup( $groupId ); $label = $group ? $group->getLabel() : $groupId; } } if ( $end == null ) { $last = array_splice( $data, -1, 1 ); // Indicator that the last value is not full $data[key( $last ) . '*'] = current( $last ); } return array( $labels, $data ); }
public function execute($messages) { $context = RequestContext::getMain(); $this->out = $context->getOutput(); // Set up diff engine $diff = new DifferenceEngine(); $diff->showDiffStyle(); $diff->setReducedLineNumbers(); // Check whether we do processing $process = $this->allowProcess(); // Initialise collection $group = $this->getGroup(); $code = $this->getCode(); $collection = $group->initCollection($code); $collection->loadTranslations(); $this->out->addHTML($this->doHeader()); // Determine changes $alldone = $process; $changed = array(); foreach ($messages as $key => $value) { $fuzzy = $old = false; if (isset($collection[$key])) { $old = $collection[$key]->translation(); } // No changes at all, ignore if (strval($old) === strval($value)) { continue; } if ($old === false) { $para = '<code class="mw-tmi-new">' . htmlspecialchars($key) . '</code>'; $name = $context->msg('translate-manage-import-new')->rawParams($para)->escaped(); $text = TranslateUtils::convertWhiteSpaceToHTML($value); $changed[] = self::makeSectionElement($name, 'new', $text); } else { $oldContent = ContentHandler::makeContent($old, $diff->getTitle()); $newContent = ContentHandler::makeContent($value, $diff->getTitle()); $diff->setContent($oldContent, $newContent); $text = $diff->getDiff('', ''); $type = 'changed'; $action = $context->getRequest()->getVal(self::escapeNameForPHP("action-{$type}-{$key}")); if ($process) { if (!count($changed)) { $changed[] = '<ul>'; } if ($action === null) { $message = $context->msg('translate-manage-inconsistent', wfEscapeWikiText("action-{$type}-{$key}"))->parse(); $changed[] = "<li>{$message}</li></ul>"; $process = false; } else { // Check processing time if (!isset($this->time)) { $this->time = wfTimestamp(); } $message = self::doAction($action, $group, $key, $code, $value); $key = array_shift($message); $params = $message; $message = $context->msg($key, $params)->parse(); $changed[] = "<li>{$message}</li>"; if ($this->checkProcessTime()) { $process = false; $message = $context->msg('translate-manage-toolong')->numParams($this->processingTime)->parse(); $changed[] = "<li>{$message}</li></ul>"; } continue; } } $alldone = false; $actions = $this->getActions(); $defaction = $this->getDefaultAction($fuzzy, $action); $act = array(); // Give grep a chance to find the usages: // translate-manage-action-import, translate-manage-action-conflict, // translate-manage-action-ignore, translate-manage-action-fuzzy foreach ($actions as $action) { $label = $context->msg("translate-manage-action-{$action}")->text(); $name = self::escapeNameForPHP("action-{$type}-{$key}"); $id = Sanitizer::escapeId("action-{$key}-{$action}"); $act[] = Xml::radioLabel($label, $name, $action, $id, $action === $defaction); } $param = '<code class="mw-tmi-diff">' . htmlspecialchars($key) . '</code>'; $name = $context->msg('translate-manage-import-diff', $param, implode(' ', $act))->text(); $changed[] = self::makeSectionElement($name, $type, $text); } } if (!$process) { $collection->filter('hastranslation', false); $keys = $collection->getMessageKeys(); $diff = array_diff($keys, array_keys($messages)); foreach ($diff as $s) { $para = '<code class="mw-tmi-deleted">' . htmlspecialchars($s) . '</code>'; $name = $context->msg('translate-manage-import-deleted')->rawParams($para)->escaped(); $text = TranslateUtils::convertWhiteSpaceToHTML($collection[$s]->translation()); $changed[] = self::makeSectionElement($name, 'deleted', $text); } } if ($process || !count($changed) && $code !== 'en') { if (!count($changed)) { $this->out->addWikiMsg('translate-manage-nochanges-other'); } if (!count($changed) || strpos($changed[count($changed) - 1], '<li>') !== 0) { $changed[] = '<ul>'; } $message = $context->msg('translate-manage-import-done')->parse(); $changed[] = "<li>{$message}</li></ul>"; $this->out->addHTML(implode("\n", $changed)); } else { // END if (count($changed)) { if ($code === 'en') { $this->out->addWikiMsg('translate-manage-intro-en'); } else { $lang = TranslateUtils::getLanguageName($code, $context->getLanguage()->getCode()); $this->out->addWikiMsg('translate-manage-intro-other', $lang); } $this->out->addHTML(Html::hidden('language', $code)); $this->out->addHTML(implode("\n", $changed)); $this->out->addHTML(Xml::submitButton($context->msg('translate-manage-submit')->text())); } else { $this->out->addWikiMsg('translate-manage-nochanges'); } } $this->out->addHTML($this->doFooter()); return $alldone; }