Completed
Pull Request — master (#550)
by
unknown
16:41
created

GraphPrinter   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 257
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 3

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 15
lcom 2
cbo 3
dl 0
loc 257
ccs 0
cts 57
cp 0
rs 10
c 0
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
A getName() 0 3 1
A handleParameters() 0 5 1
A hasMissingDependency() 0 3 2
A getDependencyError() 0 9 1
A getResultText() 0 25 3
B processResultRow() 0 22 6
B getParamDefinitions() 0 81 1
1
<?php
2
3
namespace SRF\Graph;
4
5
use SMW\ResultPrinter;
6
use SMWQueryResult;
7
use SMWWikiPageValue;
8
use GraphViz;
9
use Html;
10
11
/**
12
 * SMW result printer for graphs using graphViz.
13
 * In order to use this printer you need to have both
14
 * the graphViz library installed on your system and
15
 * have the graphViz MediaWiki extension installed.
16
 *
17
 * @file SRF_Graph.php
18
 * @ingroup SemanticResultFormats
19
 *
20
 * @licence GNU GPL v2+
21
 * @author Frank Dengler
22
 * @author Jeroen De Dauw < [email protected] >
23
 * @author Sebastian Schmid
24
 */
25
class GraphPrinter extends ResultPrinter {
26
27
	//@see https://github.com/SemanticMediaWiki/SemanticMediaWiki/pull/4273
28
	// Implement `ResultPrinterDependency` once SMW 3.1 becomes mandatory
29
30
	const NODELABEL_DISPLAYTITLE = 'displaytitle';
31
	public static $NODE_LABELS = [
32
		self::NODELABEL_DISPLAYTITLE,
33
	];
34
35
	public static $NODE_SHAPES = [
36
		'box',
37
		'box3d',
38
		'circle',
39
		'component',
40
		'diamond',
41
		'doublecircle',
42
		'doubleoctagon',
43
		'egg',
44
		'ellipse',
45
		'folder',
46
		'hexagon',
47
		'house',
48
		'invhouse',
49
		'invtrapezium',
50
		'invtriangle',
51
		'Mcircle',
52
		'Mdiamond',
53
		'Msquare',
54
		'Mrecord',
55
		'none',
56
		'note',
57
		'octagon',
58
		'parallelogram',
59
		'pentagon ',
60
		'plaintext',
61
		'point',
62
		'polygon',
63
		'rect',
64
		'record',
65
		'rectangle',
66
		'septagon',
67
		'square',
68
		'tab',
69
		'trapezium',
70
		'triangle',
71
		'tripleoctagon',
72
	];
73
74
	public static $ARROW_SHAPES = [
75
		'box',
76
		'crow',
77
		'curve',
78
		'icurve',
79
		'diamond',
80
		'dot',
81
		'inv',
82
		'none',
83
		'normal',
84
		'tee',
85
		'vee',
86
	];
87
88
	private $nodes = [];
89
	private $options;
90
91
	public function getName() {
92
		return $this->msg( 'srf-printername-graph' )->text();
93
	}
94
95
	/**
96
	 * @see SMWResultPrinter::handleParameters()
97
	 */
98
	protected function handleParameters( array $params, $outputmode ) {
99
		parent::handleParameters( $params, $outputmode );
100
101
		$this->options = new GraphOptions($params);
102
	}
103
104
	/**
105
	 * @see ResultPrinterDependency::hasMissingDependency
106
	 *
107
	 * {@inheritDoc}
108
	 */
109
	public function hasMissingDependency() {
110
		return !class_exists( 'GraphViz' ) && !class_exists( '\\MediaWiki\\Extension\\GraphViz\\GraphViz' );
111
	}
112
113
	/**
114
	 * @see ResultPrinterDependency::getDependencyError
115
	 *
116
	 * {@inheritDoc}
117
	 */
118
	public function getDependencyError() {
119
		return Html::rawElement(
120
			'div',
121
			[
122
				'class' => 'smw-callout smw-callout-error'
123
			],
124
			'The SRF Graph printer requires the GraphViz extension to be installed.'
125
		);
126
	}
127
128
	/**
129
	 * @param SMWQueryResult $res
130
	 * @param $outputmode
131
	 *
132
	 * @return string
133
	 */
134
	protected function getResultText( SMWQueryResult $res, $outputmode ) {
135
136
		// Remove this once SRF requires 3.1+
137
		if ( $this->hasMissingDependency() ) {
138
			return $this->getDependencyError();
139
		}
140
141
		// iterate query result and create SRF\GraphNodes
142
		while ( $row = $res->getNext() ) {
143
			$this->processResultRow( $row );
144
		}
145
146
		// use GraphFormater to build the graph
147
		$graphFormatter = new GraphFormatter( $this->options );
148
		$graphFormatter->buildGraph( $this->nodes );
149
150
		// Calls graphvizParserHook function from MediaWiki GraphViz extension
151
		$result = $GLOBALS['wgParser']->recursiveTagParse( "<graphviz>" . $graphFormatter->getGraph
152
				() . "</graphviz>" );
153
154
		// append legend
155
		$result .= $graphFormatter->getGraphLegend();
156
157
		return $result;
158
	}
159
160
	/**
161
	 * Process a result row and create SRF\GraphNodes
162
	 *
163
	 * @since 3.1
164
	 *
165
	 * @param array $row
166
	 *
167
	 */
168
	protected function processResultRow( array /* of SMWResultArray */ $row ) {
169
170
		// loop through all row fields
171
		foreach ( $row as $i => $resultArray ) {
172
173
			// loop through all values of a multivalue field
174
			while ( ( $dataValue = $resultArray->getNextDataValue() ) !== false ) {
175
176
				// create SRF\GraphNode for column 0
177
				if ( $i == 0 && $dataValue->getShortWikiText() !== '' ) {
178
					$node = new GraphNode( $dataValue->getShortWikiText() );
179
					$node->setLabel( $dataValue->getPreferredCaption() );
180
					$this->nodes[] = $node;
181
				} else {
182
					if ( !empty( $node ) ) {
183
						$node->addParentNode( $resultArray->getPrintRequest()->getLabel(),
184
							$dataValue->getShortWikiText() );
185
					}
186
				}
187
			}
188
		}
189
	}
190
191
	/**
192
	 * @see SMWResultPrinter::getParamDefinitions
193
	 *
194
	 * @since 1.8
195
	 *
196
	 * @param $definitions array of IParamDefinition
197
	 *
198
	 * @return array of IParamDefinition|array
199
	 */
200
	public function getParamDefinitions( array $definitions ) {
201
		$params = parent::getParamDefinitions( $definitions );
202
203
		$params['graphname'] = [
204
			'default' => 'QueryResult',
205
			'message' => 'srf-paramdesc-graphname',
206
		];
207
208
		$params['graphsize'] = [
209
			'type' => 'string',
210
			'default' => '',
211
			'message' => 'srf-paramdesc-graphsize',
212
			'manipulatedefault' => false,
213
		];
214
215
		$params['graphlegend'] = [
216
			'type' => 'boolean',
217
			'default' => false,
218
			'message' => 'srf-paramdesc-graphlegend',
219
		];
220
221
		$params['graphlabel'] = [
222
			'type' => 'boolean',
223
			'default' => false,
224
			'message' => 'srf-paramdesc-graphlabel',
225
		];
226
227
		$params['graphlink'] = [
228
			'type' => 'boolean',
229
			'default' => false,
230
			'message' => 'srf-paramdesc-graphlink',
231
		];
232
233
		$params['graphcolor'] = [
234
			'type' => 'boolean',
235
			'default' => false,
236
			'message' => 'srf-paramdesc-graphcolor',
237
		];
238
239
		$params['arrowdirection'] = [
240
			'aliases' => 'rankdir',
241
			'default' => 'LR',
242
			'message' => 'srf-paramdesc-rankdir',
243
			'values'  => [ 'LR', 'RL', 'TB', 'BT' ],
244
		];
245
246
		$params['arrowhead'] = [
247
			'default' => 'normal',
248
			'message' => 'srf-paramdesc-arrowhead',
249
			'values' => self::$ARROW_SHAPES,
250
		];
251
252
		$params['nodeshape'] = [
253
			'default' => false,
254
			'message' => 'srf-paramdesc-graph-nodeshape',
255
			'manipulatedefault' => false,
256
			'values' => self::$NODE_SHAPES,
257
		];
258
259
		$params['relation'] = [
260
			'default' => 'child',
261
			'message' => 'srf-paramdesc-graph-relation',
262
			'manipulatedefault' => false,
263
			'values' => [ 'parent', 'child' ],
264
		];
265
266
		$params['wordwraplimit'] = [
267
			'type' => 'integer',
268
			'default' => 25,
269
			'message' => 'srf-paramdesc-graph-wwl',
270
			'manipulatedefault' => false,
271
		];
272
273
		$params['nodelabel'] = [
274
			'default' => '',
275
			'message' => 'srf-paramdesc-nodelabel',
276
			'values' => self::$NODE_LABELS,
277
		];
278
279
		return $params;
280
	}
281
}
282