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

SRFOutline::getParamDefinitions()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 11
ccs 0
cts 9
cp 0
rs 9.9
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 2
1
<?php
2
3
/**
4
 * A class to print query results in an outline format, along with some
5
 * helper classes to handle the aggregation
6
 */
7
8
/**
9
 * Represents a single item, or page, in the outline - contains both the
10
 * SMWResultArray and an array of some of its values, for easier aggregation
11
 */
12
class SRFOutlineItem {
13
	var $mRow;
14
	var $mVals;
15
16
	function __construct( $row ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
Comprehensibility Best Practice introduced by
It is recommend to declare an explicit visibility for __construct.

Generally, we recommend to declare visibility for all methods in your source code. This has the advantage of clearly communication to other developers, and also yourself, how this method should be consumed.

If you are not sure which visibility to choose, it is a good idea to start with the most restrictive visibility, and then raise visibility as needed, i.e. start with private, and only raise it to protected if a sub-class needs to have access, or public if an external class needs access.

Loading history...
17
		$this->mRow = $row;
18
		$this->mVals = [];
19
	}
20
21
	function addFieldValue( $field_name, $field_val ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
Comprehensibility Best Practice introduced by
It is recommend to declare an explicit visibility for addFieldValue.

Generally, we recommend to declare visibility for all methods in your source code. This has the advantage of clearly communication to other developers, and also yourself, how this method should be consumed.

If you are not sure which visibility to choose, it is a good idea to start with the most restrictive visibility, and then raise visibility as needed, i.e. start with private, and only raise it to protected if a sub-class needs to have access, or public if an external class needs access.

Loading history...
22
		if ( array_key_exists( $field_name, $this->mVals ) ) {
23
			$this->mVals[$field_name][] = $field_val;
24
		} else {
25
			$this->mVals[$field_name] = [ $field_val ];
26
		}
27
	}
28
29
	function getFieldValues( $field_name ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
Comprehensibility Best Practice introduced by
It is recommend to declare an explicit visibility for getFieldValues.

Generally, we recommend to declare visibility for all methods in your source code. This has the advantage of clearly communication to other developers, and also yourself, how this method should be consumed.

If you are not sure which visibility to choose, it is a good idea to start with the most restrictive visibility, and then raise visibility as needed, i.e. start with private, and only raise it to protected if a sub-class needs to have access, or public if an external class needs access.

Loading history...
30
		if ( array_key_exists( $field_name, $this->mVals ) )
31
			return $this->mVals[$field_name];
32
		else {
33
			return [ wfMessage( 'srf_outline_novalue' )->text() ];
34
		}
35
	}
36
}
37
38
/**
39
 * A tree structure for holding the outline data
40
 */
41
class SRFOutlineTree {
42
	var $mTree;
43
	var $mUnsortedItems;
44
45
	function __construct( $items = [] ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
Comprehensibility Best Practice introduced by
It is recommend to declare an explicit visibility for __construct.

Generally, we recommend to declare visibility for all methods in your source code. This has the advantage of clearly communication to other developers, and also yourself, how this method should be consumed.

If you are not sure which visibility to choose, it is a good idea to start with the most restrictive visibility, and then raise visibility as needed, i.e. start with private, and only raise it to protected if a sub-class needs to have access, or public if an external class needs access.

Loading history...
46
		$this->mTree = [];
47
		$this->mUnsortedItems = $items;
48
	}
49
50
	function addItem( $item ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
Comprehensibility Best Practice introduced by
It is recommend to declare an explicit visibility for addItem.

Generally, we recommend to declare visibility for all methods in your source code. This has the advantage of clearly communication to other developers, and also yourself, how this method should be consumed.

If you are not sure which visibility to choose, it is a good idea to start with the most restrictive visibility, and then raise visibility as needed, i.e. start with private, and only raise it to protected if a sub-class needs to have access, or public if an external class needs access.

Loading history...
51
		$this->mUnsortedItems[] = $item;
52
	}
53
54
	function categorizeItem( $vals, $item ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
Comprehensibility Best Practice introduced by
It is recommend to declare an explicit visibility for categorizeItem.

Generally, we recommend to declare visibility for all methods in your source code. This has the advantage of clearly communication to other developers, and also yourself, how this method should be consumed.

If you are not sure which visibility to choose, it is a good idea to start with the most restrictive visibility, and then raise visibility as needed, i.e. start with private, and only raise it to protected if a sub-class needs to have access, or public if an external class needs access.

Loading history...
55
		foreach ( $vals as $val ) {
56
			if ( array_key_exists( $val, $this->mTree ) ) {
57
				$this->mTree[$val]->mUnsortedItems[] = $item;
58
			} else {
59
				$this->mTree[$val] = new SRFOutlineTree( [ $item ] );
60
			}
61
		}
62
	}
63
64
	function addProperty( $property ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
Comprehensibility Best Practice introduced by
It is recommend to declare an explicit visibility for addProperty.

Generally, we recommend to declare visibility for all methods in your source code. This has the advantage of clearly communication to other developers, and also yourself, how this method should be consumed.

If you are not sure which visibility to choose, it is a good idea to start with the most restrictive visibility, and then raise visibility as needed, i.e. start with private, and only raise it to protected if a sub-class needs to have access, or public if an external class needs access.

Loading history...
65
		if ( count( $this->mUnsortedItems ) > 0 ) {
66
			foreach ( $this->mUnsortedItems as $item ) {
67
				$cur_vals = $item->getFieldValues( $property );
68
				$this->categorizeItem( $cur_vals, $item );
69
			}
70
			$this->mUnsortedItems = null;
71
		} else {
72
			foreach ( $this->mTree as $i => $node ) {
73
				$this->mTree[$i]->addProperty( $property );
74
			}
75
		}
76
	}
77
}
78
79
class SRFOutline extends SMWResultPrinter {
80
	protected $mOutlineProperties = [];
81
	protected $mInnerFormat = '';
82
83
	protected function handleParameters( array $params, $outputmode ) {
84
		parent::handleParameters( $params, $outputmode );
85
		$this->mOutlineProperties = $params['outlineproperties'];
86
	}
87
88
	public function getName() {
89
		return wfMessage( 'srf_printername_outline' )->text();
90
	}
91
92
	/**
93
	 * Code mostly copied from SMW's SMWListResultPrinter::getResultText()
94
	 */
95
	function printItem( $item ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
Comprehensibility Best Practice introduced by
It is recommend to declare an explicit visibility for printItem.

Generally, we recommend to declare visibility for all methods in your source code. This has the advantage of clearly communication to other developers, and also yourself, how this method should be consumed.

If you are not sure which visibility to choose, it is a good idea to start with the most restrictive visibility, and then raise visibility as needed, i.e. start with private, and only raise it to protected if a sub-class needs to have access, or public if an external class needs access.

Loading history...
96
		$first_col = true;
97
		$found_values = false; // has anything but the first column been printed?
98
		$result = "";
99
		foreach ( $item->mRow as $orig_ra ) {
100
			// handling is somewhat simpler for SMW 1.5+
101
			$realFunction = [ 'SMWQueryResult', 'getResults' ];
102
			if ( is_callable( $realFunction ) ) {
103
				// make a new copy of this, so that the call to
104
				// getNextText() will work again
105
				$ra = clone ( $orig_ra );
106
			} else {
107
				// make a new copy of this, so that the call to
108
				// getNextText() will work again
109
				$ra = new SMWResultArray( $orig_ra->getContent(), $orig_ra->getPrintRequest() );
0 ignored issues
show
Bug introduced by
The call to SMWResultArray::__construct() misses a required argument $store.

This check looks for function calls that miss required arguments.

Loading history...
110
			}
111
			$val = $ra->getPrintRequest()->getText( SMW_OUTPUT_WIKI, null );
112
			if ( in_array( $val, $this->mOutlineProperties ) ) {
113
				continue;
114
			}
115
			$first_value = true;
116
			while ( ( $text = $ra->getNextText( SMW_OUTPUT_WIKI, $this->mLinker ) ) !== false ) {
117
				if ( !$first_col && !$found_values ) { // first values after first column
118
					$result .= ' (';
119
					$found_values = true;
120
				} elseif ( $found_values || !$first_value ) {
121
				// any value after '(' or non-first values on first column
122
					$result .= ', ';
123
				}
124
				if ( $first_value ) { // first value in any column, print header
125
					$first_value = false;
126
					if ( $this->mShowHeaders && ( '' != $ra->getPrintRequest()->getLabel() ) ) {
127
						$result .= $ra->getPrintRequest()->getText( SMW_OUTPUT_WIKI, $this->mLinker ) . ' ';
128
					}
129
				}
130
				$result .= $text; // actual output value
131
			}
132
			$first_col = false;
133
		}
134
		if ( $found_values ) $result .= ')';
135
		return $result;
136
	}
137
138
	function printTree( $outline_tree, $level = 0 ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
Comprehensibility Best Practice introduced by
It is recommend to declare an explicit visibility for printTree.

Generally, we recommend to declare visibility for all methods in your source code. This has the advantage of clearly communication to other developers, and also yourself, how this method should be consumed.

If you are not sure which visibility to choose, it is a good idea to start with the most restrictive visibility, and then raise visibility as needed, i.e. start with private, and only raise it to protected if a sub-class needs to have access, or public if an external class needs access.

Loading history...
139
		$text = "";
140
		if ( ! is_null( $outline_tree->mUnsortedItems ) ) {
141
			$text .= "<ul>\n";
142
			foreach ( $outline_tree->mUnsortedItems as $item ) {
143
				$text .= "<li>{$this->printItem($item)}</li>\n";
144
			}
145
			$text .= "</ul>\n";
146
		}
147
		if ( $level > 0 ) $text .= "<ul>\n";
148
		$num_levels = count( $this->mOutlineProperties );
149
		// set font size and weight depending on level we're at
150
		$font_level = $level;
151
		if ( $num_levels < 4 ) {
152
			$font_level += ( 4 - $num_levels );
153
		}
154
		if ( $font_level == 0 )
155
			$font_size = 'x-large';
156
		elseif ( $font_level == 1 )
157
			$font_size = 'large';
158
		elseif ( $font_level == 2 )
159
			$font_size = 'medium';
160
		else
161
			$font_size = 'small';
162
		if ( $font_level == 3 )
163
			$font_weight = 'bold';
164
		else
165
			$font_weight = 'regular';
166
		foreach ( $outline_tree->mTree as $key => $node ) {
167
			$text .= "<p style=\"font-size: $font_size; font-weight: $font_weight;\">$key</p>\n";
168
			$text .= $this->printTree( $node, $level + 1 );
169
		}
170
		if ( $level > 0 ) $text .= "</ul>\n";
171
		return $text;
172
	}
173
174
	protected function getResultText( SMWQueryResult $res, $outputmode ) {
175
		$print_fields = [];
176
		foreach ( $res->getPrintRequests() as $pr ) {
177
			$field_name = $pr->getText( $outputmode, $this->mLinker );
178
			// only print it if it's not already part of the
179
			// outline
180
			if ( ! in_array( $field_name, $this->mOutlineProperties ) ) {
181
				$print_fields[] = $field_name;
182
			}
183
		}
184
185
		// for each result row, create an array of the row itself
186
		// and all its sorted-on fields, and add it to the initial
187
		// 'tree'
188
		$outline_tree = new SRFOutlineTree();
189
		while ( $row = $res->getNext() ) {
190
			$item = new SRFOutlineItem( $row );
191
			foreach ( $row as $field ) {
192
				$first = true;
0 ignored issues
show
Unused Code introduced by
$first is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
193
				$field_name = $field->getPrintRequest()->getText( SMW_OUTPUT_HTML );
194
				if ( in_array( $field_name, $this->mOutlineProperties ) ) {
195
					while ( ( $object = $field->getNextDataValue() ) !== false ) {
196
						$field_val = $object->getLongWikiText( $this->mLinker );
197
						$item->addFieldValue( $field_name, $field_val );
198
					}
199
				}
200
			}
201
			$outline_tree->addItem( $item );
202
		}
203
204
		// now, cycle through the outline properties, creating the
205
		// tree
206
		foreach ( $this->mOutlineProperties as $outline_prop ) {
207
			$outline_tree->addProperty( $outline_prop );
208
		}
209
		$result = $this->printTree( $outline_tree );
210
211
		// print further results footer
212
		if ( $this->linkFurtherResults( $res ) ) {
213
			$link = $res->getQueryLink();
214
			if ( $this->getSearchLabel( $outputmode ) ) {
215
				$link->setCaption( $this->getSearchLabel( $outputmode ) );
216
			}
217
			$link->setParameter( 'outline', 'format' );
218
			if ( array_key_exists( 'outlineproperties', $this->m_params ) ) {
219
				$link->setParameter( $this->m_params['outlineproperties'], 'outlineproperties' );
220
			}
221
			$result .= $link->getText( $outputmode, $this->mLinker ) . "\n";
222
		}
223
		return $result;
224
	}
225
226
	/**
227
	 * @see SMWResultPrinter::getParamDefinitions
228
	 *
229
	 * @since 1.8
230
	 *
231
	 * @param $definitions array of IParamDefinition
232
	 *
233
	 * @return array of IParamDefinition|array
234
	 */
235
	public function getParamDefinitions( array $definitions ) {
236
		$params = parent::getParamDefinitions( $definitions );
237
238
		$params['outlineproperties'] = [
239
			'islist' => true,
240
			'default' => [],
241
			'message' => 'srf_paramdesc_outlineproperties',
242
		];
243
244
		return $params;
245
	}
246
247
}
248