public static function sourceExport(RequestContext $context, TranslateTask $task = null, MessageGroup $group, array $options)
 {
     if ($task || $options['taction'] !== 'export' || !$group instanceof WikiPageMessageGroup) {
         return true;
     }
     $page = TranslatablePage::newFromTitle($group->getTitle());
     $collection = $group->initCollection($options['language']);
     $collection->loadTranslations(DB_MASTER);
     $text = $page->getParse()->getTranslationPageText($collection);
     $display = $page->getPageDisplayTitle($options['language']);
     if ($display) {
         $text = "{{DISPLAYTITLE:{$display}}}{$text}";
     }
     $output = Html::element('textarea', array('rows' => 25), $text);
     $context->getOutput()->addHtml($output);
     return false;
 }
 /**
  * @param MessageGroup $group
  * @param string $code Language code
  * @return int[] ( total, translated, fuzzy, proofread )
  */
 protected static function calculateGroup($group, $code)
 {
     global $wgTranslateDocumentationLanguageCode;
     # Calculate if missing and store in the db
     $collection = $group->initCollection($code);
     if ($code === $wgTranslateDocumentationLanguageCode) {
         $ffs = $group->getFFS();
         if ($ffs instanceof GettextFFS) {
             $template = $ffs->read('en');
             $infile = array();
             foreach ($template['TEMPLATE'] as $key => $data) {
                 if (isset($data['comments']['.'])) {
                     $infile[$key] = '1';
                 }
             }
             $collection->setInFile($infile);
         }
     }
     $collection->filter('ignored');
     $collection->filter('optional');
     // Store the count of real messages for later calculation.
     $total = count($collection);
     // Count fuzzy first.
     $collection->filter('fuzzy');
     $fuzzy = $total - count($collection);
     // Count the completed translations.
     $collection->filter('hastranslation', false);
     $translated = count($collection);
     // Count how many of the completed translations
     // have been proofread
     $collection->filter('reviewer', false);
     $proofread = count($collection);
     return array(self::TOTAL => $total, self::TRANSLATED => $translated, self::FUZZY => $fuzzy, self::PROOFREAD => $proofread);
 }
 protected function exportGroup(MessageGroup $group, $multi = false)
 {
     // Make sure all existing connections are dead,
     // we can't use them in forked children.
     LBFactory::destroyInstance();
     $server = TTMServer::primary();
     $id = $group->getId();
     $sourceLanguage = $group->getSourceLanguage();
     if ($multi) {
         $stats = MessageGroupStats::forGroup($id);
         $this->statusLine("Loaded stats for {$id}\n");
     } else {
         $this->statusLine("Loading stats... ", 4);
         $stats = MessageGroupStats::forGroup($id);
         $this->output("done!", 4);
         $this->statusLine("Inserting sources: ", 5);
     }
     $collection = $group->initCollection($sourceLanguage);
     $collection->filter('ignored');
     $collection->filter('optional');
     $collection->initMessages();
     $sids = array();
     $counter = 0;
     foreach ($collection->keys() as $mkey => $title) {
         $def = $collection[$mkey]->definition();
         $sids[$mkey] = $server->insertSource($title, $sourceLanguage, $def);
         if (++$counter % $this->mBatchSize === 0 && !$multi) {
             wfWaitForSlaves(10);
             $this->output('.', 5);
         }
     }
     $total = count($sids);
     if ($multi) {
         $this->statusLine("Inserted {$total} source entries for {$id}\n");
     } else {
         $this->output("{$total} entries", 5);
         $this->statusLine("Inserting translations...", 6);
     }
     $dbw = $server->getDB(DB_MASTER);
     foreach ($stats as $targetLanguage => $numbers) {
         if ($targetLanguage === $sourceLanguage) {
             continue;
         }
         if ($numbers[MessageGroupStats::TRANSLATED] === 0) {
             continue;
         }
         if (!$multi) {
             $this->output(sprintf("%19s  ", $targetLanguage), $targetLanguage);
         }
         $collection->resetForNewLanguage($targetLanguage);
         $collection->filter('ignored');
         $collection->filter('optional');
         $collection->filter('translated', false);
         $collection->loadTranslations();
         $inserts = array();
         foreach ($collection->keys() as $mkey => $title) {
             $inserts[] = array('tmt_sid' => $sids[$mkey], 'tmt_lang' => $targetLanguage, 'tmt_text' => $collection[$mkey]->translation());
         }
         do {
             $batch = array_splice($inserts, 0, $this->mBatchSize);
             $dbw->insert('translate_tmt', $batch, __METHOD__);
             if (!$multi) {
                 $this->output('.', $targetLanguage);
             }
             wfWaitForSlaves(10);
         } while (count($inserts));
     }
     if ($multi) {
         $this->statusLine("Inserted translations for {$id}\n");
     }
 }
 /**
  * Do some conflict resolution for translations.
  * @param string $code Language code.
  * @param bool|int $startTs Time of the last export (changes in wiki after
  * this will conflict)
  * @param bool|int $endTs Time of the last export (changes in source before
  * this won't conflict)
  * @param bool|int $changeTs When change happened in the source.
  */
 public function checkConflicts($code, $startTs = false, $endTs = false, $changeTs = false)
 {
     $messages = $this->group->load($code);
     if (!count($messages)) {
         return;
     }
     $collection = $this->group->initCollection($code);
     $collection->filter('ignored');
     $collection->loadTranslations();
     foreach ($messages as $key => $translation) {
         if (!isset($collection[$key])) {
             continue;
         }
         // @todo Temporary exception. Should be fixed elsewhere more generically.
         if ($translation == '{{PLURAL:GETTEXT|}}') {
             return;
         }
         $title = Title::makeTitleSafe($this->group->getNamespace(), "{$key}/{$code}");
         $page = $title->getPrefixedText();
         if ($collection[$key]->translation() === null) {
             $this->reportProgress("Importing {$page} as a new translation\n", 'importing');
             $this->import($title, $translation, 'Importing a new translation');
             continue;
         }
         $current = str_replace(TRANSLATE_FUZZY, '', $collection[$key]->translation());
         $translation = str_replace(TRANSLATE_FUZZY, '', $translation);
         if ($translation === $current) {
             continue;
         }
         $this->reportProgress("Conflict in " . $this->color('bold', $page) . "!", $page);
         $iso = 'xnY-xnm-xnd"T"xnH:xni:xns';
         $lang = RequestContext::getMain()->getLanguage();
         // Finally all is ok, now lets start comparing timestamps
         // Make sure we are comparing timestamps in same format
         $wikiTs = $this->getLastGoodChange($title, $startTs);
         if ($wikiTs) {
             $wikiTs = wfTimestamp(TS_UNIX, $wikiTs);
             $wikiDate = $lang->sprintfDate($iso, wfTimestamp(TS_MW, $wikiTs));
         } else {
             $wikiDate = 'Unknown';
         }
         if ($startTs) {
             $startTs = wfTimestamp(TS_UNIX, $startTs);
         }
         if ($endTs) {
             $endTs = wfTimestamp(TS_UNIX, $endTs);
         }
         if ($changeTs) {
             $changeTs = wfTimestamp(TS_UNIX, $changeTs);
             $changeDate = $lang->sprintfDate($iso, wfTimestamp(TS_MW, $changeTs));
         } else {
             $changeDate = 'Unknown';
         }
         if ($changeTs) {
             if ($wikiTs > $startTs && $changeTs <= $endTs) {
                 $this->reportProgress(" →Changed in wiki after export: IGNORE", $page);
                 continue;
             } elseif (!$wikiTs || $changeTs > $endTs && $wikiTs < $startTs) {
                 $this->reportProgress(" →Changed in source after export: IMPORT", $page);
                 $this->import($title, $translation, 'Updating translation from external source');
                 continue;
             }
         }
         if (!$this->interactive) {
             continue;
         }
         $this->reportProgress(" →Needs manual resolution", $page);
         $this->reportProgress("Source translation at {$changeDate}:", 'source');
         $this->reportProgress($this->color('blue', $translation), 'source');
         $this->reportProgress("Wiki translation at {$wikiDate}:", 'translation');
         $this->reportProgress($this->color('green', $current), 'translation');
         do {
             $this->reportProgress("Resolution: [S]kip [I]mport [C]onflict: ", 'foo');
             // @todo Find an elegant way to use Maintenance::readconsole().
             $action = fgets(STDIN);
             $action = strtoupper(trim($action));
             if ($action === 'S') {
                 break;
             }
             if ($action === 'I') {
                 $this->import($title, $translation, 'Updating translation from external source');
                 break;
             }
             if ($action === 'C') {
                 $this->import($title, TRANSLATE_FUZZY . $translation, 'Edit conflict between wiki and source');
                 break;
             }
         } while (true);
     }
 }
 protected function exportGroup(MessageGroup $group, $config)
 {
     $server = TTMServer::factory($config);
     $server->setLogger($this);
     $id = $group->getId();
     $sourceLanguage = $group->getSourceLanguage();
     $stats = MessageGroupStats::forGroup($id);
     $collection = $group->initCollection($sourceLanguage);
     $collection->filter('ignored');
     $collection->initMessages();
     $server->beginBatch();
     $inserts = array();
     foreach ($collection->keys() as $mkey => $title) {
         $handle = new MessageHandle($title);
         $inserts[] = array($handle, $sourceLanguage, $collection[$mkey]->definition());
     }
     while ($inserts !== array()) {
         $batch = array_splice($inserts, 0, $this->mBatchSize);
         $server->batchInsertDefinitions($batch);
     }
     $inserts = array();
     foreach ($stats as $targetLanguage => $numbers) {
         if ($targetLanguage === $sourceLanguage) {
             continue;
         }
         if ($numbers[MessageGroupStats::TRANSLATED] === 0) {
             continue;
         }
         $collection->resetForNewLanguage($targetLanguage);
         $collection->filter('ignored');
         $collection->filter('translated', false);
         $collection->loadTranslations();
         foreach ($collection->keys() as $mkey => $title) {
             $handle = new MessageHandle($title);
             $inserts[] = array($handle, $sourceLanguage, $collection[$mkey]->translation());
         }
         while (count($inserts) >= $this->mBatchSize) {
             $batch = array_splice($inserts, 0, $this->mBatchSize);
             $server->batchInsertTranslations($batch);
         }
     }
     while ($inserts !== array()) {
         $batch = array_splice($inserts, 0, $this->mBatchSize);
         $server->batchInsertTranslations($batch);
     }
     $server->endBatch();
 }