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;
 }
Ejemplo n.º 2
0
	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 );
	}
Ejemplo n.º 9
0
 /**
  * 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 = "&#160;<sup>" . wfMsgHtml('translate-translations-history-short') . "</sup>&#160;";
     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));
 }
Ejemplo n.º 10
0
 /**
  * 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 */
    }
Ejemplo n.º 14
0
    /**
     * @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";
    }
Ejemplo n.º 16
0
 /**
  * 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;
    }
Ejemplo n.º 18
0
	protected function getLanguageNames( $code ) {
		$name = TranslateUtils::getLanguageName( $code );
		$native = TranslateUtils::getLanguageName( $code, true );

		return array( $name, $native );
	}
Ejemplo n.º 19
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;
 }
 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;
 }
Ejemplo n.º 21
0
 /**
  * @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;
    }
Ejemplo n.º 25
0
	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;
 }