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