Completed
Push — master ( 498457...3132df )
by mw
02:32
created

ScribuntoLuaLibrary::getQueryResult()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 14
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 2.0438

Importance

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