Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 79 |
|
0.00% |
0 / 15 |
CRAP | |
0.00% |
0 / 1 |
MathEngineRest | |
0.00% |
0 / 79 |
|
0.00% |
0 / 15 |
702 | |
0.00% |
0 / 1 |
doPost | |
0.00% |
0 / 18 |
|
0.00% |
0 / 1 |
12 | |||
getBackendUrl | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
setBackendUrl | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getQuery | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
__construct | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
6 | |||
getSize | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getResultSet | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getRelevanceMap | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
setQuery | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
postQuery | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
6 | |||
processMathResults | n/a |
0 / 0 |
n/a |
0 / 0 |
0 | |||||
getPostData | |
0.00% |
0 / 11 |
|
0.00% |
0 / 1 |
12 | |||
processResults | |
0.00% |
0 / 28 |
|
0.00% |
0 / 1 |
42 | |||
getType | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
setType | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
resetResults | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | |
3 | use MediaWiki\Logger\LoggerFactory; |
4 | use MediaWiki\MediaWikiServices; |
5 | |
6 | /** |
7 | * MediaWiki MathSearch extension |
8 | * |
9 | * (c) 2014 Moritz Schubotz |
10 | * GPLv2 license; info in main package. |
11 | * |
12 | * @file |
13 | * @ingroup extensions |
14 | */ |
15 | abstract class MathEngineRest { |
16 | /** @var MathQueryObject the query to be answered */ |
17 | protected $query; |
18 | /** @var string */ |
19 | protected $type = "mws"; |
20 | /** @var int|false */ |
21 | protected $size = false; |
22 | /** @var array<int,array<string,array[]>> */ |
23 | protected $resultSet = []; |
24 | /** @var int[] */ |
25 | protected $relevanceMap = []; |
26 | /** @var string */ |
27 | protected $backendUrl = "http://localhost:9090"; |
28 | |
29 | protected static function doPost( $url, $postData ) { |
30 | $res = MediaWikiServices::getInstance()->getHttpRequestFactory() |
31 | ->post( $url, [ "postData" => $postData, "timeout" => 60 ] ); |
32 | if ( $res === false ) { |
33 | if ( function_exists( 'curl_init' ) ) { |
34 | $handle = curl_init(); |
35 | $options = [ |
36 | CURLOPT_URL => $url, |
37 | CURLOPT_CUSTOMREQUEST => 'POST', // GET POST PUT PATCH DELETE HEAD OPTIONS |
38 | ]; |
39 | // TODO: Figure out how not to write the error in a message and not in top of the output page |
40 | curl_setopt_array( $handle, $options ); |
41 | $details = curl_exec( $handle ); |
42 | } else { |
43 | $details = "curl is not installed."; |
44 | } |
45 | LoggerFactory::getInstance( |
46 | 'MathSearch' |
47 | )->error( 'Nothing retrieved from $url. Check if server is running. Error:' . |
48 | var_export( $details, true ) ); |
49 | return false; |
50 | } else { |
51 | return $res; |
52 | } |
53 | } |
54 | |
55 | /** |
56 | * @return string |
57 | */ |
58 | public function getBackendUrl() { |
59 | return $this->backendUrl; |
60 | } |
61 | |
62 | /** |
63 | * @param string $backendUrl |
64 | */ |
65 | public function setBackendUrl( $backendUrl ) { |
66 | $this->backendUrl = $backendUrl; |
67 | } |
68 | |
69 | /** |
70 | * @return MathQueryObject |
71 | */ |
72 | public function getQuery() { |
73 | return $this->query; |
74 | } |
75 | |
76 | /** |
77 | * @param MathQueryObject|null $query |
78 | * @param bool|string $url |
79 | */ |
80 | function __construct( $query = null, $url = false ) { |
81 | $this->query = $query; |
82 | if ( $url ) { |
83 | $this->setBackendUrl( $url ); |
84 | } |
85 | } |
86 | |
87 | /** |
88 | * @return int|false |
89 | */ |
90 | public function getSize() { |
91 | return $this->size; |
92 | } |
93 | |
94 | /** |
95 | * @return array<int,array<string,array[]>> |
96 | */ |
97 | public function getResultSet() { |
98 | return $this->resultSet; |
99 | } |
100 | |
101 | /** |
102 | * @return int[] |
103 | */ |
104 | public function getRelevanceMap() { |
105 | return $this->relevanceMap; |
106 | } |
107 | |
108 | /** |
109 | * @param MathQueryObject $query |
110 | * @return $this |
111 | */ |
112 | public function setQuery( MathQueryObject $query ) { |
113 | $this->query = $query; |
114 | return $this; |
115 | } |
116 | |
117 | /** |
118 | * Posts the query to mwsd and evaluates the result data |
119 | * @return bool |
120 | */ |
121 | function postQuery() { |
122 | $numProcess = 30000; |
123 | $postData = $this->getPostData( $numProcess ); |
124 | $res = self::doPost( $this->backendUrl, $postData ); |
125 | if ( $res === false ) { |
126 | return false; |
127 | } else { |
128 | return $this->processResults( $res, $numProcess ); |
129 | } |
130 | } |
131 | |
132 | /** |
133 | * @param SimpleXMLElement $xmlRoot |
134 | */ |
135 | abstract function processMathResults( $xmlRoot ); |
136 | |
137 | /** |
138 | * @param int $numProcess |
139 | * @return string |
140 | */ |
141 | protected function getPostData( $numProcess ) { |
142 | global $wgMathDebug; |
143 | if ( $this->query->getXQuery() ) { |
144 | return $this->query->getXQuery(); |
145 | } else { |
146 | $tmp = |
147 | str_replace( "answsize=\"30\"", "answsize=\"$numProcess\" totalreq=\"yes\"", |
148 | $this->getQuery()->getCQuery() ); |
149 | $postData = str_replace( "m:", "", $tmp ); |
150 | if ( $wgMathDebug ) { |
151 | LoggerFactory::getInstance( 'MathSearch' )->debug( 'MWS query:' . $postData ); |
152 | return $postData; |
153 | } |
154 | return $postData; |
155 | } |
156 | } |
157 | |
158 | /** |
159 | * @param string $res |
160 | * @param int $numProcess |
161 | * @return bool |
162 | */ |
163 | protected function processResults( $res, $numProcess ) { |
164 | try { |
165 | $xres = new SimpleXMLElement( $res ); |
166 | } catch ( Exception $e ) { |
167 | LoggerFactory::getInstance( 'MathSearch' )->error( 'No valid XMLRESUSLT' . $res ); |
168 | return false; |
169 | } |
170 | |
171 | $this->size = (int)$xres["total"]; |
172 | LoggerFactory::getInstance( |
173 | 'MathSearch' |
174 | )->warning( $this->size . " results retrieved from $this->backendUrl." ); |
175 | if ( $this->size == 0 ) { |
176 | return true; |
177 | } |
178 | $this->relevanceMap = []; |
179 | $this->resultSet = []; |
180 | $this->processMathResults( $xres ); |
181 | if ( $this->size >= $numProcess ) { |
182 | ini_set( 'memory_limit', '256M' ); |
183 | for ( $i = $numProcess; $i <= $this->size; $i += $numProcess ) { |
184 | $query = str_replace( "limitmin=\"0\" ", "limitmin=\"$i\" ", $this->postData ); |
185 | $res = MediaWikiServices::getInstance()->getHttpRequestFactory() |
186 | ->post( $this->backendUrl, [ "postData" => $query, "timeout" => 60 ] ); |
187 | LoggerFactory::getInstance( 'mathsearch' )->debug( 'MWS query:' . $query ); |
188 | if ( $res == false ) { |
189 | LoggerFactory::getInstance( |
190 | 'MathSearch' |
191 | )->error( "Nothing retrieved from $this->backendUrl. Check if mwsd is running there" ); |
192 | return false; |
193 | } |
194 | $xres = new SimpleXMLElement( $res ); |
195 | $this->processMathResults( $xres ); |
196 | } |
197 | } |
198 | return true; |
199 | } |
200 | |
201 | /** |
202 | * @return string |
203 | */ |
204 | public function getType() { |
205 | return $this->type; |
206 | } |
207 | |
208 | /** |
209 | * @param string $type |
210 | */ |
211 | public function setType( $type ) { |
212 | $this->type = $type; |
213 | } |
214 | |
215 | public function resetResults() { |
216 | $this->size = false; |
217 | $this->resultSet = []; |
218 | $this->relevanceMap = []; |
219 | } |
220 | |
221 | } |