SRFD3Chart::getName()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 3
ccs 0
cts 3
cp 0
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
crap 2
1
<?php
2
3
/**
4
 * A query printer for D3 charts using the D3 JavaScript library
5
 * and SMWAggregatablePrinter.
6
 *
7
 * @file SRF_D3Chart.php
8
 * @ingroup SemanticResultFormats
9
 * @licence GNU GPL v2 or later
10
 *
11
 * @since 1.8
12
 *
13
 * @author mwjames
14
 */
15
class SRFD3Chart extends SMWAggregatablePrinter {
16
17
	/*
18
	 * @see SMWResultPrinter::getName
19
	 *
20
	 */
21
	public function getName() {
22
		return wfMessage( 'srf-printername-d3chart' )->text();
23
	}
24
25
	/**
26
	 * @see SMWResultPrinter::getFormatOutput
27
	 *
28
	 * @since 1.8
29
	 *
30
	 * @param array $data label => value
31
	 *
32
	 * @return string
33
	 */
34
	protected function getFormatOutput( array $data ) {
35
36
		// Object count
37
		static $statNr = 0;
38
		$d3chartID = 'd3-chart-' . ++$statNr;
39
40
		$this->isHTML = true;
41
42
		// Reorganize the raw data
43
		foreach ( $data as $name => $value ) {
44
			if ( $value >= $this->params['min'] ) {
45
				$dataObject[] = [ 'label' => $name, 'value' => $value ];
0 ignored issues
show
Coding Style Comprehensibility introduced by mwjames
$dataObject was never initialized. Although not strictly required by PHP, it is generally a good practice to add $dataObject = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
46
			}
47
		}
48
49
		// Ensure right conversion
50
		$width = strstr( $this->params['width'], "%" ) ? $this->params['width'] : $this->params['width'] . 'px';
51
52
		// Prepare transfer objects
53
		$d3data = [
54
			'data' => $dataObject,
0 ignored issues
show
Bug introduced by mwjames
The variable $dataObject 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...
55
			'parameters' => [
56
				'colorscheme' => $this->params['colorscheme'] ? $this->params['colorscheme'] : null,
57
				'charttitle' => $this->params['charttitle'],
58
				'charttext' => $this->params['charttext'],
59
				'datalabels' => $this->params['datalabels']
60
			]
61
		];
62
63
		// Encoding
64
		$requireHeadItem = [ $d3chartID => FormatJson::encode( $d3data ) ];
65
		SMWOutputs::requireHeadItem( $d3chartID, Skin::makeVariablesScript( $requireHeadItem ) );
66
67
		// RL module
68
		$resource = 'ext.srf.d3.chart.' . $this->params['charttype'];
69
		SMWOutputs::requireResource( $resource );
70
71
		// Chart/graph placeholder
72
		$chart = Html::rawElement(
73
			'div',
74
			[
75
				'id' => $d3chartID,
76
				'class' => 'container',
77
				'style' => 'display:none;'
78
			],
79
			null
80
		);
81
82
		// Processing placeholder
83
		$processing = SRFUtils::htmlProcessingElement( $this->isHTML );
84
85
		// Beautify class selector
86
		$class = $this->params['charttype'] ? '-' . $this->params['charttype'] : '';
87
		$class = $this->params['class'] ? $class . ' ' . $this->params['class'] : $class . ' d3-chart-common';
88
89
		// D3 wrappper
90
		return Html::rawElement(
91
			'div',
92
			[
93
				'class' => 'srf-d3-chart' . $class,
94
				'style' => "width:{$width}; height:{$this->params['height']}px;"
95
			],
96
			$processing . $chart
97
		);
98
	}
99
100
	/**
101
	 * @see SMWResultPrinter::getParamDefinitions
102
	 *
103
	 * @since 1.8
104
	 *
105
	 * @param $definitions array of IParamDefinition
106
	 *
107
	 * @return array of IParamDefinition|array
108
	 */
109
	public function getParamDefinitions( array $definitions ) {
110
		$params = parent::getParamDefinitions( $definitions );
111
112
		$params['min'] = [
113
			'type' => 'integer',
114
			'message' => 'srf-paramdesc-minvalue',
115
			'default' => false,
116
			'manipulatedefault' => false,
117
		];
118
119
		$params['charttype'] = [
120
			'message' => 'srf-paramdesc-charttype',
121
			'default' => 'treemap',
122
			'values' => [ 'treemap', 'bubble' ],
123
		];
124
125
		$params['height'] = [
126
			'type' => 'integer',
127
			'message' => 'srf_paramdesc_chartheight',
128
			'default' => 400,
129
			'lowerbound' => 1,
130
		];
131
132
		$params['width'] = [
133
			'message' => 'srf_paramdesc_chartwidth',
134
			'default' => '100%',
135
		];
136
137
		$params['charttitle'] = [
138
			'message' => 'srf_paramdesc_charttitle',
139
			'default' => '',
140
		];
141
142
		$params['charttext'] = [
143
			'message' => 'srf-paramdesc-charttext',
144
			'default' => '',
145
		];
146
147
		$params['class'] = [
148
			'message' => 'srf-paramdesc-class',
149
			'default' => '',
150
		];
151
152
		$params['datalabels'] = [
153
			'message' => 'srf-paramdesc-datalabels',
154
			'default' => 'none',
155
			'values' => [ 'value', 'label' ],
156
		];
157
158
		$params['colorscheme'] = [
159
			'message' => 'srf-paramdesc-colorscheme',
160
			'default' => '',
161
			'values' => $GLOBALS['srfgColorScheme'],
162
		];
163
164
		$params['chartcolor'] = [
165
			'message' => 'srf-paramdesc-chartcolor',
166
			'default' => '',
167
		];
168
169
		return $params;
170
	}
171
}
172