Completed
Push — rel300 ( 603b3e...0d5c58 )
by Karsten
20:08
created

TreeResultPrinter::getLinkerForColumn()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 1
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
		// Allow "_" for encoding spaces, as documented
77 8
		$this->params['sep'] = str_replace( '_', ' ', $this->params['sep'] );
78
79 8
		if ( !ctype_digit( strval( $this->params['start level'] ) ) || $this->params['start level'] < 1 ) {
80
			$this->params['start level'] = 1;
81
		}
82 8
83 8
	}
84
85
	/**
86 8
	 * Return serialised results in specified format.
87
	 *
88
	 * @param SMWQueryResult $queryResult
89
	 * @param $outputmode
90
	 *
91 8
	 * @return string
92
	 */
93 8
	protected function getResultText( SMWQueryResult $queryResult, $outputmode ) {
94
95
		$this->setQueryResult( $queryResult );
96
97 8
		if ( $this->params['parent'] === '' ) {
98
			$this->addError( 'srf-tree-noparentprop' );
99
			return '';
100
		}
101
102
		$rootHash = $this->getRootHash();
103
104
		if ( $rootHash === false ) {
105
			$this->addError( 'srf-tree-rootinvalid', $this->params['root'] );
106
			return '';
107 7
		}
108
109 7
		$this->hasTemplates =
110
			$this->params['introtemplate'] !== '' ||
111 7
			$this->params['outrotemplate'] !== '' ||
112 2
			$this->params['template'] !== '';
113 2
114
		if ( $this->hasTemplates ) {
115
			$this->initalizeStandardTemplateParameters();
116 5
		}
117
118 5
		$tree = $this->buildTreeFromQueryResult( $rootHash );
119
		$lines = $this->buildLinesFromTree( $tree );
120
121
		// Display default if the result is empty
122
		if ( count( $lines ) === 0 ) {
123 5
			return $this->params['default'];
124 5
		}
125 5
126 5
		// FIXME: Linking to further events ($this->linkFurtherResults())
127
		// does not make sense for tree format. But maybe display a warning?
128 5
129 3
		$resultText = join(
130
			"\n",
131
			array_merge(
132 5
				[ $this->getTemplateCall( $this->params['introtemplate'] ) ],
133 5
				$lines,
134
				[ $this->getTemplateCall( $this->params['outrotemplate'] ) ]
135
			)
136 5
		);
137
138
		$this->setQueryResult( null );
139
140
		return Html::rawElement( 'div', [ 'class' => 'srf-tree' ], $resultText );
141
	}
142
143 5
	/**
144 5
	 * @param string $templateName
145 5
	 * @param string[] $params
146 5
	 *
147 5
	 * @return string
148 5
	 */
149
	public function getTemplateCall( $templateName, $params = [] ) {
150
151
		if ( $templateName === '' ) {
152 5
			return '';
153
		}
154 5
155
		return '{{' . $templateName . '|' . join( '|', $params ) . $this->standardTemplateParameters . '}}';
156
	}
157
158
	/**
159
	 * @see SMWResultPrinter::getParamDefinitions
160
	 *
161
	 * @since 1.8
162
	 *
163 5
	 * @param $definitions array of IParamDefinition
164
	 *
165 5
	 * @return array of IParamDefinition|array
166 5
	 * @throws Exception
167
	 */
168
	public function getParamDefinitions( array $definitions ) {
169 3
		$params = parent::getParamDefinitions( $definitions );
170
171
		$params['parent'] = [
172
			'default' => '',
173
			'message' => 'srf-paramdesc-tree-parent',
174
		];
175
176
		$params['root'] = [
177
			'default' => '',
178
			'message' => 'srf-paramdesc-tree-root',
179
		];
180
181 8
		$params['start level'] = [
182 8
			'default' => 1,
183
			'message' => 'srf-paramdesc-tree-startlevel',
184 8
			'type' => 'integer',
185
		];
186
187
		$params['sep'] = [
188
			'default' => ', ',
189 8
			'message' => 'smw-paramdesc-sep',
190
		];
191
192
		$params['template arguments'] = [
193
			'default' => '',
194 8
			'message' => 'smw-paramdesc-template-arguments',
195
		];
196
197
		return $params;
198
	}
199
200 8
	/**
201
	 * @param string $rootHash
202
	 *
203
	 * @return TreeNode
204
	 */
205 8
	protected function buildTreeFromQueryResult( $rootHash ) {
206
207
		$nodes = $this->getHashOfNodes();
208
209
		if ( $rootHash !== '' && !array_key_exists( $rootHash, $nodes ) ) {
210 8
			return new TreeNode();
211
		}
212
213
		return $this->buildTreeFromNodeList( $rootHash, $nodes );
214
	}
215
216
	/**
217
	 * @return string | false
218 5
	 */
219
	protected function getRootHash() {
220 5
221
		if ( $this->params['root'] === '' ) {
222 5
			return '';
223
		}
224
225
		// get the title object of the root page
226 5
		$rootTitle = Title::newFromText( $this->params['root'] );
227
228
		if ( $rootTitle !== null ) {
229
			return DIWikiPage::newFromTitle( $rootTitle )->getSerialization();
230
		}
231
232 5
		return false;
233
234 5
	}
235 5
236
	/**
237
	 * @return TreeNode[]
238
	 */
239 1
	protected function getHashOfNodes() {
240
241 1
		/** @var TreeNode[] $nodes */
242 1
		$nodes = [];
243
244
		$queryResult = $this->getQueryResult();
245
246
		$row = $queryResult->getNext();
247
		while ( $row !== false ) {
248
			$node = new TreeNode( $row );
249
			$nodes[$node->getHash()] = $node;
250
			$row = $queryResult->getNext();
251
		}
252 5
253
		return $nodes;
254
	}
255 5
256
	/**
257 5
	 * Returns a linker object for making hyperlinks
258
	 *
259 5
	 * @return \Linker
260 5
	 */
261 5
	public function getLinker( $firstcol = false ) {
262 5
		return $this->mLinker;
263 5
	}
264
265
	/**
266 5
	 * Depending on current linking settings, returns a linker object
267
	 * for making hyperlinks or NULL if no links should be created.
268
	 *
269
	 * @param int $column Column number
270
	 *
271
	 * @return \Linker|null
272
	 */
273
	public function getLinkerForColumn( $column ) {
274 1
		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...
275 1
	}
276
277
	private function initalizeStandardTemplateParameters() {
278
279
		$query = $this->getQueryResult()->getQuery();
280
		$userparam = trim( $this->params[ 'userparam' ] );
281
282
		$this->standardTemplateParameters =
283
			( $userparam !== '' ? ( '|userparam=' . $userparam ) : '' ) .
284
			'|smw-resultquerycondition=' . $query->getQueryString() .
285
			'|smw-resultquerylimit=' . $query->getLimit() .
286 5
			'|smw-resultqueryoffset=' . $query->getOffset();
287 5
288
	}
289
290 3
	/**
291
	 * @param string $rootHash
292 3
	 * @param TreeNode[] $nodes
293
	 *
294 3
	 * @return TreeNode
295 3
	 * @throws \Exception
296 1
	 */
297 2
	protected function buildTreeFromNodeList( $rootHash, $nodes ) {
298 3
299 3
		$isRootSpecified = $rootHash !== '';
300 3
301
		$root = new TreeNode();
302 3
		if ( $isRootSpecified ) {
303
			$root->addChild( $nodes[$rootHash] );
304
		}
305
306
		$store = $this->getQueryResult()->getStore();
307
		$parentPointerProperty = DIProperty::newFromUserLabel( $this->params['parent'] );
308
309
		foreach ( $nodes as $hash => $node ) {
310 5
311
			$parents = $store->getPropertyValues(
312 5
				$node->getResultSubject(),
313
				$parentPointerProperty
314 5
			);
315 5
316 1
			if ( empty( $parents ) && !$isRootSpecified ) {
317
318
				$root->addChild( $node );
319 5
320 5
			} else {
321
322 5
				foreach ( $parents as $parent ) {
323
324 5
					$parentHash = $parent->getSerialization();
325 5
326 5
					try {
327
						if ( array_key_exists( $parentHash, $nodes ) ) {
328
							$nodes[$parentHash]->addChild( $node );
329 5
						} elseif ( !$isRootSpecified ) {
330
							$root->addChild( $node );
331 5
						}
332
					}
333
					catch ( Exception $e ) {
334
						$this->addError( $e->getMessage(), $node->getResultSubject()->getTitle()->getPrefixedText() );
335 4
					}
336
				}
337 4
			}
338
		}
339
		return $root;
340 4
	}
341 4
342
	/**
343 4
	 * @param TreeNode $tree
344
	 *
345
	 * @return mixed
346 1
	 */
347 5
	protected function buildLinesFromTree( $tree ) {
348
		$nodePrinterConfiguration = [
349
			'format' => trim( $this->params['format'] ),
350
			'template' => trim( $this->params['template'] ),
351
			'headers' => $this->params['headers'],
352 5
			'named args' => $this->params['named args'],
353
			'sep' => $this->params['sep'],
354
		];
355
356
		$visitor = new TreeNodePrinter( $this, $nodePrinterConfiguration );
357
		$lines = $tree->accept( $visitor );
358
		return $lines;
359
	}
360 5
361
	/**
362 5
	 * @param string $msgkey
363 5
	 * @param string | string[] $params
364 5
	 */
365 5
	protected function addError( $msgkey, $params = [] ) {
366 5
367
		parent::addError(
368
			\Message::newFromKey( $msgkey )
369 5
				->params( $params )
370 5
				->inContentLanguage()->text()
371 5
		);
372
	}
373
374
}
375
376