public function includeAssets() { TranslationHelpers::addModules($this->context->getOutput()); $pages = array(); foreach ($this->collection->getTitles() as $title) { $pages[] = $title->getPrefixedDBKey(); } $vars = array('trlKeys' => $pages); $this->context->getOutput()->addScript(Skin::makeVariablesScript($vars)); }
public function includeAssets() { global $wgOut; TranslationHelpers::addModules( $wgOut ); $pages = array(); foreach ( $this->collection->getTitles() as $title ) { $pages[] = $title->getPrefixedDBKey(); } $vars = array( 'trlKeys' => $pages ); $wgOut->addScript( Skin::makeVariablesScript( $vars ) ); $wgOut->addModules( 'ext.translate.messagetable' ); }
/** * Generates the html snippet for ajax edit. Echoes it to the output and * disabled all other output. */ public function execute() { global $wgServer, $wgScriptPath; $context = RequestContext::getMain(); $context->getOutput()->disable(); $data = $this->getEditInfo(); $helpers = new TranslationHelpers($this->getTitle(), ''); $id = "tm-target-{$helpers->dialogID()}"; $helpers->setTextareaId($id); if ($this->suggestions === 'checks') { echo $helpers->getBoxes($this->suggestions); return; } $handle = new MessageHandle($this->getTitle()); $groupId = MessageIndex::getPrimaryGroupId($handle); $translation = ''; if ($groupId) { $translation = $helpers->getTranslation(); } $targetLang = Language::factory($helpers->getTargetLanguage()); $textareaParams = array('name' => 'text', 'class' => 'mw-translate-edit-area', 'id' => $id, 'lang' => $targetLang->getCode(), 'dir' => $targetLang->getDir()); if (!$groupId || !$context->getUser()->isAllowed('translate')) { $textareaParams['readonly'] = 'readonly'; } $extraInputs = ''; Hooks::run('TranslateGetExtraInputs', array(&$translation, &$extraInputs)); $textarea = Html::element('textarea', $textareaParams, $translation); $hidden = array(); $hidden[] = Html::hidden('title', $this->getTitle()->getPrefixedDbKey()); if (isset($data['revisions'][0]['timestamp'])) { $hidden[] = Html::hidden('basetimestamp', $data['revisions'][0]['timestamp']); } $hidden[] = Html::hidden('starttimestamp', $data['starttimestamp']); if (isset($data['edittoken'])) { $hidden[] = Html::hidden('token', $data['edittoken']); } $hidden[] = Html::hidden('format', 'json'); $hidden[] = Html::hidden('action', 'edit'); $summary = Xml::inputLabel($context->msg('translate-js-summary')->text(), 'summary', 'summary', 40); $save = Xml::submitButton($context->msg('translate-js-save')->text(), array('class' => 'mw-translate-save')); $saveAndNext = Xml::submitButton($context->msg('translate-js-next')->text(), array('class' => 'mw-translate-next')); $skip = Html::element('input', array('class' => 'mw-translate-skip', 'type' => 'button', 'value' => $context->msg('translate-js-skip')->text())); if ($this->getTitle()->exists()) { $history = Html::element('input', array('class' => 'mw-translate-history', 'type' => 'button', 'value' => $context->msg('translate-js-history')->text())); } else { $history = ''; } $support = $this->getSupportButton($this->getTitle()); if ($context->getUser()->isAllowed('translate')) { $bottom = "{$summary}{$save}{$saveAndNext}{$skip}{$history}{$support}"; } else { $text = $context->msg('translate-edit-nopermission')->escaped(); $button = $this->getPermissionPageButton(); $bottom = "{$text} {$button}{$skip}{$history}{$support}"; } // Use the api to submit edits $formParams = array('action' => "{$wgServer}{$wgScriptPath}/api.php", 'method' => 'post'); $form = Html::rawElement('form', $formParams, implode("\n", $hidden) . "\n" . $helpers->getBoxes($this->suggestions) . "\n" . Html::rawElement('div', array('class' => 'mw-translate-inputs'), "{$textarea}\n{$extraInputs}") . "\n" . Html::rawElement('div', array('class' => 'mw-translate-bottom'), $bottom)); echo Html::rawElement('div', array('class' => 'mw-ajax-dialog'), $form); }
/** * Hook: ArticleContentOnDiff */ public static function displayOnDiff(DifferenceEngine $de, OutputPage $out) { $title = $de->getTitle(); $handle = new MessageHandle($title); if (!$handle->isValid()) { return true; } $th = new TranslationHelpers($title, false); $th->setEditMode(false); $de->loadNewText(); if ($de->mNewContent instanceof TextContent) { $th->setTranslation($de->mNewContent->getNativeData()); } else { // Screw you, not interested. return true; } TranslationHelpers::addModules($out); $boxes = array(); $boxes[] = $th->callBox('documentation', array($th, 'getDocumentationBox')); $boxes[] = $th->callBox('definition', array($th, 'getDefinitionBox')); $boxes[] = $th->callBox('translation', array($th, 'getTranslationDisplayBox')); $output = implode("\n", $boxes); $output = Html::rawElement('div', array('class' => 'mw-sp-translate-edit-fields'), $output); $out->addHtml($output); return true; }
/** * Add JavaScript assets * * @return void */ private static function includeAssets() { global $wgOut; TranslationHelpers::addModules($wgOut); $wgOut->addModules('ext.translate.messagetable'); }
protected function preinit() { $code = $this->options->getLanguage(); global $wgTranslateTranslationServices; $config = $wgTranslateTranslationServices['tmserver']; $server = $config['server']; $port = $config['port']; $timeout = $config['timeout-sync']; $sourceLanguage = $this->group->getSourceLanguage(); $this->collection = $this->group->initCollection( $code ); $this->collection->setInfile( $this->group->load( $code ) ); $this->collection->filter( 'ignored' ); $this->collection->filter( 'optional' ); $this->collection->filter( 'translated' ); $this->collection->filter( 'fuzzy' ); $this->collection->loadTranslations(); $start = time(); foreach ( $this->collection->getMessageKeys() as $key ) { // Allow up to 10 seconds to search for suggestions. if ( time() - $start > 10 || TranslationHelpers::checkTranslationServiceFailure( 'tmserver' ) ) { unset( $this->collection[$key] ); continue; } $def = rawurlencode( $this->collection[$key]->definition() ); $url = "$server:$port/tmserver/$sourceLanguage/$code/unit/$def"; $suggestions = Http::get( $url, $timeout ); if ( $suggestions !== false ) { $suggestions = FormatJson::decode( $suggestions, true ); foreach ( $suggestions as $s ) { // We have a good suggestion, do not filter. if ( $s['quality'] > 0.80 ) { continue 2; } } } else { TranslationHelpers::reportTranslationServiceFailure( 'tmserver' ); } unset( $this->collection[$key] ); } }
/** * Hook: ArticleContentOnDiff */ public static function displayOnDiff( DifferenceEngine $de, OutputPage $out ) { $title = $de->getTitle(); $handle = new MessageHandle( $title ); if ( !$handle->isValid() ) { return true; } $de->loadNewText(); $out->setRevisionId( $de->mNewRev->getId() ); $th = new TranslationHelpers( $title, /*group*/false ); $th->setEditMode( false ); $th->setTranslation( $de->mNewtext ); TranslationHelpers::addModules( $out ); $boxes = array(); $boxes[] = $th->getDocumentationBox(); $boxes[] = $th->getDefinitionBox(); $boxes[] = $th->getTranslationDisplayBox(); $output = Html::rawElement( 'div', array( 'class' => 'mw-sp-translate-edit-fields' ), implode( "\n\n", $boxes ) ); $out->addHtml( $output ); return false; }
/** * Add JavaScript assets */ private function includeAssets() { $out = $this->getOutput(); TranslationHelpers::addModules($out); $out->addModuleStyles('ext.translate.legacy'); }
/** * Generates the html snippet for ajax edit. Echoes it to the output and * disabled all other output. */ public function execute() { global $wgOut, $wgServer, $wgScriptPath, $wgUser, $wgRequest; $wgOut->disable(); $data = $this->getEditInfo(); $groupId = $wgRequest->getText( 'loadgroup', '' ); $helpers = new TranslationHelpers( $this->getTitle(), $groupId ); $id = "tm-target-{$helpers->dialogID()}"; $helpers->setTextareaId( $id ); if ( $this->suggestions === 'only' ) { echo $helpers->getBoxes( $this->suggestions ); return; } if ( $this->suggestions === 'checks' ) { echo $helpers->getBoxes( $this->suggestions ); return; } $translation = $helpers->getTranslation(); $targetLang = Language::factory( $helpers->getTargetLanguage() ); $textareaParams = array( 'name' => 'text', 'class' => 'mw-translate-edit-area', 'id' => $id, /* Target language might differ from interface language. Set * a suitable default direction */ 'lang' => $targetLang->getCode(), 'dir' => $targetLang->getDir(), ); if ( !$wgUser->isAllowed( 'translate' ) ) { $textareaParams['readonly'] = 'readonly'; } $textarea = Html::element( 'textarea', $textareaParams, $translation ); $hidden = array(); $hidden[] = Html::hidden( 'title', $this->getTitle()->getPrefixedDbKey() ); if ( isset( $data['revisions'][0]['timestamp'] ) ) { $hidden[] = Html::hidden( 'basetimestamp', $data['revisions'][0]['timestamp'] ); } $hidden[] = Html::hidden( 'starttimestamp', $data['starttimestamp'] ); $hidden[] = Html::hidden( 'token', $data['edittoken'] ); $hidden[] = Html::hidden( 'format', 'json' ); $hidden[] = Html::hidden( 'action', 'edit' ); $summary = Xml::inputLabel( wfMsg( 'translate-js-summary' ), 'summary', 'summary', 40 ); $save = Xml::submitButton( wfMsg( 'translate-js-save' ), array( 'class' => 'mw-translate-save' ) ); $saveAndNext = Xml::submitButton( wfMsg( 'translate-js-next' ), array( 'class' => 'mw-translate-next' ) ); $skip = Html::element( 'input', array( 'class' => 'mw-translate-skip', 'type' => 'button', 'value' => wfMsg( 'translate-js-skip' ) ) ); if ( $this->getTitle()->exists() ) { $history = Html::element( 'input', array( 'class' => 'mw-translate-history', 'type' => 'button', 'value' => wfMsg( 'translate-js-history' ) ) ); } else { $history = ''; } $support = $this->getSupportButton( $this->getTitle() ); if ( $wgUser->isAllowed( 'translate' ) ) { $bottom = "$summary$save$saveAndNext$skip$history$support"; } else { $text = wfMessage( 'translate-edit-nopermission' )->escaped(); $button = $this->getPermissionPageButton(); $bottom = "$text $button$skip$history$support"; } // Use the api to submit edits $formParams = array( 'action' => "{$wgServer}{$wgScriptPath}/api.php", 'method' => 'post', ); $form = Html::rawElement( 'form', $formParams, implode( "\n", $hidden ) . "\n" . $helpers->getBoxes( $this->suggestions ) . "\n" . "$textarea\n$bottom" ); echo Html::rawElement( 'div', array( 'class' => 'mw-ajax-dialog' ), $form ); }
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); }
public function formatGroupInformation($blocks, $level = 2) { global $wgLang; if (is_array($blocks)) { foreach ($blocks as $i => $block) { if (!is_array($block) && MessageGroups::getPriority($block) === 'discouraged') { unset($blocks[$i]); } } $block = array_shift($blocks); } else { $block = $blocks; if (MessageGroups::getPriority($block) === 'discouraged') { return ''; } } $id = $block->getId(); $title = $this->getTitle(); $code = $this->options['language']; $queryParams = array('group' => $id, 'language' => $code); $linker = class_exists('DummyLinker') ? new DummyLinker() : new Linker(); $label = $linker->link($title, htmlspecialchars($block->getLabel()), array(), $queryParams); $desc = $this->getGroupDescription($block); $hasSubblocks = is_array($blocks) && count($blocks); $subid = Sanitizer::escapeId("mw-subgroup-{$id}"); if ($hasSubblocks) { $msg = wfMessage('translate-showsub', $wgLang->formatNum(count($blocks)))->text(); $target = TranslationHelpers::jQueryPathId($subid); $desc .= Html::element('a', array('onclick' => "jQuery({$target}).toggle()", 'class' => 'mw-sp-showmore'), $msg); } $out = "\n<tr><td>{$label}</td>\n<td>{$desc}</td></tr>\n"; if ($hasSubblocks) { $out .= "<tr><td></td><td>\n"; $tableParams = array('id' => $subid, 'style' => 'display:none;', 'class' => "mw-sp-translate-subgroup depth-{$level}"); $out .= Html::openElement('table', $tableParams); foreach ($blocks as $subBlock) { $out .= $this->formatGroupInformation($subBlock, $level + 1); } $out .= '</table></td></tr>'; } return $out; }