Completed
Push — master ( dc1683...3e9aec )
by mw
07:38 queued 05:33
created

src/CompoundQueryProcessor.php (1 issue)

Labels
Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace SCQ;
4
5
use SMWQueryProcessor as QueryProcessor;
6
use SMWQuery as Query;
7
use Parser;
8
9
/**
10
 * Class that holds static functions for handling compound queries.
11
 * This class inherits from Semantic MediaWiki's QueryProcessor.
12
 *
13
 * @license GNU GPL v2+
14
 * @since 1.0
15
 *
16
 * @author Yaron Koren
17
 * @author Peter Grassberger < [email protected] >
18
 */
19
class CompoundQueryProcessor extends QueryProcessor {
20
21
	/**
22
	 * Comparison helper function, used in sorting results.
23
	 */
24
	public static function compareQueryResults( $a, $b ) {
25
26
		if ( $a->getSerialization() == $b->getSerialization() ) {
27
			return 0;
28
		}
29
30
		return ( $a->getSerialization() < $b->getSerialization() ) ? -1 : 1;
31
	}
32
33
	/**
34
	 * Handler for the #compound_query parser function.
35
	 *
36
	 * @param Parser $parser
37
	 *
38
	 * @return string
39
	 */
40
	public static function doCompoundQuery( Parser &$parser ) {
41
		global $smwgQEnabled, $smwgIQRunningNumber;
42
43
		if ( !$smwgQEnabled ) {
44
			return smwfEncodeMessages( array( wfMessage( 'smw_iq_disabled' )->inContentLanguage()->text() ) );
45
		}
46
47
		$smwgIQRunningNumber++;
48
49
		$params = func_get_args();
50
		array_shift( $params ); // We already know the $parser.
51
52
		list( $queryParams, $otherParams ) = self::separateParams( $params );
53
		list( $queryResult, $otherParams ) = self::queryAndMergeResults( $queryParams, $otherParams );
54
55
		return self::getResultFromQueryResult(
56
			$queryResult,
57
			$otherParams,
58
			SMW_OUTPUT_WIKI
59
		);
60
	}
61
62
	/**
63
	 * Separates $queryParams from $otherParams.
64
	 *
65
	 * @param $params
66
	 * @return array
67
	 */
68
	public static function separateParams( $params ) {
69
		$queryParams = array();
70
		$otherParams = array();
71
72
		foreach ( $params as $param ) {
73
			// Very primitive heuristic - if the parameter
74
			// includes a square bracket, then it's a
75
			// sub-query; otherwise it's a regular parameter.
76
			if ( strpos( $param, '[' ) !== false ) {
77
				$queryParams[] = $param;
78
			} else {
79
				$parts = explode( '=', $param, 2 );
80
81
				if ( count( $parts ) >= 2 ) {
82
					$otherParams[strtolower( trim( $parts[0] ) )] = $parts[1]; // don't trim here, some params care for " "
83
				}
84
			}
85
		}
86
		return array( $queryParams, $otherParams );
87
	}
88
89
	/**
90
	 * Query and merge results of subqueries.
91
	 *
92
	 * @param $queryParams
93
	 * @param $otherParams
94
	 * @return array
95
	 */
96
	public static function queryAndMergeResults( $queryParams, $otherParams ) {
97
		$results = array();
98
		$printRequests = array();
99
100
		foreach ( $queryParams as $param ) {
101
			$subQueryParams = self::getSubParams( $param );
102
103
			if ( array_key_exists( 'format', $otherParams ) && !array_key_exists( 'format', $subQueryParams ) ) {
104
				$subQueryParams['format'] = $otherParams['format'];
105
			}
106
107
			$nextResult = self::getQueryResultFromFunctionParams($subQueryParams);
108
109
			$results = self::mergeSMWQueryResults( $results, $nextResult->getResults() );
110
			$printRequests = self::mergeSMWPrintRequests( $printRequests, $nextResult->getPrintRequests() );
111
		}
112
113
		// Sort results so that they'll show up by page name
114
		if( !isset($otherParams['unsorted']) || !strcmp( $otherParams['unsorted'], 'on' ) ) {
115
			uasort( $results, array( '\SCQ\CompoundQueryProcessor', 'compareQueryResults' ) );
116
		}
117
118
		$queryResult = new CompoundQueryResult( $printRequests, new Query(), $results, smwfGetStore() );
119
120 View Code Duplication
		if ( version_compare( SMW_VERSION, '1.6.1', '>' ) ) {
121
			self::addThisPrintout( $printRequests, $otherParams );
122
			$otherParams = self::getProcessedParams( $otherParams, $printRequests );
123
		}
124
125
		return array( $queryResult, $otherParams );
126
	}
127
128
	/**
129
	 * An alternative to explode() - that function won't work here,
130
	 * because we don't want to split the string on all semicolons, just
131
	 * the ones that aren't contained within square brackets
132
	 *
133
	 * @param string $param
134
	 *
135
	 * @return array
136
	 */
137
	protected static function getSubParams( $param ) {
138
		$sub_params = array();
139
		$sub_param = '';
140
		$uncompleted_square_brackets = 0;
141
142
		for ( $i = 0; $i < strlen( $param ); $i++ ) {
143
			$c = $param[$i];
144
145
			if ( ( $c == ';' ) && ( $uncompleted_square_brackets <= 0 ) ) {
146
				$sub_params[] = trim( $sub_param );
147
				$sub_param = '';
148
			} else {
149
				$sub_param .= $c;
150
151
				if ( $c == '[' ) {
152
					$uncompleted_square_brackets++;
153
				}
154
155
				elseif ( $c == ']' ) {
156
					$uncompleted_square_brackets--;
157
				}
158
			}
159
		}
160
161
		$sub_params[] = trim( $sub_param );
162
163
		return $sub_params;
164
	}
165
166
	/**
167
	 * @param $rawparams
168
	 * @param $context
169
	 * @param $showmode
170
	 *
171
	 * @return SMWQueryResult
172
	 */
173
	protected static function getQueryResultFromFunctionParams( $rawparams, $context = QueryProcessor::INLINE_QUERY, $showmode = false ) {
174
		$printouts = array();
175
		self::processFunctionParams( $rawparams, $querystring, $params, $printouts, $showmode );
176
		return self::getQueryResultFromQueryString( $querystring, $params, $printouts, $context );
177
	}
178
179
	/**
180
	 * Combine two arrays of SMWWikiPageValue objects into one
181
	 *
182
	 * @param array $result1
183
	 * @param array $result2
184
	 *
185
	 * @return array
186
	 */
187
	protected static function mergeSMWQueryResults( $result1, $result2 ) {
188
		if ( $result1 == null ) {
189
			return $result2;
190
		}
191
192
		$existing_page_names = array();
193
		foreach ( $result1 as $r1 ) {
194
			$existing_page_names[] = $r1->getSerialization();
195
		}
196
197
		foreach ( $result2 as $r2 ) {
198
			$page_name = $r2->getSerialization();
199
			if ( ! in_array( $page_name, $existing_page_names ) ) {
200
				$result1[] = $r2;
201
			}
202
		}
203
204
		return $result1;
205
	}
206
207
	protected static function mergeSMWPrintRequests( $printRequests1, $printRequests2 ) {
208
		$existingPrintoutLabels = array();
209
		foreach ( $printRequests1 as $p1 ) {
210
			$existingPrintoutLabels[] = $p1->getLabel();
211
		}
212
213
		foreach ( $printRequests2 as $p2 ) {
214
			$label = $p2->getLabel();
215
			if ( ! in_array( $label, $existingPrintoutLabels ) ) {
216
				$printRequests1[] = $p2;
217
			}
218
		}
219
		return $printRequests1;
220
	}
221
222
	/**
223
	 * @param $querystring
224
	 * @param array $params
225
	 * @param $extraPrintouts
226
	 * @param $outputMode
227
	 * @param $context
228
	 *
229
	 * @return SMWQueryResult
230
	 */
231
	protected static function getQueryResultFromQueryString( $querystring, array $params, $extraPrintouts, $context = QueryProcessor::INLINE_QUERY ) {
232
233 View Code Duplication
		if ( version_compare( SMW_VERSION, '1.6.1', '>' ) ) {
234
			QueryProcessor::addThisPrintout( $extraPrintouts, $params );
235
			$params = self::getProcessedParams( $params, $extraPrintouts, false );
236
		}
237
238
		$query = self::createQuery( $querystring, $params, $context, null, $extraPrintouts );
239
		$queryResult = smwfGetStore()->getQueryResult( $query );
240
241
		$parameters = array();
242
243
		if ( version_compare( SMW_VERSION, '1.7.2', '>' ) ) {
244
			foreach ( $params as $param ) {
245
				$parameters[$param->getName()] = $param->getValue();
246
			}
247
		}
248
		else {
249
			$parameters = $params;
250
		}
251
252
		foreach ( $queryResult->getResults() as $wikiPage ) {
253
			$wikiPage->display_options = $parameters;
254
		}
255
256
		return $queryResult;
257
	}
258
259
	/**
260
	 * Matches getResultFromQueryResult() from SMWQueryProcessor,
261
	 * except that formats of type 'debug' and 'count' aren't handled.
262
	 *
263
	 * @param CompoundQueryResult $res
264
	 * @param array $params These need to be the result of a list fed to getProcessedParams as of SMW 1.6.2
265
	 * @param $outputmode
266
	 * @param $context
267
	 * @param string $format
268
	 *
269
	 * @return string
270
	 */
271
	protected static function getResultFromQueryResult( CompoundQueryResult $res, array $params, $outputmode, $context = QueryProcessor::INLINE_QUERY, $format = '' ) {
272
273
		if ( version_compare( SMW_VERSION, '1.6.1', '>' ) ) {
274
			$format = $params['format'];
275
276
			if ( version_compare( SMW_VERSION, '1.7.2', '>' ) ) {
277
				$format = $format->getValue();
278
			}
279
		} else {
280
			$format = self::getResultFormat( $params );
0 ignored issues
show
The method getResultFormat() does not seem to exist on object<SCQ\CompoundQueryProcessor>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
281
		}
282
283
		$printer = self::getResultPrinter( $format, $context );
284
		$result = $printer->getResult( $res, $params, $outputmode );
285
286
		return $result;
287
	}
288
289
}
290