Completed
Push — master ( ea0e5d...10ff2a )
by mw
02:37
created

formats/graphviz/SRF_Graph.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
/**
4
 * SMW result printer for graphs using graphViz.
5
 * In order to use this printer you need to have both
6
 * the graphViz library installed on your system and
7
 * have the graphViz MediaWiki extension installed.
8
 * 
9
 * @file SRF_Graph.php
10
 * @ingroup SemanticResultFormats
11
 *
12
 * @licence GNU GPL v2+
13
 * @author Frank Dengler
14
 * @author Jeroen De Dauw < [email protected] >
15
 */
16
class SRFGraph extends SMWResultPrinter {
17
	
18
	public static $NODE_SHAPES = array(
19
		'box',
20
		'box3d',
21
		'circle',
22
		'component',
23
		'diamond',
24
		'doublecircle',
25
		'doubleoctagon',
26
		'egg',
27
		'ellipse',
28
		'folder',
29
		'hexagon',
30
		'house',
31
		'invhouse',
32
		'invtrapezium',
33
		'invtriangle',
34
		'Mcircle',
35
		'Mdiamond',
36
		'Msquare',
37
		'none',
38
		'note',
39
		'octagon',
40
		'parallelogram',
41
		'pentagon ',
42
		'plaintext',
43
		'point',
44
		'polygon',
45
		'rect',
46
		'rectangle',
47
		'septagon',
48
		'square',
49
		'tab',
50
		'trapezium',
51
		'triangle',
52
		'tripleoctagon',
53
	);
54
	
55
	protected $m_graphName;
56
	protected $m_graphLabel;
57
	protected $m_graphColor;
58
	protected $m_graphLegend;
59
	protected $m_graphLink;
60
	protected $m_rankdir;
61
	protected $m_graphSize;
62
	protected $m_labelArray = array();
63
	protected $m_graphColors = array( 'black', 'red', 'green', 'blue', 'darkviolet', 'gold', 'deeppink', 'brown', 'bisque', 'darkgreen', 'yellow', 'darkblue', 'magenta', 'steelblue2' );
64
	protected $m_nameProperty;
65
	protected $m_nodeShape;
66
	protected $m_parentRelation;
67
	protected $m_wordWrapLimit;
68
	
69
	/**
70
	 * (non-PHPdoc)
71
	 * @see SMWResultPrinter::handleParameters()
72
	 */
73
	protected function handleParameters( array $params, $outputmode ) {
74
		parent::handleParameters( $params, $outputmode );
75
		
76
		$this->m_graphName = trim( $params['graphname'] );
77
		$this->m_graphSize = trim( $params['graphsize'] );
78
		
79
		$this->m_graphLegend = $params['graphlegend'];
80
		$this->m_graphLabel = $params['graphlabel'];
81
		
82
		$this->m_rankdir = strtoupper( trim( $params['arrowdirection'] ) );
83
		
84
		$this->m_graphLink = $params['graphlink'];
85
		$this->m_graphColor =$params['graphcolor'];
86
		
87
		$this->m_nameProperty = $params['nameproperty'] === false ? false : trim( $params['nameproperty'] );
88
		
89
		$this->m_parentRelation = strtolower( trim( $params['relation'] ) ) == 'parent';
90
		
91
		$this->m_nodeShape = $params['nodeshape'];
92
		$this->m_wordWrapLimit = $params['wordwraplimit'];
93
	}
94
	
95
	protected function getResultText( SMWQueryResult $res, $outputmode ) {
0 ignored issues
show
getResultText uses the super-global variable $GLOBALS which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
96
		if ( !is_callable( 'GraphViz::graphvizParserHook' ) ) {
97
			wfWarn( 'The SRF Graph printer needs the GraphViz extension to be installed.' );
98
			return '';
99
		}
100
		
101
		$this->isHTML = true;
102
103
		$graphInput = "digraph $this->m_graphName {";
104
		if ( $this->m_graphSize != '' ) $graphInput .= "size=\"$this->m_graphSize\";";
105
		if ( $this->m_nodeShape ) $graphInput .=  "node [shape=$this->m_nodeShape];";
106
		$graphInput .= "rankdir=$this->m_rankdir;";		
107
		
108
		while ( $row = $res->getNext() ) {
109
			$graphInput .= $this->getGVForItem( $row, $outputmode );
110
		}
111
		
112
		$graphInput .= "}";
113
		
114
		// Calls graphvizParserHook function from MediaWiki GraphViz extension
115
		$result = GraphViz::graphvizParserHook( $graphInput, "", $GLOBALS['wgParser'] );
116
		
117
		if ( $this->m_graphLegend && $this->m_graphColor ) {
118
			$arrayCount = 0;
119
			$arraySize = count( $this->m_graphColors );
120
			$result .= "<P>";
121
			
122
			foreach ( $this->m_labelArray as $m_label ) {
123
				if ( $arrayCount >= $arraySize ) {
124
					$arrayCount = 0;
125
				}				
126
				
127
				$color = $this->m_graphColors[$arrayCount];
128
				$result .= "<font color=$color>$color: $m_label </font><br />";
129
				
130
				$arrayCount += 1;
131
			}
132
			
133
			$result .= "</P>";
134
		}
135
		
136
		return $result;
137
	}
138
139
	/**
140
	 * Returns the GV for a single subject.
141
	 * 
142
	 * @since 1.5.4
143
	 * 
144
	 * @param array $row
145
	 * @param $outputmode
146
	 * 
147
	 * @return string
148
	 */
149
	protected function getGVForItem( array /* of SMWResultArray */ $row, $outputmode ) {	
150
		$segments = array();
151
		
152
		// Loop throught all fields of the record.
153
		foreach ( $row as $i => $resultArray ) {
154
155
			// Loop throught all the parts of the field value.
156
			while ( ( $object = $resultArray->getNextDataValue() ) !== false ) {
157
				$propName = $resultArray->getPrintRequest()->getLabel();
158
				$isName = $this->m_nameProperty ? ( $i != 0 && $this->m_nameProperty === $propName ) : $i == 0;
159
				
160
				if ( $isName ) {
161
					$name = $this->getWordWrappedText( $object->getShortText( $outputmode ), $this->m_wordWrapLimit );
162
				}
163
				
164
				if ( !( $this->m_nameProperty && $i == 0 ) ) {
165
					$segments[] = $this->getGVForDataValue( $object, $outputmode, $isName, $name, $propName );
166
				}
167
			}
168
		}
169
170
		return implode( "\n", $segments );
171
	}
172
	
173
	/**
174
	 * Returns the GV for a single SMWDataValue.
175
	 * 
176
	 * @since 1.5.4
177
	 * 
178
	 * @param SMWDataValue $object
179
	 * @param $outputmode
180
	 * @param boolean $isName Is this the name that should be used for the node?
181
	 * @param string $name
182
	 * @param string $labelName
183
	 * 
184
	 * @return string
185
	 */	
186
	protected function getGVForDataValue( SMWDataValue $object, $outputmode, $isName, $name, $labelName ) {
187
		$graphInput = '';
188
		$text = $object->getShortText( $outputmode );
189
190
		if ( $this->m_graphLink ) {
191
			$nodeLinkURL = "[[" . $text . "]]";
192
		}
193
		
194
		$text = $this->getWordWrappedText( $text, $this->m_wordWrapLimit );
195
		
196
		if ( $this->m_graphLink ) {
197
			$graphInput .= " \"$text\" [URL = \"$nodeLinkURL\"]; ";
198
		}
199
200
		if ( !$isName ) {
201
			$graphInput .= $this->m_parentRelation ? " \"$text\" -> \"$name\" " : " \"$name\" -> \"$text\" ";
202
			
203
			if ( $this->m_graphLabel || $this->m_graphColor ) {
204
				$graphInput .= ' [';
205
206
				if ( array_search( $labelName, $this->m_labelArray, true ) === false ) {
207
					$this->m_labelArray[] = $labelName;
208
				}
209
				
210
				$color = $this->m_graphColors[array_search( $labelName, $this->m_labelArray, true )];
211
212
				if ( $this->m_graphLabel ) {
213
					$graphInput .= "label=\"$labelName\"";
214
					if ( $this->m_graphColor ) $graphInput .= ",fontcolor=$color,";
215
				}
216
				
217
				if ( $this->m_graphColor ) {
218
					$graphInput .= "color=$color";
219
				}
220
				
221
				$graphInput .= ']';
222
	
223
			}
224
			
225
			$graphInput .= ';';
226
		}
227
228
		return $graphInput;
229
	}
230
	
231
	/**
232
	 * Returns the word wrapped version of the provided text. 
233
	 * 
234
	 * @since 1.5.4
235
	 * 
236
	 * @param string $text
237
	 * @param integer $charLimit
238
	 * 
239
	 * @return string
240
	 */
241
	protected function getWordWrappedText( $text, $charLimit ) {
242
		$charLimit = max( array( $charLimit, 1 ) );
243
		$segments = array();
244
		
245
		while ( strlen( $text ) > $charLimit ) {
246
			// Find the last space in the allowed range.
247
			$splitPosition = strrpos( substr( $text, 0, $charLimit ), ' ' );
248
			
249
			if ( $splitPosition === false ) {
250
				// If there is no space (lond word), find the next space.
251
				$splitPosition = strpos( $text, ' ' );
252
				
253
				if ( $splitPosition === false ) {
254
					// If there are no spaces, everything goes on one line.
255
					 $splitPosition = strlen( $text ) - 1;
256
				}
257
			}
258
			
259
			$segments[] = substr( $text, 0, $splitPosition + 1 );
260
			$text = substr( $text, $splitPosition + 1 );
261
		}
262
		
263
		$segments[] = $text;
264
		
265
		return implode( '\n', $segments );
266
	}
267
	
268
	/**
269
	 * (non-PHPdoc)
270
	 * @see SMWResultPrinter::getName()
271
	 */
272
	public function getName() {
273
		return wfMessage( 'srf-printername-graph' )->text();
274
	}
275
276
	/**
277
	 * @see SMWResultPrinter::getParamDefinitions
278
	 *
279
	 * @since 1.8
280
	 *
281
	 * @param $definitions array of IParamDefinition
282
	 *
283
	 * @return array of IParamDefinition|array
284
	 */
285
	public function getParamDefinitions( array $definitions ) {
286
		$params = parent::getParamDefinitions( $definitions );
287
288
		$params['graphname'] = array(
289
			'default' => 'QueryResult',
290
			'message' => 'srf_paramdesc_graphname',
291
		);
292
293
		$params['graphsize'] = array(
294
			'type' => 'string',
295
			'default' => '',
296
			'message' => 'srf_paramdesc_graphsize',
297
			'manipulatedefault' => false,
298
		);
299
300
		$params['graphlegend'] = array(
301
			'type' => 'boolean',
302
			'default' => false,
303
			'message' => 'srf_paramdesc_graphlegend',
304
		);
305
306
		$params['graphlabel'] = array(
307
			'type' => 'boolean',
308
			'default' => false,
309
			'message' => 'srf_paramdesc_graphlabel',
310
		);
311
312
		$params['graphlink'] = array(
313
			'type' => 'boolean',
314
			'default' => false,
315
			'message' => 'srf_paramdesc_graphlink',
316
		);
317
318
		$params['graphcolor'] = array(
319
			'type' => 'boolean',
320
			'default' => false,
321
			'message' => 'srf_paramdesc_graphcolor',
322
		);
323
324
		$params['arrowdirection'] = array(
325
			'aliases' => 'rankdir',
326
			'default' => 'LR',
327
			'message' => 'srf_paramdesc_rankdir',
328
			'values' => array( 'LR', 'RL', 'TB', 'BT' ),
329
		);
330
331
		$params['nodeshape'] = array(
332
			'default' => false,
333
			'message' => 'srf-paramdesc-graph-nodeshape',
334
			'manipulatedefault' => false,
335
			'values' => self::$NODE_SHAPES,
336
		);
337
338
		$params['relation'] = array(
339
			'default' => 'child',
340
			'message' => 'srf-paramdesc-graph-relation',
341
			'manipulatedefault' => false,
342
			'values' => array( 'parent', 'child' ),
343
		);
344
345
		$params['nameproperty'] = array(
346
			'default' => false,
347
			'message' => 'srf-paramdesc-graph-nameprop',
348
			'manipulatedefault' => false,
349
		);
350
351
		$params['wordwraplimit'] = array(
352
			'type' => 'integer',
353
			'default' => 25,
354
			'message' => 'srf-paramdesc-graph-wwl',
355
			'manipulatedefault' => false,
356
		);
357
		
358
		return $params;
359
	}
360
	
361
}
362