Translate extension for MediaWiki
 
Loading...
Searching...
No Matches
CrossLanguageTranslationSearchQuery.php
1<?php
2
6
13 protected $server;
15 protected $params;
17 protected $resultset;
19 protected $total = 0;
20 protected $hl = [ '', '' ];
21
22 public function __construct( array $params, SearchableTtmServer $server ) {
23 $this->params = $params;
24 $this->server = $server;
25 }
26
27 public function getDocuments() {
28 $documents = [];
29 $offset = $this->params['offset'];
30 $limit = $this->params['limit'];
31
32 $options = $this->params;
33 $options['language'] = $this->params['sourcelanguage'];
34 // Use a bigger limit that what was requested, since we are likely to throw away many
35 // results in the local filtering step at extractMessages
36 $options['limit'] = $limit * 10;
37 // TODO: the real offset should be communicated to the frontend. It currently assumes
38 // next offset is current offset + limit and previous one is current offset - limit.
39 // It might be difficult to fix scrolling results backwards. For now we handle offset
40 // locally.
41 $options['offset'] = 0;
42
43 // @phan-suppress-next-line PhanUndeclaredMethod
44 $search = $this->server->createSearch( $this->params['query'], $options, $this->hl );
45 $scroll = $search->scroll( '5s' );
46
47 // Used for aggregations. Only the first scroll response has them.
48 $this->resultset = null;
49
50 foreach ( $scroll as $resultSet ) {
51 if ( !$this->resultset ) {
52 $this->resultset = $resultSet;
53 $this->total = $resultSet->getTotalHits();
54 }
55
56 $results = $this->extractMessages( $resultSet->getDocuments() );
57 $documents = array_merge( $documents, $results );
58
59 $count = count( $documents );
60
61 if ( $count >= $offset + $limit ) {
62 break;
63 }
64 }
65
66 if ( !$this->resultset ) {
67 // No hits for documents, just set the result set.
68 $this->resultset = $scroll->current();
69 $this->total = $scroll->current()->getTotalHits();
70 }
71
72 // clear was introduced in Elastica 5.3.1, but Elastica extension uses 5.3.0
73 if ( is_callable( [ $scroll, 'clear' ] ) ) {
74 $scroll->clear();
75 }
76 $documents = array_slice( $documents, $offset, $limit );
77
78 return $documents;
79 }
80
89 protected function extractMessages( $documents ) {
90 $messages = $ret = [];
91
92 $language = $this->params['language'];
93 foreach ( $documents as $document ) {
94 $data = $document->getData();
95
96 // @phan-suppress-next-line PhanUndeclaredMethod
97 if ( !$this->server->isLocalSuggestion( $data ) ) {
98 continue;
99 }
100
101 $title = Title::newFromText( $data['localid'] );
102 if ( !$title ) {
103 continue;
104 }
105
106 $handle = new MessageHandle( $title );
107 if ( !$handle->isValid() ) {
108 continue;
109 }
110
111 $key = $title->getNamespace() . ':' . $title->getDBkey();
112 $messages[$key] = $data['content'];
113 }
114
115 $definitions = new MessageDefinitions( $messages );
116 $collection = MessageCollection::newFromDefinitions( $definitions, $language );
117
118 $filter = $this->params['filter'];
119 if ( $filter === 'untranslated' ) {
120 $collection->filter( 'hastranslation', true );
121 } elseif ( in_array( $filter, $this->getAvailableFilters() ) ) {
122 $collection->filter( $filter, false );
123 }
124
125 if ( $filter === 'translated' || $filter === 'fuzzy' ) {
126 $collection->loadTranslations();
127 }
128
129 foreach ( $collection->keys() as $mkey => $titleValue ) {
130 $title = Title::newFromLinkTarget( $titleValue );
131
132 $result = [];
133 $result['content'] = $messages[$mkey];
134 if ( $filter === 'translated' || $filter === 'fuzzy' ) {
135 $result['content'] = $collection[$mkey]->translation();
136 }
137 $handle = new MessageHandle( $title );
138 $result['localid'] = $handle->getTitleForBase()->getPrefixedText();
139 $result['language'] = $language;
140
141 $ret[] = $result;
142 }
143
144 return $ret;
145 }
146
148 public function getAvailableFilters() {
149 return [
150 'translated',
151 'fuzzy',
152 'untranslated'
153 ];
154 }
155
156 public function getTotalHits() {
157 return $this->total;
158 }
159
160 public function getResultSet() {
161 return $this->resultset;
162 }
163}
extractMessages( $documents)
Extract messages from the documents and build message definitions.
This file contains the class for core message collections implementation.
Wrapper for message definitions, just to beauty the code.
Class for pointing to messages, like Title class is for titles.
Interface for TTMServer that can act as backend for translation search.