Completed
Push — master ( 3132df...b84890 )
by mw
03:02
created

ScribuntoLuaLibrary::ask()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 18
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 2.024

Importance

Changes 0
Metric Value
cc 2
eloc 9
nc 2
nop 1
dl 0
loc 18
ccs 9
cts 11
cp 0.8182
crap 2.024
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace SMW\Scribunto;
4
5
use Scribunto_LuaLibraryBase;
6
use SMW\DIProperty;
7
use SMW\ApplicationFactory;
8
use SMWOutputs;
9
10
/**
11
 * @license GNU GPL v2+
12
 * @since 1.0
13
 *
14
 * @author mwjames
15
 */
16
class ScribuntoLuaLibrary extends Scribunto_LuaLibraryBase {
17
18
	/**
19
	 * @var LibraryFactory
20
	 */
21
	private $libraryFactory;
22
23
	/**
24
	 * This is the name of the key for error messages
25
	 *
26
	 * @var string
27
	 * @since 1.0
28
	 */
29
	const SMW_ERROR_FIELD = 'error';
30
31
	/**
32
	 * @since 1.0
33
	 */
34 33
	public function register() {
35
36
		$lib = array(
37 33
			'ask'             => array( $this, 'ask' ),
38 33
			'getPropertyType' => array( $this, 'getPropertyType' ),
39 33
			'getQueryResult'  => array( $this, 'getQueryResult' ),
40 33
			'info'            => array( $this, 'info' ),
41 33
			'set'             => array( $this, 'set' ),
42 33
			'subobject'       => array( $this, 'subobject' ),
43 33
		);
44
45 33
		$this->getEngine()->registerInterface( __DIR__ . '/' . 'mw.smw.lua', $lib, array() );
46 33
	}
47
48
	/**
49
	 * This mirrors the functionality of the parser function #ask and makes it
50
	 * available in lua.
51
	 *
52
	 * @since 1.0
53
	 *
54
	 * @param string|array $arguments parameters passed from lua, string or array depending on call
55
	 *
56
	 * @return null|array[]
57
	 */
58 6
	public function ask ( $arguments = null ) {
59
60 6
		$queryResult = $this->getLibraryFactory()->newQueryResultFrom(
61 6
			$this->processLuaArguments( $arguments )
62 6
		);
63
64 6
		$luaResultProcessor = $this->getLibraryFactory()->newLuaAskResultProcessor(
65
			$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...
66 6
		);
67
68 6
		$result = $luaResultProcessor->getQueryResultAsTable();
69
70 6
		if ( !empty( $result ) ) {
71
			array_unshift( $result, null );
72
		}
73
74 6
		return array( $result );
75
	}
76
77
	/**
78
	 * Returns property type
79
	 *
80
	 * @since 1.0
81
	 *
82
	 * @param string $propertyName
83
	 *
84
	 * @return array
85
	 */
86 5
	public function getPropertyType( $propertyName = null ) {
87
88 5
		$this->checkType( 'getPropertyType', 1, $propertyName, 'string' );
89 5
		$propertyName = trim( $propertyName );
90
91 5
		if ( $propertyName === '' ) {
92 3
			return array( null );
93
		}
94
95 3
		$property = DIProperty::newFromUserLabel( $propertyName );
96
97 3
		if ( $property === null ) {
98
			return array( null );
99
		}
100
101 3
		return array( $property->findPropertyTypeID() );
102
	}
103
104
	/**
105
	 * Returns query results in for of the standard API return format
106
	 *
107
	 * @since 1.0
108
	 *
109
	 * @param string|array $arguments
110
	 *
111
	 * @return array
112
	 */
113 4
	public function getQueryResult( $arguments = null ) {
114
115 4
		$queryResult = $this->getLibraryFactory()->newQueryResultFrom(
116 4
			$this->processLuaArguments( $arguments )
117 4
		);
118
119 4
		$result = $queryResult->toArray();
120
121 4
		if( !empty( $result["results"] ) ) {
122
		    $result["results"] = array_combine( range( 1, count( $result["results"] ) ), array_values( $result["results"] ) );
123
		}
124
125 4
		return array( $result );
126
	}
127
128
	/**
129
	 * This mirrors the functionality of the parser function #info and makes it
130
	 * available to lua.
131
	 *
132
	 * @since 1.0
133
	 *
134
	 * @param string $text text to show inside the info popup
135
	 * @param string $icon identifier for the icon to use
136
	 *
137
	 * @return string[]
138
	 */
139 6
	public function info( $text, $icon = 'info' ) {
140
141
		// do some parameter processing
142 6
		if ( ! trim( $text ) || ! is_string( $text ) ) {
143
			// no info-text present, or wrong type. abort
144 3
			return null;
145
		}
146
147
		// check if icon is set and valid
148 4
		if ( !is_string( $icon ) || !in_array( $icon, [ 'note', 'warning' ] ) ) {
149 4
			$icon = 'info';
150 4
		}
151
152
		// the actual info message is easy to create:
153 4
		$result = smwfEncodeMessages(
154 4
			array( $text ),
155 4
			$icon,
156 4
			' <!--br-->',
157
			false // No escaping.
158 4
		);
159
160
		// to have all necessary data committed to output, use SMWOutputs::commitToParser()
161 4
		SMWOutputs::commitToParser(
162 4
			$this->getEngine()->getParser()
163 4
		);
164
165 4
		return array( $this->doPostProcessParserFunctionCallResult( $result ) );
166
	}
167
168
	/**
169
	 * This mirrors the functionality of the parser function #set and makes it
170
	 * available in lua.
171
	 *
172
	 * @since 1.0
173
	 *
174
	 * @param string|array $arguments arguments passed from lua, string or array depending on call
175
	 *
176
	 * @return null|array|array[]
177
	 */
178 13
	public function set( $arguments ) {
179
180 13
		$arguments = $this->processLuaArguments( $arguments );
181
182 13
		$setParserFunction = $this->getLibraryFactory()->newSetParserFunction(
183 13
			$this->getEngine()->getParser()
184 13
		);
185
186 13
		$parserFunctionCallResult = $setParserFunction->parse(
187 13
			$this->getLibraryFactory()->newParserParameterProcessorFrom( $arguments )
188 13
		);
189
190
		// get usable result
191 13
		$result = $this->doPostProcessParserFunctionCallResult(
192
			$parserFunctionCallResult
193 13
		);
194
195 13
		if ( strlen( $result ) ) {
196
			// if result is a non empty string, assume an error message
197 2
			return array( [ 1 => false, self::SMW_ERROR_FIELD => preg_replace( '/<[^>]+>/', '', $result ) ] );
198
		}
199
200
		// on success, return true
201 11
		return array( 1 => true );
202
	}
203
204
	/**
205
	 * This mirrors the functionality of the parser function #subobject and
206
	 * makes it available to lua.
207
	 *
208
	 * @param string|array $arguments arguments passed from lua, string or array depending on call
209
	 * @param string $subobjectId if you need to manually assign an id, do this here
210
	 *
211
	 * @return null|array|array[]
212
	 */
213 21
	public function subobject( $arguments, $subobjectId = null ) {
214
215 21
		$arguments = $this->processLuaArguments( $arguments );
216
217
		// parameters[0] would be the subobject id, so unshift
218 21
		array_unshift( $arguments, null );
219
220
		// if subobject id was set, put it on position 0
221 21
		if ( !is_null( $subobjectId ) && $subobjectId ) {
222
			// user deliberately set an id for this subobject
223 10
			$arguments[0] = $subobjectId;
224
225
			// we need to ksort, otherwise ParameterProcessorFactory doesn't
226
			// recognize the id
227 10
			ksort( $arguments );
228 10
		}
229
230
		// prepare subobjectParserFunction object
231 21
		$subobjectParserFunction = $this->getLibraryFactory()->newSubobjectParserFunction(
232 21
			$this->getEngine()->getParser()
233 21
		);
234
235 21
		$parserFunctionCallResult = $subobjectParserFunction->parse(
236 21
			 $this->getLibraryFactory()->newParserParameterProcessorFrom( $arguments )
237 21
		);
238
239 21
		if ( strlen( $result = $this->doPostProcessParserFunctionCallResult( $parserFunctionCallResult ) ) ) {
240
			// if result a non empty string, assume an error message
241 4
			return array( [ 1 => false, self::SMW_ERROR_FIELD => preg_replace( '/<[^>]+>/', '', $result ) ] );
242
		}
243
244
		// on success, return true
245 17
		return array( 1 => true );
246
	}
247
248
	/**
249
	 * Takes a result returned from a parser function call and prepares it to be
250
	 * used as parsed string.
251
	 *
252
	 * @since 1.0
253
	 *
254
	 * @param string|array $parserFunctionResult
255
	 *
256
	 * @return string
257
	 */
258 38
	private function doPostProcessParserFunctionCallResult( $parserFunctionResult ) {
259
260
		// parser function call can return string or array
261 38
		if ( is_array( $parserFunctionResult ) ) {
262 13
			$result = $parserFunctionResult[0];
263 13
			$noParse = isset( $parserFunctionResult['noparse'] ) ? $parserFunctionResult['noparse'] : true;
264 13
		} else {
265 25
			$result = $parserFunctionResult;
266 25
			$noParse = true;
267
		}
268
269 38
		if ( !$noParse ) {
270
			$result = $this->getEngine()->getParser()->recursiveTagParseFully( $result );
271
		}
272
273 38
		return trim( $result );
274
	}
275
276
	/**
277
	 * Returns the LibraryFactory singleton (and creates it first, if not already present)
278
	 *
279
	 * @since 1.0
280
	 *
281
	 * @return LibraryFactory
282
	 */
283 44
	private function getLibraryFactory() {
284
285 44
		if ( $this->libraryFactory !== null ) {
286 41
			return $this->libraryFactory;
287
		}
288
289 44
		$this->libraryFactory = new LibraryFactory(
290 44
			ApplicationFactory::getInstance()->getStore()
291 44
		);
292
293 44
		return $this->libraryFactory;
294
	}
295
296
	/**
297
	 * Takes the $arguments passed from lua and pre-processes them: make sure,
298
	 * we have a sequence array (not associative)
299
	 *
300
	 * @since 1.0
301
	 *
302
	 * @param string|array $arguments
303
	 *
304
	 * @return array
305
	 */
306 44
	private function processLuaArguments( $arguments ) {
307
308
		// make sure, we have an array of parameters
309 44
		if ( !is_array( $arguments ) ) {
310 21
			$arguments = preg_split( "/(?<=[^\|])\|(?=[^\|])/", $arguments );
311 21
		}
312
313
		// if $arguments were supplied as key => value pair (aka associative array),
314
		// we rectify this here
315 44
		$processedArguments = array();
316 44
		foreach ( $arguments as $key => $value ) {
317 40
			if ( !is_int( $key ) && !preg_match( '/[0-9]+/', $key ) ) {
318 11
				$value = (string) $key . '=' . (string) $value;
319 11
			}
320 40
			$processedArguments[] = $value;
321 44
		}
322
323 44
		return $processedArguments;
324
	}
325
326
}
327