public function testGetNamespaceString()
 {
     $conf = $this->groupConfiguration;
     $conf['BASIC']['namespace'] = 'image';
     $this->group = MessageGroupBase::factory($conf);
     $this->assertEquals(NS_IMAGE, $this->group->getNamespace(), "should parse string namespace name.");
 }
Exemple #2
0
 /**
  * Returns the message groups this message group is part of.
  * @since 2011-12-25
  * @return array
  */
 public static function getParentGroups(MessageGroup $group)
 {
     // Take the first message, get a handle for it and check
     // if that message belongs to other groups. Those are the
     // parent aggregate groups. Ideally we loop over all keys,
     // but this should be enough.
     $keys = array_keys($group->getDefinitions());
     $title = Title::makeTitle($group->getNamespace(), $keys[0]);
     $handle = new MessageHandle($title);
     $ids = $handle->getGroupIds();
     foreach ($ids as $index => $id) {
         if ($id === $group->getId()) {
             unset($ids[$index]);
         }
     }
     return $ids;
 }
 /**
  * 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);
     }
 }
 /**
  * @param MessageGroup $group
  * @param string $code
  * @param string $type
  * @param array $params
  * @param int $limit
  * @return string HTML
  */
 protected function formatChange(MessageGroup $group, $code, $type, $params, &$limit)
 {
     $key = $params['key'];
     $title = Title::makeTitleSafe($group->getNamespace(), "{$key}/{$code}");
     $id = self::changeId($group->getId(), $code, $type, $key);
     if ($title && $title->exists() && $type === 'addition') {
         // The message has for some reason dropped out from cache
         // or perhaps it is being reused. In any case treat it
         // as a change for display, so the admin can see if
         // action is needed and let the message be processed.
         // Otherwise it will end up in the postponed category
         // forever and will prevent rebuilding the cache, which
         // leads to many other annoying problems.
         $type = 'change';
     } elseif ($title && !$title->exists() && ($type === 'deletion' || $type === 'change')) {
         return '';
     }
     $text = '';
     if ($type === 'deletion') {
         $wiki = ContentHandler::getContentText(Revision::newFromTitle($title)->getContent());
         $oldContent = ContentHandler::makeContent($wiki, $title);
         $newContent = ContentHandler::makeContent('', $title);
         $this->diff->setContent($oldContent, $newContent);
         $text = $this->diff->getDiff(Linker::link($title), '');
     } elseif ($type === 'addition') {
         $oldContent = ContentHandler::makeContent('', $title);
         $newContent = ContentHandler::makeContent($params['content'], $title);
         $this->diff->setContent($oldContent, $newContent);
         $text = $this->diff->getDiff('', Linker::link($title));
     } elseif ($type === 'change') {
         $wiki = ContentHandler::getContentText(Revision::newFromTitle($title)->getContent());
         $handle = new MessageHandle($title);
         if ($handle->isFuzzy()) {
             $wiki = '!!FUZZY!!' . str_replace(TRANSLATE_FUZZY, '', $wiki);
         }
         $label = $this->msg('translate-manage-action-ignore')->text();
         $actions = Xml::checkLabel($label, "i/{$id}", "i/{$id}");
         $limit--;
         if ($group->getSourceLanguage() === $code) {
             $label = $this->msg('translate-manage-action-fuzzy')->text();
             $actions .= ' ' . Xml::checkLabel($label, "f/{$id}", "f/{$id}", true);
             $limit--;
         }
         $oldContent = ContentHandler::makeContent($wiki, $title);
         $newContent = ContentHandler::makeContent($params['content'], $title);
         $this->diff->setContent($oldContent, $newContent);
         $text .= $this->diff->getDiff(Linker::link($title), $actions);
     }
     $hidden = Html::hidden($id, 1);
     $limit--;
     $text .= $hidden;
     $classes = "mw-translate-smg-change smg-change-{$type}";
     if ($limit < 0) {
         // Don't add if one of the fields might get dropped of at submission
         return '';
     }
     return Html::rawElement('div', array('class' => $classes), $text);
 }
 /**
  * Given a group, message key and language code, creates a title for the
  * translation page.
  *
  * @param MessageGroup $group
  * @param string $key Message key
  * @param string $code Language code
  * @return Title
  */
 public static function makeTranslationTitle($group, $key, $code)
 {
     $ns = $group->getNamespace();
     return Title::makeTitleSafe($ns, "{$key}/{$code}");
 }