Completed
Push — master256 ( 37ad46 )
by Karsten
05:12 queued 02:27
created

TreeResultPrinter::getName()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 5
ccs 0
cts 2
cp 0
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
crap 2
1
<?php
2
3
namespace SRF\Formats\Tree;
4
5
/**
6
 * File holding the Tree class.
7
 *
8
 * @author Stephan Gambke
9
 */
10
11
use Exception;
12
use Html;
13
use SMW\DIProperty;
14
use SMW\DIWikiPage;
15
use SMW\ListResultPrinter;
16
use SMWQueryResult;
17
use Title;
18
19
/**
20
 * Result printer that prints query results as a tree (nested html lists).
21
 *
22
 * The available formats are 'tree', 'ultree', 'oltree'. 'tree' is an alias of
23
 * 'ultree'. In an #ask query the parameter 'parent' must be set to contain the
24
 * name of the property, that gives the parent page of the subject page.
25
 *
26
 */
27
class TreeResultPrinter extends ListResultPrinter {
28
29
	private $standardTemplateParameters;
30
31
	/**
32
	 * @var SMWQueryResult | null
33
	 */
34
	private $queryResult = null;
35
36
	/**
37
	 * (non-PHPdoc)
38
	 * @see SMWResultPrinter::getName()
39
	 */
40
	public function getName() {
41
		// Give grep a chance to find the usages:
42
		// srf-printername-tree, srf-printername-ultree, srf-printername-oltree
43
		return \Message::newFromKey( 'srf-printername-' . $this->mFormat )->text();
44
	}
45
46
	/**
47
	 * @return SMWQueryResult
48
	 * @throws Exception
49
	 */
50 5
	public function getQueryResult() {
51
52 5
		if ( $this->queryResult === null ) {
53
			throw new Exception( __METHOD__ . ' called outside of ' . __CLASS__ . '::getResultText().' );
54
		}
55
56 5
		return $this->queryResult;
57
	}
58
59
	/**
60
	 * @param SMWQueryResult | null $queryResult
61
	 */
62 7
	public function setQueryResult( $queryResult ) {
63 7
		$this->queryResult = $queryResult;
64 7
	}
65
66
	/**
67
	 * @see ResultPrinter::postProcessParameters()
68
	 */
69 8
	protected function postProcessParameters() {
70
71 8
		parent::postProcessParameters();
72
73
		// Don't support pagination in trees
74 8
		$this->mSearchlabel = null;
75
76 8
		if ( array_key_exists( 'template arguments', $this->params )
77 8
			&& $this->params['template arguments'] !== 'numbered' ) {
78
79 8
			if ( filter_var( $this->params['named args'], FILTER_VALIDATE_BOOLEAN ) === true ) {
80
				$this->params['template arguments'] = 'legacy';
81
			} elseif (
82 8
				$this->params['template arguments'] !== 'named' &&
83 8
				$this->params['template arguments'] !== 'legacy'
84
			) {
85
				// default
86 8
				$this->params['template arguments'] = 'numbered';
87
			}
88
		}
89
90
		// Allow "_" for encoding spaces, as documented
91 8
		$this->params['sep'] = str_replace( '_', ' ', $this->params['sep'] );
92
93 8
		if ( !ctype_digit( strval( $this->params['start level'] ) ) || $this->params['start level'] < 1 ) {
94
			$this->params['start level'] = 1;
95
		}
96
97 8
	}
98
99
	/**
100
	 * Return serialised results in specified format.
101
	 *
102
	 * @param SMWQueryResult $queryResult
103
	 * @param $outputmode
104
	 *
105
	 * @return string
106
	 */
107 7
	protected function getResultText( SMWQueryResult $queryResult, $outputmode ) {
108
109 7
		$this->setQueryResult( $queryResult );
110
111 7
		if ( $this->params['parent'] === '' ) {
112 2
			$this->addError( 'srf-tree-noparentprop' );
113 2
			return '';
114
		}
115
116 5
		$rootHash = $this->getRootHash();
117
118 5
		if ( $rootHash === false ) {
119
			$this->addError( 'srf-tree-rootinvalid', $this->params['root'] );
120
			return '';
121
		}
122
123 5
		$this->hasTemplates =
124 5
			$this->params['introtemplate'] !== '' ||
125 5
			$this->params['outrotemplate'] !== '' ||
126 5
			$this->params['template'] !== '';
127
128 5
		if ( $this->hasTemplates ) {
129 3
			$this->initalizeStandardTemplateParameters();
130
		}
131
132 5
		$tree = $this->buildTreeFromQueryResult( $rootHash );
133 5
		$lines = $this->buildLinesFromTree( $tree );
134
135
		// Display default if the result is empty
136 5
		if ( count( $lines ) === 0 ) {
137
			return $this->params['default'];
138
		}
139
140
		// FIXME: Linking to further events ($this->linkFurtherResults())
141
		// does not make sense for tree format. But maybe display a warning?
142
143 5
		$resultText = join(
144 5
			"\n",
145 5
			array_merge(
146 5
				[ $this->getTemplateCall( $this->params['introtemplate'] ) ],
147 5
				$lines,
148 5
				[ $this->getTemplateCall( $this->params['outrotemplate'] ) ]
149
			)
150
		);
151
152 5
		$this->setQueryResult( null );
153
154 5
		return Html::rawElement( 'div', [ 'class' => 'srf-tree' ], $resultText );
155
	}
156
157
	/**
158
	 * @param string $templateName
159
	 * @param string[] $params
160
	 *
161
	 * @return string
162
	 */
163 5
	public function getTemplateCall( $templateName, $params = [] ) {
164
165 5
		if ( $templateName === '' ) {
166 5
			return '';
167
		}
168
169 3
		return '{{' . $templateName . '|' . join( '|', $params ) . $this->standardTemplateParameters . '}}';
170
	}
171
172
	/**
173
	 * @see SMWResultPrinter::getParamDefinitions
174
	 *
175
	 * @since 1.8
176
	 *
177
	 * @param $definitions array of IParamDefinition
178
	 *
179
	 * @return array of IParamDefinition|array
180
	 */
181 8
	public function getParamDefinitions( array $definitions ) {
182 8
		$params = parent::getParamDefinitions( $definitions );
183
184 8
		$params['parent'] = [
185
			'default' => '',
186
			'message' => 'srf-paramdesc-tree-parent',
187
		];
188
189 8
		$params['root'] = [
190
			'default' => '',
191
			'message' => 'srf-paramdesc-tree-root',
192
		];
193
194 8
		$params['start level'] = [
195
			'default' => 1,
196
			'message' => 'srf-paramdesc-tree-startlevel',
197
			'type' => 'integer',
198
		];
199
200 8
		$params['sep'] = [
201
			'default' => ', ',
202
			'message' => 'smw-paramdesc-sep',
203
		];
204
205 8
		$params['template arguments'] = [
206
			'default' => '',
207
			'message' => 'smw-paramdesc-template-arguments',
208
		];
209
210 8
		return $params;
211
	}
212
213
	/**
214
	 * @param string $rootHash
215
	 *
216
	 * @return TreeNode
217
	 */
218 5
	protected function buildTreeFromQueryResult( $rootHash ) {
219
220 5
		$nodes = $this->getHashOfNodes();
221
222 5
		if ( $rootHash !== '' && !array_key_exists( $rootHash, $nodes ) ) {
223
			return new TreeNode();
224
		}
225
226 5
		return $this->buildTreeFromNodeList( $rootHash, $nodes );
227
	}
228
229
	/**
230
	 * @return string | false
231
	 */
232 5
	protected function getRootHash() {
233
234 5
		if ( $this->params['root'] === '' ) {
235 5
			return '';
236
		}
237
238
		// get the title object of the root page
239 1
		$rootTitle = Title::newFromText( $this->params['root'] );
240
241 1
		if ( $rootTitle !== null ) {
242 1
			return DIWikiPage::newFromTitle( $rootTitle )->getSerialization();
243
		}
244
245
		return false;
246
247
	}
248
249
	/**
250
	 * @return TreeNode[]
251
	 */
252 5
	protected function getHashOfNodes() {
253
254
		/** @var TreeNode[] $nodes */
255 5
		$nodes = [];
256
257 5
		$queryResult = $this->getQueryResult();
258
259 5
		$row = $queryResult->getNext();
260 5
		while ( $row !== false ) {
261 5
			$node = new TreeNode( $row );
262 5
			$nodes[$node->getHash()] = $node;
263 5
			$row = $queryResult->getNext();
264
		}
265
266 5
		return $nodes;
267
	}
268
269
	/**
270
	 * Returns a linker object for making hyperlinks
271
	 *
272
	 * @return \Linker
273
	 */
274 1
	public function getLinker( $firstcol = false ) {
275 1
		return $this->mLinker;
276
	}
277
278
	/**
279
	 * Depending on current linking settings, returns a linker object
280
	 * for making hyperlinks or NULL if no links should be created.
281
	 *
282
	 * @param int $column Column number
283
	 *
284
	 * @return \Linker|null
285
	 */
286 5
	public function getLinkerForColumn( $column ) {
287 5
		return parent::getLinker( $column === 0 );
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (getLinker() instead of getLinkerForColumn()). Are you sure this is correct? If so, you might want to change this to $this->getLinker().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
288
	}
289
290 3
	private function initalizeStandardTemplateParameters() {
291
292 3
		$query = $this->getQueryResult()->getQuery();
293
294 3
		$this->standardTemplateParameters =
295 3
			( trim( $this->params['userparam'] ) !== '' ? ( '|userparam=' . trim(
296 1
					$this->params['userparam']
297 2
				) ) : '' ) .
298 3
			'|smw-resultquerycondition=' . $query->getQueryString() .
299 3
			'|smw-resultquerylimit=' . $query->getLimit() .
300 3
			'|smw-resultqueryoffset=' . $query->getOffset();
301
302 3
	}
303
304
	/**
305
	 * @param string $rootHash
306
	 * @param TreeNode[] $nodes
307
	 *
308
	 * @return TreeNode
309
	 */
310 5
	protected function buildTreeFromNodeList( $rootHash, $nodes ) {
311
312 5
		$isRootSpecified = $rootHash !== '';
313
314 5
		$root = new TreeNode();
315 5
		if ( $isRootSpecified ) {
316 1
			$root->addChild( $nodes[$rootHash] );
317
		}
318
319 5
		$store = $this->getQueryResult()->getStore();
320 5
		$parentPointerProperty = DIProperty::newFromUserLabel( $this->params['parent'] );
321
322 5
		foreach ( $nodes as $hash => $node ) {
323
324 5
			$parents = $store->getPropertyValues(
325 5
				$node->getResultSubject(),
326 5
				$parentPointerProperty
327
			);
328
329 5
			if ( empty( $parents ) && !$isRootSpecified ) {
330
331 5
				$root->addChild( $node );
332
333
			} else {
334
335 4
				foreach ( $parents as $parent ) {
336
337 4
					$parentHash = $parent->getSerialization();
338
339
					try {
340 4
						if ( array_key_exists( $parentHash, $nodes ) ) {
341 4
							$nodes[$parentHash]->addChild( $node );
342
						} elseif ( !$isRootSpecified ) {
343 4
							$root->addChild( $node );
344
						}
345
					}
346 1
					catch ( Exception $e ) {
347 5
						$this->addError( $e->getMessage(), $node->getResultSubject()->getTitle()->getPrefixedText() );
348
					}
349
				}
350
			}
351
		}
352 5
		return $root;
353
	}
354
355
	/**
356
	 * @param TreeNode $tree
357
	 *
358
	 * @return mixed
359
	 */
360 5
	protected function buildLinesFromTree( $tree ) {
361
		$nodePrinterConfiguration = [
362 5
			'format' => trim( $this->params['format'] ),
363 5
			'template' => trim( $this->params['template'] ),
364 5
			'headers' => $this->params['headers'],
365 5
			'template arguments' => $this->params['template arguments'],
366 5
			'sep' => $this->params['sep'],
367
		];
368
369 5
		$visitor = new TreeNodePrinter( $this, $nodePrinterConfiguration );
370 5
		$lines = $tree->accept( $visitor );
371 5
		return $lines;
372
	}
373
374
	/**
375
	 * @param string $msgkey
376
	 * @param string | string[] $params
377
	 */
378 3
	protected function addError( $msgkey, $params = [] ) {
379
380 3
		parent::addError(
381 3
			\Message::newFromKey( $msgkey )
382 3
				->params( $params )
383 3
				->inContentLanguage()->text()
384
		);
385 3
	}
386
387
}
388
389