Completed
Push — master ( 4c0a47...4e7d8d )
by
unknown
17:45
created

SRFGraph::getParamDefinitions()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 75

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 75
ccs 0
cts 17
cp 0
rs 8.5454
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 2

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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 = [
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 = [];
63
	protected $m_graphColors = [ '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
Coding Style introduced by
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
97
		if ( !class_exists( 'GraphViz' )
98
			&& !class_exists( '\\MediaWiki\\Extension\\GraphViz\\GraphViz' )
99
		) {
100
			wfWarn( 'The SRF Graph printer needs the GraphViz extension to be installed.' );
101
			return '';
102
		}
103
		
104
		$this->isHTML = true;
105
106
		$graphInput = "digraph $this->m_graphName {";
107
		if ( $this->m_graphSize != '' ) $graphInput .= "size=\"$this->m_graphSize\";";
108
		if ( $this->m_nodeShape ) $graphInput .=  "node [shape=$this->m_nodeShape];";
109
		$graphInput .= "rankdir=$this->m_rankdir;";		
110
		
111
		while ( $row = $res->getNext() ) {
112
			$graphInput .= $this->getGVForItem( $row, $outputmode );
113
		}
114
		
115
		$graphInput .= "}";
116
		
117
		// Calls graphvizParserHook function from MediaWiki GraphViz extension
118
		$result = $GLOBALS['wgParser']->recursiveTagParse( "<graphviz>$graphInput</graphviz>" );
119
		
120
		if ( $this->m_graphLegend && $this->m_graphColor ) {
121
			$arrayCount = 0;
122
			$arraySize = count( $this->m_graphColors );
123
			$result .= "<P>";
124
			
125
			foreach ( $this->m_labelArray as $m_label ) {
126
				if ( $arrayCount >= $arraySize ) {
127
					$arrayCount = 0;
128
				}				
129
				
130
				$color = $this->m_graphColors[$arrayCount];
131
				$result .= "<font color=$color>$color: $m_label </font><br />";
132
				
133
				$arrayCount += 1;
134
			}
135
			
136
			$result .= "</P>";
137
		}
138
		
139
		return $result;
140
	}
141
142
	/**
143
	 * Returns the GV for a single subject.
144
	 * 
145
	 * @since 1.5.4
146
	 * 
147
	 * @param array $row
148
	 * @param $outputmode
149
	 * 
150
	 * @return string
151
	 */
152
	protected function getGVForItem( array /* of SMWResultArray */ $row, $outputmode ) {	
153
		$segments = [];
154
		
155
		// Loop throught all fields of the record.
156
		foreach ( $row as $i => $resultArray ) {
157
158
			// Loop throught all the parts of the field value.
159
			while ( ( $object = $resultArray->getNextDataValue() ) !== false ) {
160
				$propName = $resultArray->getPrintRequest()->getLabel();
161
				$isName = $this->m_nameProperty ? ( $i != 0 && $this->m_nameProperty === $propName ) : $i == 0;
162
				
163
				if ( $isName ) {
164
					$name = $this->getWordWrappedText( $object->getShortText( $outputmode ), $this->m_wordWrapLimit );
165
				}
166
				
167
				if ( !( $this->m_nameProperty && $i == 0 ) ) {
168
					$segments[] = $this->getGVForDataValue( $object, $outputmode, $isName, $name, $propName );
0 ignored issues
show
Bug introduced by
The variable $name does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
169
				}
170
			}
171
		}
172
173
		return implode( "\n", $segments );
174
	}
175
	
176
	/**
177
	 * Returns the GV for a single SMWDataValue.
178
	 * 
179
	 * @since 1.5.4
180
	 * 
181
	 * @param SMWDataValue $object
182
	 * @param $outputmode
183
	 * @param boolean $isName Is this the name that should be used for the node?
184
	 * @param string $name
185
	 * @param string $labelName
186
	 * 
187
	 * @return string
188
	 */	
189
	protected function getGVForDataValue( SMWDataValue $object, $outputmode, $isName, $name, $labelName ) {
190
		$graphInput = '';
191
		$text = $object->getShortText( $outputmode );
192
193
		if ( $this->m_graphLink ) {
194
			$nodeLinkURL = "[[" . $text . "]]";
195
		}
196
		
197
		$text = $this->getWordWrappedText( $text, $this->m_wordWrapLimit );
198
		
199
		if ( $this->m_graphLink ) {
200
			$graphInput .= " \"$text\" [URL = \"$nodeLinkURL\"]; ";
0 ignored issues
show
Bug introduced by
The variable $nodeLinkURL does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
201
		}
202
203
		if ( !$isName ) {
204
			$graphInput .= $this->m_parentRelation ? " \"$text\" -> \"$name\" " : " \"$name\" -> \"$text\" ";
205
			
206
			if ( $this->m_graphLabel || $this->m_graphColor ) {
207
				$graphInput .= ' [';
208
209
				if ( array_search( $labelName, $this->m_labelArray, true ) === false ) {
210
					$this->m_labelArray[] = $labelName;
211
				}
212
				
213
				$color = $this->m_graphColors[array_search( $labelName, $this->m_labelArray, true )];
214
215
				if ( $this->m_graphLabel ) {
216
					$graphInput .= "label=\"$labelName\"";
217
					if ( $this->m_graphColor ) $graphInput .= ",fontcolor=$color,";
218
				}
219
				
220
				if ( $this->m_graphColor ) {
221
					$graphInput .= "color=$color";
222
				}
223
				
224
				$graphInput .= ']';
225
	
226
			}
227
			
228
			$graphInput .= ';';
229
		}
230
231
		return $graphInput;
232
	}
233
	
234
	/**
235
	 * Returns the word wrapped version of the provided text. 
236
	 * 
237
	 * @since 1.5.4
238
	 * 
239
	 * @param string $text
240
	 * @param integer $charLimit
241
	 * 
242
	 * @return string
243
	 */
244
	protected function getWordWrappedText( $text, $charLimit ) {
245
		$charLimit = max( [ $charLimit, 1 ] );
246
		$segments = [];
247
		
248
		while ( strlen( $text ) > $charLimit ) {
249
			// Find the last space in the allowed range.
250
			$splitPosition = strrpos( substr( $text, 0, $charLimit ), ' ' );
251
			
252
			if ( $splitPosition === false ) {
253
				// If there is no space (lond word), find the next space.
254
				$splitPosition = strpos( $text, ' ' );
255
				
256
				if ( $splitPosition === false ) {
257
					// If there are no spaces, everything goes on one line.
258
					 $splitPosition = strlen( $text ) - 1;
259
				}
260
			}
261
			
262
			$segments[] = substr( $text, 0, $splitPosition + 1 );
263
			$text = substr( $text, $splitPosition + 1 );
264
		}
265
		
266
		$segments[] = $text;
267
		
268
		return implode( '\n', $segments );
269
	}
270
	
271
	/**
272
	 * (non-PHPdoc)
273
	 * @see SMWResultPrinter::getName()
274
	 */
275
	public function getName() {
276
		return wfMessage( 'srf-printername-graph' )->text();
277
	}
278
279
	/**
280
	 * @see SMWResultPrinter::getParamDefinitions
281
	 *
282
	 * @since 1.8
283
	 *
284
	 * @param $definitions array of IParamDefinition
285
	 *
286
	 * @return array of IParamDefinition|array
287
	 */
288
	public function getParamDefinitions( array $definitions ) {
289
		$params = parent::getParamDefinitions( $definitions );
290
291
		$params['graphname'] = [
292
			'default' => 'QueryResult',
293
			'message' => 'srf-paramdesc-graphname',
294
		];
295
296
		$params['graphsize'] = [
297
			'type' => 'string',
298
			'default' => '',
299
			'message' => 'srf-paramdesc-graphsize',
300
			'manipulatedefault' => false,
301
		];
302
303
		$params['graphlegend'] = [
304
			'type' => 'boolean',
305
			'default' => false,
306
			'message' => 'srf-paramdesc-graphlegend',
307
		];
308
309
		$params['graphlabel'] = [
310
			'type' => 'boolean',
311
			'default' => false,
312
			'message' => 'srf-paramdesc-graphlabel',
313
		];
314
315
		$params['graphlink'] = [
316
			'type' => 'boolean',
317
			'default' => false,
318
			'message' => 'srf-paramdesc-graphlink',
319
		];
320
321
		$params['graphcolor'] = [
322
			'type' => 'boolean',
323
			'default' => false,
324
			'message' => 'srf-paramdesc-graphcolor',
325
		];
326
327
		$params['arrowdirection'] = [
328
			'aliases' => 'rankdir',
329
			'default' => 'LR',
330
			'message' => 'srf-paramdesc-rankdir',
331
			'values' => [ 'LR', 'RL', 'TB', 'BT' ],
332
		];
333
334
		$params['nodeshape'] = [
335
			'default' => false,
336
			'message' => 'srf-paramdesc-graph-nodeshape',
337
			'manipulatedefault' => false,
338
			'values' => self::$NODE_SHAPES,
339
		];
340
341
		$params['relation'] = [
342
			'default' => 'child',
343
			'message' => 'srf-paramdesc-graph-relation',
344
			'manipulatedefault' => false,
345
			'values' => [ 'parent', 'child' ],
346
		];
347
348
		$params['nameproperty'] = [
349
			'default' => false,
350
			'message' => 'srf-paramdesc-graph-nameprop',
351
			'manipulatedefault' => false,
352
		];
353
354
		$params['wordwraplimit'] = [
355
			'type' => 'integer',
356
			'default' => 25,
357
			'message' => 'srf-paramdesc-graph-wwl',
358
			'manipulatedefault' => false,
359
		];
360
		
361
		return $params;
362
	}
363
	
364
}
365