public function contents()
 {
     $optional = $this->context->msg('translate-optional')->escaped();
     $this->doLinkBatch();
     $sourceLang = Language::factory($this->group->getSourceLanguage());
     $targetLang = Language::factory($this->collection->getLanguage());
     $titleMap = $this->collection->keys();
     $output = '';
     $this->collection->initMessages();
     // Just to be sure
     /**
      * @var TMessage $m
      */
     foreach ($this->collection as $key => $m) {
         $tools = array();
         /**
          * @var Title $title
          */
         $title = $titleMap[$key];
         $original = $m->definition();
         $translation = $m->translation();
         $hasTranslation = $translation !== null;
         if ($hasTranslation) {
             $message = $translation;
             $extraAttribs = self::getLanguageAttributes($targetLang);
         } else {
             $message = $original;
             $extraAttribs = self::getLanguageAttributes($sourceLang);
         }
         Hooks::run('TranslateFormatMessageBeforeTable', array(&$message, $m, $this->group, $targetLang, &$extraAttribs));
         // Using Html::element( a ) because Linker::link is memory hog.
         // It takes about 20 KiB per call, and that times 5000 is quite
         // a lot of memory.
         $niceTitle = htmlspecialchars($this->context->getLanguage()->truncate($title->getPrefixedText(), -35));
         $linkAttribs = array('href' => $title->getLocalUrl(array('action' => 'edit')));
         $linkAttribs += TranslationEditPage::jsEdit($title, $this->group->getId());
         $tools['edit'] = Html::element('a', $linkAttribs, $niceTitle);
         $anchor = 'msg_' . $key;
         $anchor = Xml::element('a', array('id' => $anchor, 'href' => "#{$anchor}"), "↓");
         $extra = '';
         if ($m->hasTag('optional')) {
             $extra = '<br />' . $optional;
         }
         $tqeData = $extraAttribs + array('data-title' => $title->getPrefixedText(), 'data-group' => $this->group->getId(), 'id' => 'tqe-anchor-' . substr(sha1($title->getPrefixedText()), 0, 12), 'class' => 'tqe-inlineeditable ' . ($hasTranslation ? 'translated' : 'untranslated'));
         $button = $this->getReviewButton($m);
         $status = $this->getReviewStatus($m);
         $leftColumn = $button . $anchor . $tools['edit'] . $extra . $status;
         if ($this->reviewMode) {
             $output .= Xml::tags('tr', array('class' => 'orig'), Xml::tags('td', array('rowspan' => '2'), $leftColumn) . Xml::tags('td', self::getLanguageAttributes($sourceLang), TranslateUtils::convertWhiteSpaceToHTML($original)));
             $output .= Xml::tags('tr', null, Xml::tags('td', $tqeData, TranslateUtils::convertWhiteSpaceToHTML($message)));
         } else {
             $output .= Xml::tags('tr', array('class' => 'def'), Xml::tags('td', null, $leftColumn) . Xml::tags('td', $tqeData, TranslateUtils::convertWhiteSpaceToHTML($message)));
         }
         $output .= "\n";
     }
     return $output;
 }
 /**
  * @param MessageCollection $collection
  * @return string
  */
 protected function writeReal(MessageCollection $collection)
 {
     $messages = array();
     $template = $this->read($collection->getLanguage());
     if (isset($template['METADATA'])) {
         $messages['@metadata'] = $template['METADATA'];
     }
     $authors = $collection->getAuthors();
     $authors = $this->filterAuthors($authors, $collection->code);
     if (isset($template['AUTHORS'])) {
         $authors = array_unique(array_merge($template['AUTHORS'], $authors));
     }
     if ($authors !== array()) {
         $messages['@metadata']['authors'] = array_values($authors);
     }
     $mangler = $this->group->getMangler();
     /**
      * @var $m ThinMessage
      */
     foreach ($collection as $key => $m) {
         $value = $m->translation();
         if ($value === null) {
             continue;
         }
         if ($m->hasTag('fuzzy')) {
             $value = str_replace(TRANSLATE_FUZZY, '', $value);
         }
         $key = $mangler->unmangle($key);
         $messages[$key] = $value;
     }
     // Do not create empty files
     if (!count($messages)) {
         return '';
     }
     return FormatJson::encode($messages, "\t", FormatJson::ALL_OK) . "\n";
 }
 protected function writeReal(MessageCollection $collection)
 {
     $output = '';
     $mangler = $this->group->getMangler();
     /**
      * @var $m ThinMessage
      */
     foreach ($collection as $key => $m) {
         $value = $m->translation();
         if ($value === null) {
             continue;
         }
         $comment = '';
         if ($m->hasTag('fuzzy')) {
             $value = str_replace(TRANSLATE_FUZZY, '', $value);
             $comment = "; Fuzzy\n";
         }
         $key = $mangler->unmangle($key);
         $output .= "{$comment}{$key} = {$value}\n";
     }
     // Do not create empty files
     if ($output === '') {
         return '';
     }
     global $wgSitename;
     // Accumulator
     $header = "; Exported from {$wgSitename}\n";
     $authors = $collection->getAuthors();
     $authors = $this->filterAuthors($authors, $collection->getLanguage());
     foreach ($authors as $author) {
         $header .= "; Author: {$author}\n";
     }
     $header .= '[' . $collection->getLanguage() . "]\n";
     return $header . $output;
 }
    /**
     * @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";
    }