Completed
Push — master ( dc3c24...8b46b8 )
by mw
02:43
created

ScribuntoLuaLibrary::isAQueryResult()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 2
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
1
<?php
2
3
namespace SMW\Scribunto;
4
5
use Scribunto_LuaLibraryBase;
6
use SMW\DIProperty;
7
use SMW\ApplicationFactory;
8
use SMWQueryResult as QueryResult;
9
use SMWOutputs;
10
11
/**
12
 * @license GNU GPL v2+
13
 * @since 1.0
14
 *
15
 * @author mwjames
16
 */
17
class ScribuntoLuaLibrary extends Scribunto_LuaLibraryBase {
18
19
	/**
20
	 * @var LibraryFactory
21
	 */
22
	private $libraryFactory;
23
24
	/**
25
	 * This is the name of the key for error messages
26
	 *
27
	 * @var string
28
	 * @since 1.0
29
	 */
30
	const SMW_ERROR_FIELD = 'error';
31
32
	/**
33
	 * @since 1.0
34
	 */
35 34
	public function register() {
36
37
		$lib = array(
38 34
			'ask'             => array( $this, 'ask' ),
39 34
			'getPropertyType' => array( $this, 'getPropertyType' ),
40 34
			'getQueryResult'  => array( $this, 'getQueryResult' ),
41 34
			'info'            => array( $this, 'info' ),
42 34
			'set'             => array( $this, 'set' ),
43 34
			'subobject'       => array( $this, 'subobject' ),
44 34
		);
45
46 34
		$this->getEngine()->registerInterface( __DIR__ . '/' . 'mw.smw.lua', $lib, array() );
47 34
	}
48
49
	/**
50
	 * This mirrors the functionality of the parser function #ask and makes it
51
	 * available in lua.
52
	 *
53
	 * @since 1.0
54
	 *
55
	 * @param string|array $arguments parameters passed from lua, string or array depending on call
56
	 *
57
	 * @return array    array( null ) or array[]
58
	 */
59 7
	public function ask( $arguments = null ) {
60
61 7
		$queryResult = $this->getLibraryFactory()->newQueryResultFrom(
62 7
			$this->processLuaArguments( $arguments )
63 7
		);
64
65 7
		if ( !$this->isAQueryResult( $queryResult ) ) {
66
			return array( $queryResult );
67
		}
68
69 7
		$luaResultProcessor = $this->getLibraryFactory()->newLuaAskResultProcessor(
70
			$queryResult
0 ignored issues
show
Documentation introduced by
$queryResult is of type object<SMWQueryResult>, but the function expects a object<SMW\Scribunto\QueryResult>|string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
71 7
		);
72
73 7
		$result = $luaResultProcessor->getQueryResultAsTable();
74
75 7
		if ( !empty( $result ) ) {
76 1
			array_unshift( $result, null );
77 1
		}
78
79 7
		return array( $result );
80
	}
81
82
	/**
83
	 * Returns property type
84
	 *
85
	 * @since 1.0
86
	 *
87
	 * @param string $propertyName
88
	 *
89
	 * @return array
90
	 */
91 5
	public function getPropertyType( $propertyName = null ) {
92
93 5
		$this->checkType( 'getPropertyType', 1, $propertyName, 'string' );
94 5
		$propertyName = trim( $propertyName );
95
96 5
		if ( $propertyName === '' ) {
97 3
			return array( null );
98
		}
99
100 3
		$property = DIProperty::newFromUserLabel( $propertyName );
101
102 3
		if ( $property === null ) {
103
			return array( null );
104
		}
105
106 3
		return array( $property->findPropertyTypeID() );
107
	}
108
109
	/**
110
	 * Returns query results in for of the standard API return format
111
	 *
112
	 * @since 1.0
113
	 *
114
	 * @param string|array $arguments
115
	 *
116
	 * @return array
117
	 */
118 5
	public function getQueryResult( $arguments = null ) {
119
120 4
		$queryResult = $this->getLibraryFactory()->newQueryResultFrom(
121 4
			$this->processLuaArguments( $arguments )
122 4
		);
123
124 4
		if ( !$this->isAQueryResult( $queryResult ) ) {
125
			return array( $queryResult );
126
		}
127
128 4
		$result = $queryResult->toArray();
129
130 4
		if( !empty( $result["results"] ) ) {
131
		    $result["results"] = array_combine( range( 1, count( $result["results"] ) ), array_values( $result["results"] ) );
132
		}
133
134 5
		return array( $result );
135
	}
136
137
	/**
138
	 * This mirrors the functionality of the parser function #info and makes it
139
	 * available to lua.
140
	 *
141
	 * @since 1.0
142
	 *
143
	 * @param string $text text to show inside the info popup
144
	 * @param string $icon identifier for the icon to use
145
	 *
146
	 * @return string[]
147
	 */
148 6
	public function info( $text, $icon = 'info' ) {
149
150
		// do some parameter processing
151 6
		if ( ! trim( $text ) || ! is_string( $text ) ) {
152
			// no info-text present, or wrong type. abort
153 3
			return null;
154
		}
155
156
		// check if icon is set and valid
157 4
		if ( !is_string( $icon ) || !in_array( $icon, [ 'note', 'warning' ] ) ) {
158 4
			$icon = 'info';
159 4
		}
160
161
		// the actual info message is easy to create:
162 4
		$result = smwfEncodeMessages(
163 4
			array( $text ),
164 4
			$icon,
165 4
			' <!--br-->',
166
			false // No escaping.
167 4
		);
168
169
		// to have all necessary data committed to output, use SMWOutputs::commitToParser()
170 4
		SMWOutputs::commitToParser(
171 4
			$this->getEngine()->getParser()
172 4
		);
173
174 4
		return array( $this->doPostProcessParserFunctionCallResult( $result ) );
175
	}
176
177
	/**
178
	 * This mirrors the functionality of the parser function #set and makes it
179
	 * available in lua.
180
	 *
181
	 * @since 1.0
182
	 *
183
	 * @param string|array $arguments arguments passed from lua, string or array depending on call
184
	 *
185
	 * @return null|array|array[]
186
	 */
187 13
	public function set( $arguments ) {
188
189 13
		$arguments = $this->processLuaArguments( $arguments );
190
191 13
		$setParserFunction = $this->getLibraryFactory()->newSetParserFunction(
192 13
			$this->getEngine()->getParser()
193 13
		);
194
195 13
		$parserFunctionCallResult = $setParserFunction->parse(
196 13
			$this->getLibraryFactory()->newParserParameterProcessorFrom( $arguments )
197 13
		);
198
199
		// get usable result
200 13
		$result = $this->doPostProcessParserFunctionCallResult(
201
			$parserFunctionCallResult
202 13
		);
203
204 13
		if ( strlen( $result ) ) {
205
			// if result is a non empty string, assume an error message
206 2
			return array( [ 1 => false, self::SMW_ERROR_FIELD => preg_replace( '/<[^>]+>/', '', $result ) ] );
207
		}
208
209
		// on success, return true
210 11
		return array( 1 => true );
211
	}
212
213
	/**
214
	 * This mirrors the functionality of the parser function #subobject and
215
	 * makes it available to lua.
216
	 *
217
	 * @param string|array $arguments arguments passed from lua, string or array depending on call
218
	 * @param string $subobjectId if you need to manually assign an id, do this here
219
	 *
220
	 * @return null|array|array[]
221
	 */
222 21
	public function subobject( $arguments, $subobjectId = null ) {
223
224 21
		$arguments = $this->processLuaArguments( $arguments );
225
226
		// parameters[0] would be the subobject id, so unshift
227 21
		array_unshift( $arguments, null );
228
229
		// if subobject id was set, put it on position 0
230 21
		if ( !is_null( $subobjectId ) && $subobjectId ) {
231
			// user deliberately set an id for this subobject
232 10
			$arguments[0] = $subobjectId;
233
234
			// we need to ksort, otherwise ParameterProcessorFactory doesn't
235
			// recognize the id
236 10
			ksort( $arguments );
237 10
		}
238
239
		// prepare subobjectParserFunction object
240 21
		$subobjectParserFunction = $this->getLibraryFactory()->newSubobjectParserFunction(
241 21
			$this->getEngine()->getParser()
242 21
		);
243
244 21
		$parserFunctionCallResult = $subobjectParserFunction->parse(
245 21
			 $this->getLibraryFactory()->newParserParameterProcessorFrom( $arguments )
246 21
		);
247
248 21
		if ( strlen( $result = $this->doPostProcessParserFunctionCallResult( $parserFunctionCallResult ) ) ) {
249
			// if result a non empty string, assume an error message
250 4
			return array( [ 1 => false, self::SMW_ERROR_FIELD => preg_replace( '/<[^>]+>/', '', $result ) ] );
251
		}
252
253
		// on success, return true
254 17
		return array( 1 => true );
255
	}
256
257
	/**
258
	 * Takes a result returned from a parser function call and prepares it to be
259
	 * used as parsed string.
260
	 *
261
	 * @since 1.0
262
	 *
263
	 * @param string|array $parserFunctionResult
264
	 *
265
	 * @return string
266
	 */
267 38
	private function doPostProcessParserFunctionCallResult( $parserFunctionResult ) {
268
269
		// parser function call can return string or array
270 38
		if ( is_array( $parserFunctionResult ) ) {
271 13
			$result = $parserFunctionResult[0];
272 13
			$noParse = isset( $parserFunctionResult['noparse'] ) ? $parserFunctionResult['noparse'] : true;
273 13
		} else {
274 25
			$result = $parserFunctionResult;
275 25
			$noParse = true;
276
		}
277
278 38
		if ( !$noParse ) {
279
			$result = $this->getEngine()->getParser()->recursiveTagParseFully( $result );
280
		}
281
282 38
		return trim( $result );
283
	}
284
285
	/**
286
	 * Returns the LibraryFactory singleton (and creates it first, if not already present)
287
	 *
288
	 * @since 1.0
289
	 *
290
	 * @return LibraryFactory
291
	 */
292 45
	private function getLibraryFactory() {
293
294 45
		if ( $this->libraryFactory !== null ) {
295 42
			return $this->libraryFactory;
296
		}
297
298 45
		$this->libraryFactory = new LibraryFactory(
299 45
			ApplicationFactory::getInstance()->getStore()
300 45
		);
301
302 45
		return $this->libraryFactory;
303
	}
304
305
	/**
306
	 * Tests, if supplied parameter `$queryResult` is a valid {@see QueryResult}
307
	 *
308
	 * @since 1.0
309
	 *
310
	 * @param mixed $queryResult
311
	 *
312
	 * @return bool
313
	 */
314 11
	private function isAQueryResult( $queryResult ) {
315 11
		return is_a( $queryResult, QueryResult::class );
316
	}
317
318
	/**
319
	 * Takes the $arguments passed from lua and pre-processes them: make sure,
320
	 * we have a sequence array (not associative)
321
	 *
322
	 * @since 1.0
323
	 *
324
	 * @param string|array $arguments
325
	 *
326
	 * @return array
327
	 */
328 45
	private function processLuaArguments( $arguments ) {
329
330
		// make sure, we have an array of parameters
331 45
		if ( !is_array( $arguments ) ) {
332 21
			$arguments = preg_split( "/(?<=[^\|])\|(?=[^\|])/", $arguments );
333 21
		}
334
335
		// if $arguments were supplied as key => value pair (aka associative array),
336
		// we rectify this here
337 45
		$processedArguments = array();
338 45
		foreach ( $arguments as $key => $value ) {
339 41
			if ( !is_int( $key ) && !preg_match( '/[0-9]+/', $key ) ) {
340 12
				$value = (string) $key . '=' . (string) $value;
341 12
			}
342 41
			$processedArguments[] = $value;
343 45
		}
344
345 45
		return $processedArguments;
346
	}
347
348
}
349