Completed
Push — master ( 009a56...ff47c8 )
by mw
17:58
created

ScribuntoLuaLibrary::getLibraryFactory()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 6
c 0
b 0
f 0
nc 2
nop 0
dl 0
loc 12
ccs 7
cts 7
cp 1
crap 2
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 20
	public function register() {
35
36
		$lib = array(
37 20
			'getPropertyType' => array( $this, 'getPropertyType' ),
38 20
			'getQueryResult'  => array( $this, 'getQueryResult' ),
39 20
			'info'            => array( $this, 'info' ),
40 20
			'set'             => array( $this, 'set' ),
41 20
			'subobject'       => array( $this, 'subobject' ),
42 20
		);
43
44 20
		$this->getEngine()->registerInterface( __DIR__ . '/' . 'mw.smw.lua', $lib, array() );
45 20
	}
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 6
		$parser = $this->getEngine()->getParser();
112
113
		// do some parameter processing
114 6
		if ( ! trim( $text ) || ! is_string( $text ) ) {
115
			// no info-text present, or wrong type. abort
116 3
			return null;
117
		}
118
119
		// check if icon is set and valid
120 4
		if ( !is_string( $icon ) || !in_array( $icon, [ 'note', 'warning' ] ) ) {
121 4
			$icon = 'info';
122 4
		}
123
124
		// the actual info message is easy to create:
125 4
		$result = smwfEncodeMessages(
126 4
			array( $text ),
127 4
			$icon,
128 4
			' <!--br-->',
129
			false // No escaping.
130 4
		);
131
132
		// to have all necessary data committed to output, use SMWOutputs::commitToParser()
133 4
		SMWOutputs::commitToParser( $parser );
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 $parameters parameters passed from lua, string or array depending on call
145
	 *
146
	 * @return null|array|array[]
147
	 */
148 10
	public function set( $parameters ) {
149
150 10
		$parser = $this->getEngine()->getParser();
151
152
		// if we have no arguments, do nothing
153 10
		if ( !count( $arguments = $this->processLuaArguments( $parameters ) ) ) {
154 3
			return null;
155
		}
156
157 7
		$setParserFunction = $this->getLibraryFactory()->newSetParserFunction( $parser );
158
159 7
		$parserFunctionCallResult = $setParserFunction->parse(
160 7
			$this->getLibraryFactory()->newParserParameterProcessorFrom( $arguments )
161 7
		);
162
163
		// get usable result
164 7
		$result = $this->doPostProcessParserFunctionCallResult( $parserFunctionCallResult );
165
166 7
		if ( strlen( $result ) ) {
167
			// if result a non empty string, assume an error message
168 2
			return array( [ 1 => false, self::SMW_ERROR_FIELD => preg_replace( '/<[^>]+>/', '', $result ) ] );
169
		} else {
170
			// on success, return true
171 5
			return array( 1 => true );
172
		}
173
	}
174
175
	/**
176
	 * This mirrors the functionality of the parser function #subobject and
177
	 * makes it available to lua.
178
	 *
179
	 * @param string|array $parameters parameters passed from lua, string or array depending on call
180
	 * @param string $subobjectId if you need to manually assign an id, do this here
181
	 *
182
	 * @return null|array|array[]
183
	 */
184 13
	public function subobject( $parameters, $subobjectId = null ) {
185
186 13
		$parser = $this->getEngine()->getParser();
187
188
		// if we have no arguments, do nothing
189 13
		if ( !count( $arguments = $this->processLuaArguments( $parameters ) ) ) {
190 7
			return null;
191
		}
192
193
		// parameters[0] would be the subobject id, so unshift
194 6
		if ( isset( $arguments[0] ) ) {
195 6
			array_unshift( $arguments, null );
196 6
		}
197
198
		// if subobject id was set, put it on position 0
199 6
		if ( !is_null( $subobjectId ) && $subobjectId ) {
200
			// user deliberately set an id for this subobject
201 3
			$arguments[0] = $subobjectId;
202
203
			// we need to ksort, otherwise ParameterProcessorFactory doesn't
204
			// recognize the id
205 3
			ksort( $arguments );
206 3
		}
207
208
		// prepare subobjectParserFunction object
209 6
		$subobjectParserFunction = $this->getLibraryFactory()->newSubobjectParserFunction(
210
			$parser
211 6
		);
212
213 6
		$parserFunctionCallResult = $subobjectParserFunction->parse(
214 6
			 $this->getLibraryFactory()->newParserParameterProcessorFrom( $arguments )
215 6
		);
216
217 6
		if ( strlen( $result = $this->doPostProcessParserFunctionCallResult( $parserFunctionCallResult ) ) ) {
218
			// if result a non empty string, assume an error message
219 2
			return array( [ 1 => false, self::SMW_ERROR_FIELD => preg_replace( '/<[^>]+>/', '', $result ) ] );
220
		} else {
221
			// on success, return true
222 4
			return array( 1 => true );
223
		}
224
	}
225
226
	/**
227
	 * Takes a result returned from a parser function call and prepares it to be
228
	 * used as parsed string.
229
	 *
230
	 * @since 1.0
231
	 *
232
	 * @param string|array $parserFunctionResult
233
	 *
234
	 * @return string
235
	 */
236 17
	private function doPostProcessParserFunctionCallResult( $parserFunctionResult ) {
237
238
		// parser function call can return string or array
239 17
		if ( is_array( $parserFunctionResult ) ) {
240 7
			$result = $parserFunctionResult[0];
241 7
			$noParse = isset( $parserFunctionResult['noparse'] ) ? $parserFunctionResult['noparse'] : true;
242 7
		} else {
243 10
			$result = $parserFunctionResult;
244 10
			$noParse = true;
245
		}
246
247 17
		if ( !$noParse ) {
248
			$result = $this->getEngine()->getParser()->recursiveTagParseFully( $result );
249
		}
250
251 17
		return trim( $result );
252
	}
253
254
	/**
255
	 * Takes the $arguments passed from lua and pre-processes them: make sure,
256
	 * we have a sequence array (not associative)
257
	 *
258
	 * @since 1.0
259
	 *
260
	 * @param string|array $arguments
261
	 *
262
	 * @return array
263
	 */
264 27
	private function processLuaArguments( $arguments ) {
265
266
		// make sure, we have an array of parameters
267 27
		if ( !is_array( $arguments ) ) {
268 14
			$arguments = preg_split( "/(?<=[^\|])\|(?=[^\|])/", $arguments );
269 14
		}
270
271
		// if $arguments were supplied as key => value pair (aka associative array),
272
		// we rectify this here
273 27
		$processedArguments = array();
274 27
		foreach ( $arguments as $key => $value ) {
275 24
			if ( !is_int( $key ) && !preg_match( '/[0-9]+/', $key ) ) {
276 3
				$value = (string) $key . '=' . (string) $value;
277 3
			}
278 24
			if ( $value ) {
279
				// only add, when value is set. could be empty, if lua function
280
				// was called with no parameter or empty string
281 15
				$processedArguments[] = $value;
282 15
			}
283 27
		}
284
285 27
		return $processedArguments;
286
	}
287
288 17
	private function getLibraryFactory() {
289
290 17
		if ( $this->libraryFactory !== null ) {
291 14
			return $this->libraryFactory;
292
		}
293
294 17
		$this->libraryFactory = new LibraryFactory(
295 17
			ApplicationFactory::getInstance()->getStore()
296 17
		);
297
298 17
		return $this->libraryFactory;
299
	}
300
301
}
302