summaryrefslogtreecommitdiff
path: root/www/wiki/extensions/Translate/specials/SpecialSearchTranslations.php
diff options
context:
space:
mode:
Diffstat (limited to 'www/wiki/extensions/Translate/specials/SpecialSearchTranslations.php')
-rw-r--r--www/wiki/extensions/Translate/specials/SpecialSearchTranslations.php208
1 files changed, 126 insertions, 82 deletions
diff --git a/www/wiki/extensions/Translate/specials/SpecialSearchTranslations.php b/www/wiki/extensions/Translate/specials/SpecialSearchTranslations.php
index 133d4b80..68ac1b2e 100644
--- a/www/wiki/extensions/Translate/specials/SpecialSearchTranslations.php
+++ b/www/wiki/extensions/Translate/specials/SpecialSearchTranslations.php
@@ -4,7 +4,7 @@
*
* @file
* @author Niklas Laxström
- * @license GPL-2.0+
+ * @license GPL-2.0-or-later
*/
/**
@@ -23,7 +23,7 @@ class SpecialSearchTranslations extends SpecialPage {
* don't contain any chars that are escaped in html.
* @var array
*/
- protected $hl = array();
+ protected $hl = [];
/**
* How many search results to display per page
@@ -33,10 +33,10 @@ class SpecialSearchTranslations extends SpecialPage {
public function __construct() {
parent::__construct( 'SearchTranslations' );
- $this->hl = array(
+ $this->hl = [
TranslateUtils::getPlaceholder(),
TranslateUtils::getPlaceholder(),
- );
+ ];
}
public function setHeaders() {
@@ -64,9 +64,11 @@ class SpecialSearchTranslations extends SpecialPage {
$out->addModuleStyles( 'jquery.uls.grid' );
$out->addModuleStyles( 'ext.translate.special.searchtranslations.styles' );
$out->addModuleStyles( 'ext.translate.special.translate.styles' );
+ $out->addModuleStyles( [ 'mediawiki.ui.button', 'mediawiki.ui.input', 'mediawiki.ui.checkbox' ] );
$out->addModules( 'ext.translate.special.searchtranslations' );
$out->addModules( 'ext.translate.special.searchtranslations.operatorsuggest' );
$out->addHelpLink( 'Help:Extension:Translate#searching' );
+ $out->addJsConfigVars( 'wgTranslateLanguages', TranslateUtils::getLanguageNames( null ) );
$this->opts = $opts = new FormOptions();
$opts->add( 'query', '' );
@@ -86,10 +88,11 @@ class SpecialSearchTranslations extends SpecialPage {
if ( $queryString === '' ) {
$this->showEmptySearch();
-
return;
}
+ $search = $this->getSearchInput( $queryString );
+
$options = $params = $opts->getAllValues();
$filter = $opts->getValue( 'filter' );
try {
@@ -98,6 +101,11 @@ class SpecialSearchTranslations extends SpecialPage {
}
$translationSearch = new CrossLanguageTranslationSearchQuery( $options, $server );
if ( in_array( $filter, $translationSearch->getAvailableFilters() ) ) {
+ if ( $options['language'] === $options['sourcelanguage'] ) {
+ $this->showSearchError( $search, $this->msg( 'tux-sst-error-language' ) );
+ return;
+ }
+
$opts->setValue( 'language', $options['language'] );
$documents = $translationSearch->getDocuments();
$total = $translationSearch->getTotalHits();
@@ -108,7 +116,15 @@ class SpecialSearchTranslations extends SpecialPage {
$total = $server->getTotalHits( $resultset );
}
} catch ( TTMServerException $e ) {
- error_log( 'Translation search server unavailable:' . $e->getMessage() );
+ $message = $e->getMessage();
+ // Known exceptions
+ if ( preg_match( '/^Result window is too large/', $message ) ) {
+ $this->showSearchError( $search, $this->msg( 'tux-sst-error-offset' ) );
+ return;
+ }
+
+ // Other exceptions
+ error_log( 'Translation search server unavailable: ' . $e->getMessage() );
throw new ErrorPageError( 'tux-sst-solr-offline-title', 'tux-sst-solr-offline-body' );
}
@@ -116,28 +132,28 @@ class SpecialSearchTranslations extends SpecialPage {
$facets = $server->getFacets( $resultset );
$facetHtml = '';
- if ( count( $facets['language'] ) > 0 ) {
+ if ( $facets['language'] !== [] ) {
if ( $filter !== '' ) {
$facets['language'] = array_merge(
$facets['language'],
- array( $opts->getValue( 'language' ) => $total )
+ [ $opts->getValue( 'language' ) => $total ]
);
}
$facetHtml = Html::element( 'div',
- array( 'class' => 'row facet languages',
+ [ 'class' => 'row facet languages',
'data-facets' => FormatJson::encode( $this->getLanguages( $facets['language'] ) ),
'data-language' => $opts->getValue( 'language' ),
- ),
- $this->msg( 'tux-sst-facet-language' )
+ ],
+ $this->msg( 'tux-sst-facet-language' )->text()
);
}
- if ( count( $facets['group'] ) > 0 ) {
+ if ( $facets['group'] !== [] ) {
$facetHtml .= Html::element( 'div',
- array( 'class' => 'row facet groups',
+ [ 'class' => 'row facet groups',
'data-facets' => FormatJson::encode( $this->getGroups( $facets['group'] ) ),
- 'data-group' => $opts->getValue( 'group' ) ),
- $this->msg( 'tux-sst-facet-group' )
+ 'data-group' => $opts->getValue( 'group' ) ],
+ $this->msg( 'tux-sst-facet-group' )->text()
);
}
@@ -150,11 +166,16 @@ class SpecialSearchTranslations extends SpecialPage {
$code = $handle->getCode();
$language = $opts->getValue( 'language' );
if ( $code !== '' && $code !== $language && $handle->isValid() ) {
- $groupId = $handle->getGroup()->getId();
- $helpers = new TranslationHelpers( $title, $groupId );
+ $dataProvider = new TranslationAidDataProvider( $handle );
+ $aid = new CurrentTranslationAid(
+ $handle->getGroup(),
+ $handle,
+ $this->getContext(),
+ $dataProvider
+ );
$document['wiki'] = wfWikiID();
$document['localid'] = $handle->getTitleForBase()->getPrefixedText();
- $document['content'] = $helpers->getTranslation();
+ $document['content'] = $aid->getData()['value'];
$document['language'] = $handle->getCode();
array_unshift( $documents, $document );
$total++;
@@ -175,25 +196,19 @@ class SpecialSearchTranslations extends SpecialPage {
continue;
}
- $resultAttribs = array(
+ $resultAttribs = [
'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' ) );
+ $uri = TranslateUtils::getEditorUrl( $handle );
$link = Html::element(
'a',
- array( 'href' => $uri ),
+ [ 'href' => $uri ],
$this->msg( 'tux-sst-edit' )->text()
);
} else {
@@ -201,29 +216,29 @@ class SpecialSearchTranslations extends SpecialPage {
$domain = $url['host'];
$link = Html::element(
'a',
- array( 'href' => $document['uri'] ),
+ [ 'href' => $document['uri'] ],
$this->msg( 'tux-sst-view-foreign', $domain )->text()
);
}
$access = Html::rawElement(
'div',
- array( 'class' => 'row tux-edit tux-message-item' ),
+ [ 'class' => 'row tux-edit tux-message-item' ],
$link
);
$titleText = $title->getPrefixedText();
- $titleAttribs = array(
+ $titleAttribs = [
'class' => 'row tux-title',
'dir' => 'ltr',
- );
+ ];
$language = Language::factory( $document['language'] );
- $textAttribs = array(
+ $textAttribs = [
'class' => 'row tux-text',
'lang' => $language->getHtmlCode(),
'dir' => $language->getDir(),
- );
+ ];
$resultsHtml = $resultsHtml
. Html::openElement( 'div', $resultAttribs )
@@ -233,41 +248,40 @@ class SpecialSearchTranslations extends SpecialPage {
. Html::closeElement( 'div' );
}
- $resultsHtml .= Html::rawElement( 'hr', array( 'class' => 'tux-pagination-line' ) );
+ $resultsHtml .= Html::rawElement( 'hr', [ '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(
+ $newParams = [ 'offset' => $offset + $this->limit ] + $params;
+ $attribs = [
'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(
+ $newParams = [ 'offset' => max( 0, $offset - $this->limit ) ] + $params;
+ $attribs = [
'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' ),
+ $resultsHtml .= Html::rawElement( 'div', [ '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 );
}
protected function getLanguages( array $facet ) {
- $output = array();
+ $output = [];
$nondefaults = $this->opts->getChangedValues();
$selected = $this->opts->getValue( 'language' );
@@ -289,10 +303,10 @@ class SpecialSearchTranslations extends SpecialPage {
$url = $this->getPageTitle()->getLocalURL( $nondefaults );
$value = $this->getLanguage()->formatNum( $value );
- $output[$key] = array(
+ $output[$key] = [
'count' => $value,
'url' => $url
- );
+ ];
}
return $output;
@@ -304,7 +318,7 @@ class SpecialSearchTranslations extends SpecialPage {
}
protected function makeGroupFacetRows( array $groups, $counts, $level = 0, $pathString = '' ) {
- $output = array();
+ $output = [];
$nondefaults = $this->opts->getChangedValues();
$selected = $this->opts->getValue( 'group' );
@@ -316,7 +330,7 @@ class SpecialSearchTranslations extends SpecialPage {
if ( is_array( $mixed ) ) {
$group = array_shift( $subgroups );
} else {
- $subgroups = array();
+ $subgroups = [];
}
$id = $group->getId();
@@ -333,13 +347,13 @@ class SpecialSearchTranslations extends SpecialPage {
$nondefaults['grouppath'] = $pathString . $id;
}
- $value = isset( $counts[$id] ) ? $counts[$id] : 0;
+ $value = $counts[$id] ?? 0;
- $output[$id] = array(
+ $output[$id] = [
'id' => $id,
'count' => $value,
'label' => $group->getLabel(),
- );
+ ];
if ( isset( $path[$level] ) && $path[$level] === $id ) {
$output[$id]['groups'] = $this->makeGroupFacetRows(
@@ -376,14 +390,14 @@ HTML
$size = 100;
if ( $total > $size && $match !== 'all' && $hasSpace ) {
$params = $this->opts->getChangedValues();
- $params = array( 'match' => 'all' ) + $params;
+ $params = [ 'match' => 'all' ] + $params;
$linkText = $this->msg( 'tux-sst-link-all-match' )->text();
$link = $this->getPageTitle()->getFullURL( $params );
$link = "<span class='plainlinks'>[$link $linkText]</span>";
$this->getOutput()->wrapWikiMsg(
'<div class="successbox">$1</div>',
- array( 'tux-sst-match-message', $link )
+ [ 'tux-sst-match-message', $link ]
);
}
@@ -409,61 +423,85 @@ HTML
);
}
- // Build ellipsis to select options
+ protected function showSearchError( $search, Message $message ) {
+ $messageSelector = $this->messageSelector();
+ $this->getOutput()->addHTML( <<<HTML
+<div class="grid tux-searchpage">
+ <div class="row tux-searchboxform">
+ <div class="tux-search-tabs offset-by-three">$messageSelector</div>
+ <div class="row tux-search-options">
+ <div class="offset-by-three nine columns tux-search-inputs">
+ <div class="row searchinput">$search</div>
+ <div class="row errorbox">{$message->escaped()}</div>
+ </div>
+ </div>
+ </div>
+</div>
+HTML
+ );
+ }
+
+ /**
+ * Build ellipsis to select options
+ * @param string $key
+ * @param string $value
+ * @return string
+ */
protected function ellipsisSelector( $key, $value ) {
$nondefaults = $this->opts->getChangedValues();
- $taskParams = array( 'filter' => $value ) + $nondefaults;
+ $taskParams = [ 'filter' => $value ] + $nondefaults;
ksort( $taskParams );
$href = $this->getPageTitle()->getLocalURL( $taskParams );
$link = Html::element( 'a',
- array( 'href' => $href ),
+ [ 'href' => $href ],
// Messages for grepping:
// tux-sst-ellipsis-untranslated
// tux-sst-ellipsis-outdated
$this->msg( 'tux-sst-ellipsis-' . $key )->text()
);
- $container = Html::rawElement( 'li', array(
+ $container = Html::rawElement( 'li', [
'class' => 'column',
'data-filter' => $value,
'data-title' => $key,
- ), $link );
+ ], $link );
return $container;
}
- /*
+ /**
* Design the tabs
+ * @return string
*/
protected function messageSelector() {
$nondefaults = $this->opts->getChangedValues();
- $output = Html::openElement( 'div', array( 'class' => 'row tux-messagetable-header' ) );
- $output .= Html::openElement( 'div', array( 'class' => 'nine columns' ) );
- $output .= Html::openElement( 'ul', array( 'class' => 'row tux-message-selector' ) );
- $tabs = array(
+ $output = Html::openElement( 'div', [ 'class' => 'row tux-messagetable-header' ] );
+ $output .= Html::openElement( 'div', [ 'class' => 'nine columns' ] );
+ $output .= Html::openElement( 'ul', [ 'class' => 'row tux-message-selector' ] );
+ $tabs = [
'default' => '',
'translated' => 'translated',
'untranslated' => 'untranslated'
- );
+ ];
- $ellipsisOptions = array(
+ $ellipsisOptions = [
'outdated' => 'fuzzy'
- );
+ ];
$selected = $this->opts->getValue( 'filter' );
$keys = array_keys( $tabs );
if ( in_array( $selected, array_values( $ellipsisOptions ) ) ) {
$key = $keys[count( $keys ) - 1];
- $ellipsisOptions = array( $key => $tabs[$key] );
+ $ellipsisOptions = [ $key => $tabs[$key] ];
// Remove the last tab
unset( $tabs[$key] );
- $tabs = array_merge( $tabs, array( 'outdated' => $selected ) );
+ $tabs = array_merge( $tabs, [ 'outdated' => $selected ] );
} elseif ( !in_array( $selected, array_values( $tabs ) ) ) {
$selected = '';
}
- $container = Html::openElement( 'ul', array( 'class' => 'column tux-message-selector' ) );
+ $container = Html::openElement( 'ul', [ 'class' => 'column tux-message-selector' ] );
foreach ( $ellipsisOptions as $optKey => $optValue ) {
$container .= $this->ellipsisSelector( $optKey, $optValue );
}
@@ -477,19 +515,19 @@ HTML
// tux-sst-untranslated
// tux-sst-outdated
$tabClass = "tux-sst-$tab";
- $taskParams = array( 'filter' => $filter ) + $nondefaults;
+ $taskParams = [ 'filter' => $filter ] + $nondefaults;
ksort( $taskParams );
$href = $this->getPageTitle()->getLocalURL( $taskParams );
if ( $tab === 'default' ) {
$link = Html::element(
'a',
- array( 'href' => $href ),
+ [ 'href' => $href ],
$this->msg( $tabClass )->text()
);
} else {
$link = Html::element(
'a',
- array( 'href' => $href ),
+ [ 'href' => $href ],
$this->msg( $tabClass, $sourcelanguage )->text()
);
}
@@ -497,15 +535,15 @@ HTML
if ( $selected === $filter ) {
$tabClass = $tabClass . ' selected';
}
- $output .= Html::rawElement( 'li', array(
- 'class' => array( 'column', $tabClass ),
+ $output .= Html::rawElement( 'li', [
+ 'class' => [ 'column', $tabClass ],
'data-filter' => $filter,
'data-title' => $tab,
- ), $link );
+ ], $link );
}
// More column
- $output .= Html::openElement( 'li', array( 'class' => 'column more' ) ) .
+ $output .= Html::openElement( 'li', [ 'class' => 'column more' ] ) .
'...' .
$container .
Html::closeElement( 'li' );
@@ -518,15 +556,18 @@ HTML
}
protected function getSearchInput( $query ) {
- $attribs = array(
+ $attribs = [
'placeholder' => $this->msg( 'tux-sst-search-ph' ),
- 'class' => 'searchinputbox',
+ 'class' => 'searchinputbox mw-ui-input',
'dir' => $this->getLanguage()->getDir(),
- );
+ ];
$title = Html::hidden( 'title', $this->getPageTitle()->getPrefixedText() );
$input = Xml::input( 'query', false, $query, $attribs );
- $submit = Xml::submitButton( $this->msg( 'tux-sst-search' ), array( 'class' => 'button' ) );
+ $submit = Xml::submitButton(
+ $this->msg( 'tux-sst-search' ),
+ [ 'class' => 'mw-ui-button' ]
+ );
$nondefaults = $this->opts->getChangedValues();
$checkLabel = Xml::checkLabel(
@@ -535,14 +576,17 @@ HTML
'tux-case-sensitive',
isset( $nondefaults['case'] )
);
- $checkLabel = Html::openElement( 'div', array( 'class' => 'tux-search-operators' ) ) .
+ $checkLabel = Html::openElement(
+ 'div',
+ [ 'class' => 'tux-search-operators mw-ui-checkbox' ]
+ ) .
$checkLabel .
Html::closeElement( 'div' );
$lang = $this->getRequest()->getVal( 'language' );
$language = is_null( $lang ) ? '' : Html::hidden( 'language', $lang );
- $form = Html::rawElement( 'form', array( 'action' => wfScript(), 'name' => 'searchform' ),
+ $form = Html::rawElement( 'form', [ 'action' => wfScript(), 'name' => 'searchform' ],
$title . $input . $submit . $checkLabel . $language
);