public function testConstruct() { $server = TTMServer::primary(); $this->assertEquals('FakeTTMServer', get_class($server), 'Fake server given when default server is disabled'); global $wgTranslateTranslationServices; $wgTranslateTranslationServices['TTMServer'] = array('database' => false, 'cutoff' => 0.75, 'type' => 'ttmserver', 'public' => false); $server = TTMServer::primary(); $this->assertEquals('DatabaseTTMServer', get_class($server), 'Real server given when default server is enabled'); unset($wgTranslateTranslationServices['TTMServer']); }
public function execute() { $params = $this->extractRequestParams(); $server = TTMServer::primary(); $suggestions = $server->query($params['sourcelanguage'], $params['targetlanguage'], $params['text']); $result = $this->getResult(); foreach ($suggestions as $sug) { $result->setContent($sug, $sug['target']); unset($sug['target']); $result->addValue($this->getModuleName(), null, $sug); } $result->setIndexedTagName_internal($this->getModuleName(), 'suggestion'); }
/** * Returns suggestions from a translation memory. * @param $serviceName * @param $config * @return string Html snippet which contains the suggestions. */ protected function getTTMServerBox($serviceName, $config) { $this->mustHaveDefinition(); $this->mustBeTranslation(); $source = $this->group->getSourceLanguage(); $code = $this->handle->getCode(); $definition = $this->getDefinition(); $suggestions = TTMServer::primary()->query($source, $code, $definition); if (count($suggestions) === 0) { return null; } foreach ($suggestions as $s) { $accuracy = wfMsgHtml('translate-edit-tmmatch', sprintf('%.2f', $s['quality'] * 100)); $legend = array($accuracy => array()); $sourceTitle = Title::newFromText($s['context']); $handle = new MessageHandle($sourceTitle); $targetTitle = Title::makeTitle($sourceTitle->getNamespace(), $handle->getKey() . "/{$code}"); if ($targetTitle) { $legend[$accuracy][] = self::ajaxEditLink($targetTitle, '•'); } // Show the source text in a tooltip $text = $this->suggestionField($s['target']); $params = array('class' => 'mw-sp-translate-edit-tmsug', 'title' => $s['source']); // Group identical suggestions together if (isset($sugFields[$s['target']])) { $sugFields[$s['target']][2] = array_merge_recursive($sugFields[$s['target']][2], $legend); } else { $sugFields[$s['target']] = array($text, $params, $legend); } } foreach ($sugFields as $field) { list($text, $params, $label) = $field; $legend = array(); foreach ($label as $acc => $links) { $legend[] = $acc . ' ' . implode(" ", $links); } $legend = implode(' | ', $legend); $boxes[] = Html::rawElement('div', $params, self::legend($legend) . $text . self::clear()) . "\n"; } // Limit to three best $boxes = array_slice($boxes, 0, 3); $result = implode("\n", $boxes); return $result; }
/** * Shovels the new translation into TTMServer. * Hook: Translate:newTranslation */ public static function updateTM(MessageHandle $handle, $revision, $text, User $user) { TTMServer::primary()->update($handle, $text); return true; }
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"); } }
public static function onChange(MessageHandle $handle, $text, $fuzzy) { if ($fuzzy) { $text = null; } TTMServer::primary()->update($handle, $text); }
public function execute($par) { global $wgLanguageCode; $this->setHeaders(); $this->checkPermissions(); $server = TTMServer::primary(); if (!$server instanceof SearchableTTMServer) { throw new ErrorPageError('tux-sst-nosolr-title', 'tux-sst-nosolr-body'); } $out = $this->getOutput(); $out->addModuleStyles('jquery.uls.grid'); $out->addModuleStyles('ext.translate.special.searchtranslations.styles'); $out->addModuleStyles('ext.translate.special.translate.styles'); $out->addModules('ext.translate.special.searchtranslations'); $out->addModules('ext.translate.special.searchtranslations.operatorsuggest'); TranslateUtils::addSpecialHelpLink($out, 'Help:Extension:Translate#searching'); $this->opts = $opts = new FormOptions(); $opts->add('query', ''); $opts->add('sourcelanguage', $wgLanguageCode); $opts->add('language', ''); $opts->add('group', ''); $opts->add('grouppath', ''); $opts->add('filter', ''); $opts->add('match', ''); $opts->add('case', ''); $opts->add('limit', $this->limit); $opts->add('offset', 0); $opts->fetchValuesFromRequest($this->getRequest()); $queryString = $opts->getValue('query'); if ($queryString === '') { $this->showEmptySearch(); return; } $params = $opts->getAllValues(); $filter = $opts->getValue('filter'); try { $translationSearch = new CrossLanguageTranslationSearchQuery($params, $server); if (in_array($filter, $translationSearch->getAvailableFilters())) { if ($opts->getValue('language') === '') { $params['language'] = $this->getLanguage()->getCode(); $opts->setValue('language', $params['language']); } $documents = $translationSearch->getDocuments(); $total = $translationSearch->getTotalHits(); $resultset = $translationSearch->getResultSet(); } else { $resultset = $server->search($queryString, $params, $this->hl); $documents = $server->getDocuments($resultset); $total = $server->getTotalHits($resultset); } } catch (TTMServerException $e) { error_log('Translation search server unavailable:' . $e->getMessage()); throw new ErrorPageError('tux-sst-solr-offline-title', 'tux-sst-solr-offline-body'); } // Part 1: facets $facets = $server->getFacets($resultset); $facetHtml = ''; if (count($facets['language']) > 0) { if ($filter !== '') { $facets['language'] = array_merge($facets['language'], array($opts->getValue('language') => $total)); } $facetHtml = Html::element('div', array('class' => 'row facet languages', 'data-facets' => FormatJson::encode($this->getLanguages($facets['language'])), 'data-language' => $opts->getValue('language')), $this->msg('tux-sst-facet-language')); } if (count($facets['group']) > 0) { $facetHtml .= Html::element('div', array('class' => 'row facet groups', 'data-facets' => FormatJson::encode($this->getGroups($facets['group'])), 'data-group' => $opts->getValue('group')), $this->msg('tux-sst-facet-group')); } // Part 2: results $resultsHtml = ''; $title = Title::newFromText($queryString); if ($title && !in_array($filter, $translationSearch->getAvailableFilters())) { $handle = new MessageHandle($title); $code = $handle->getCode(); $language = $opts->getValue('language'); if ($handle->isValid() && $code !== '' && $code !== $language) { $groupId = $handle->getGroup()->getId(); $helpers = new TranslationHelpers($title, $groupId); $document['wiki'] = wfWikiId(); $document['localid'] = $handle->getTitleForBase()->getPrefixedText(); $document['content'] = $helpers->getTranslation(); $document['language'] = $handle->getCode(); array_unshift($documents, $document); $total++; } } foreach ($documents as $document) { $text = $document['content']; $text = TranslateUtils::convertWhiteSpaceToHTML($text); list($pre, $post) = $this->hl; $text = str_replace($pre, '<strong class="tux-search-highlight">', $text); $text = str_replace($post, '</strong>', $text); $title = Title::newFromText($document['localid'] . '/' . $document['language']); if (!$title) { // Should not ever happen but who knows... continue; } $resultAttribs = array('class' => 'row tux-message', 'data-title' => $title->getPrefixedText(), 'data-language' => $document['language']); $handle = new MessageHandle($title); if ($handle->isValid()) { $groupId = $handle->getGroup()->getId(); $helpers = new TranslationHelpers($title, $groupId); $resultAttribs['data-definition'] = $helpers->getDefinition(); $resultAttribs['data-translation'] = $helpers->getTranslation(); $resultAttribs['data-group'] = $groupId; $uri = $title->getLocalUrl(array('action' => 'edit')); $link = Html::element('a', array('href' => $uri), $this->msg('tux-sst-edit')->text()); } else { $url = wfParseUrl($document['uri']); $domain = $url['host']; $link = Html::element('a', array('href' => $document['uri']), $this->msg('tux-sst-view-foreign', $domain)->text()); } $access = Html::rawElement('div', array('class' => 'row tux-edit tux-message-item'), $link); $titleText = $title->getPrefixedText(); $titleAttribs = array('class' => 'row tux-title', 'dir' => 'ltr'); $textAttribs = array('class' => 'row tux-text', 'lang' => wfBCP47($document['language']), 'dir' => Language::factory($document['language'])->getDir()); $resultsHtml = $resultsHtml . Html::openElement('div', $resultAttribs) . Html::rawElement('div', $textAttribs, $text) . Html::element('div', $titleAttribs, $titleText) . $access . Html::closeElement('div'); } $resultsHtml .= Html::rawElement('hr', array('class' => 'tux-pagination-line')); $prev = $next = ''; $offset = $this->opts->getValue('offset'); $params = $this->opts->getChangedValues(); if ($total - $offset > $this->limit) { $newParams = array('offset' => $offset + $this->limit) + $params; $attribs = array('class' => 'mw-ui-button pager-next', 'href' => $this->getPageTitle()->getLocalUrl($newParams)); $next = Html::element('a', $attribs, $this->msg('tux-sst-next')->text()); } if ($offset) { $newParams = array('offset' => max(0, $offset - $this->limit)) + $params; $attribs = array('class' => 'mw-ui-button pager-prev', 'href' => $this->getPageTitle()->getLocalUrl($newParams)); $prev = Html::element('a', $attribs, $this->msg('tux-sst-prev')->text()); } $resultsHtml .= Html::rawElement('div', array('class' => 'tux-pagination-links'), "{$prev} {$next}"); $search = $this->getSearchInput($queryString); $count = $this->msg('tux-sst-count')->numParams($total); $this->showSearch($search, $count, $facetHtml, $resultsHtml, $total); }