Completed
Push — master ( 977272...11f4a6 )
by Karsten
07:17
created

formats/outline/SRF_Outline.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
 * 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
14
	var $mRow;
15
	var $mVals;
16
17
	function __construct( $row ) {
18
		$this->mRow = $row;
19
		$this->mVals = [];
20
	}
21
22
	function addFieldValue( $field_name, $field_val ) {
23
		if ( array_key_exists( $field_name, $this->mVals ) ) {
24
			$this->mVals[$field_name][] = $field_val;
25
		} else {
26
			$this->mVals[$field_name] = [ $field_val ];
27
		}
28
	}
29
30
	function getFieldValues( $field_name ) {
31
		if ( array_key_exists( $field_name, $this->mVals ) ) {
32
			return $this->mVals[$field_name];
33
		} else {
34
			return [ wfMessage( 'srf_outline_novalue' )->text() ];
35
		}
36
	}
37
}
38
39
/**
40
 * A tree structure for holding the outline data
41
 */
42
class SRFOutlineTree {
43
44
	var $mTree;
45
	var $mUnsortedItems;
46
47
	function __construct( $items = [] ) {
48
		$this->mTree = [];
49
		$this->mUnsortedItems = $items;
50
	}
51
52
	function addItem( $item ) {
53
		$this->mUnsortedItems[] = $item;
54
	}
55
56
	function categorizeItem( $vals, $item ) {
57
		foreach ( $vals as $val ) {
58
			if ( array_key_exists( $val, $this->mTree ) ) {
59
				$this->mTree[$val]->mUnsortedItems[] = $item;
60
			} else {
61
				$this->mTree[$val] = new SRFOutlineTree( [ $item ] );
62
			}
63
		}
64
	}
65
66
	function addProperty( $property ) {
67
		if ( count( $this->mUnsortedItems ) > 0 ) {
68
			foreach ( $this->mUnsortedItems as $item ) {
69
				$cur_vals = $item->getFieldValues( $property );
70
				$this->categorizeItem( $cur_vals, $item );
71
			}
72
			$this->mUnsortedItems = null;
73
		} else {
74
			foreach ( $this->mTree as $i => $node ) {
75
				$this->mTree[$i]->addProperty( $property );
76
			}
77
		}
78
	}
79
}
80
81
class SRFOutline extends SMWResultPrinter {
82
83
	protected $mOutlineProperties = [];
84
	protected $mInnerFormat = '';
85
86
	protected function handleParameters( array $params, $outputmode ) {
87
		parent::handleParameters( $params, $outputmode );
88
		$this->mOutlineProperties = $params['outlineproperties'];
89
	}
90
91
	public function getName() {
92
		return wfMessage( 'srf_printername_outline' )->text();
93
	}
94
95
	/**
96
	 * Code mostly copied from SMW's SMWListResultPrinter::getResultText()
97
	 */
98
	function printItem( $item ) {
99
		$first_col = true;
100
		$found_values = false; // has anything but the first column been printed?
101
		$result = "";
102
		foreach ( $item->mRow as $orig_ra ) {
103
			// handling is somewhat simpler for SMW 1.5+
104
			$realFunction = [ 'SMWQueryResult', 'getResults' ];
105
			if ( is_callable( $realFunction ) ) {
106
				// make a new copy of this, so that the call to
107
				// getNextText() will work again
108
				$ra = clone ( $orig_ra );
109
			} else {
110
				// make a new copy of this, so that the call to
111
				// getNextText() will work again
112
				$ra = new SMWResultArray( $orig_ra->getContent(), $orig_ra->getPrintRequest() );
0 ignored issues
show
The call to SMWResultArray::__construct() misses a required argument $store.

This check looks for function calls that miss required arguments.

Loading history...
113
			}
114
			$val = $ra->getPrintRequest()->getText( SMW_OUTPUT_WIKI, null );
115
			if ( in_array( $val, $this->mOutlineProperties ) ) {
116
				continue;
117
			}
118
			$first_value = true;
119
			while ( ( $text = $ra->getNextText( SMW_OUTPUT_WIKI, $this->mLinker ) ) !== false ) {
120
				if ( !$first_col && !$found_values ) { // first values after first column
121
					$result .= ' (';
122
					$found_values = true;
123
				} elseif ( $found_values || !$first_value ) {
124
					// any value after '(' or non-first values on first column
125
					$result .= ', ';
126
				}
127
				if ( $first_value ) { // first value in any column, print header
128
					$first_value = false;
129
					if ( $this->mShowHeaders && ( '' != $ra->getPrintRequest()->getLabel() ) ) {
130
						$result .= $ra->getPrintRequest()->getText( SMW_OUTPUT_WIKI, $this->mLinker ) . ' ';
131
					}
132
				}
133
				$result .= $text; // actual output value
134
			}
135
			$first_col = false;
136
		}
137
		if ( $found_values ) {
138
			$result .= ')';
139
		}
140
		return $result;
141
	}
142
143
	function printTree( $outline_tree, $level = 0 ) {
144
		$text = "";
145
		if ( !is_null( $outline_tree->mUnsortedItems ) ) {
146
			$text .= "<ul>\n";
147
			foreach ( $outline_tree->mUnsortedItems as $item ) {
148
				$text .= "<li>{$this->printItem($item)}</li>\n";
149
			}
150
			$text .= "</ul>\n";
151
		}
152
		if ( $level > 0 ) {
153
			$text .= "<ul>\n";
154
		}
155
		$num_levels = count( $this->mOutlineProperties );
156
		// set font size and weight depending on level we're at
157
		$font_level = $level;
158
		if ( $num_levels < 4 ) {
159
			$font_level += ( 4 - $num_levels );
160
		}
161
		if ( $font_level == 0 ) {
162
			$font_size = 'x-large';
163
		} elseif ( $font_level == 1 ) {
164
			$font_size = 'large';
165
		} elseif ( $font_level == 2 ) {
166
			$font_size = 'medium';
167
		} else {
168
			$font_size = 'small';
169
		}
170
		if ( $font_level == 3 ) {
171
			$font_weight = 'bold';
172
		} else {
173
			$font_weight = 'regular';
174
		}
175
		foreach ( $outline_tree->mTree as $key => $node ) {
176
			$text .= "<p style=\"font-size: $font_size; font-weight: $font_weight;\">$key</p>\n";
177
			$text .= $this->printTree( $node, $level + 1 );
178
		}
179
		if ( $level > 0 ) {
180
			$text .= "</ul>\n";
181
		}
182
		return $text;
183
	}
184
185
	protected function getResultText( SMWQueryResult $res, $outputmode ) {
186
		$print_fields = [];
187
		foreach ( $res->getPrintRequests() as $pr ) {
188
			$field_name = $pr->getText( $outputmode, $this->mLinker );
189
			// only print it if it's not already part of the
190
			// outline
191
			if ( !in_array( $field_name, $this->mOutlineProperties ) ) {
192
				$print_fields[] = $field_name;
193
			}
194
		}
195
196
		// for each result row, create an array of the row itself
197
		// and all its sorted-on fields, and add it to the initial
198
		// 'tree'
199
		$outline_tree = new SRFOutlineTree();
200
		while ( $row = $res->getNext() ) {
201
			$item = new SRFOutlineItem( $row );
202
			foreach ( $row as $field ) {
203
				$field_name = $field->getPrintRequest()->getText( SMW_OUTPUT_HTML );
204
				if ( in_array( $field_name, $this->mOutlineProperties ) ) {
205
					while ( ( $object = $field->getNextDataValue() ) !== false ) {
206
						$field_val = $object->getLongWikiText( $this->mLinker );
207
						$item->addFieldValue( $field_name, $field_val );
208
					}
209
				}
210
			}
211
			$outline_tree->addItem( $item );
212
		}
213
214
		// now, cycle through the outline properties, creating the
215
		// tree
216
		foreach ( $this->mOutlineProperties as $outline_prop ) {
217
			$outline_tree->addProperty( $outline_prop );
218
		}
219
		$result = $this->printTree( $outline_tree );
220
221
		// print further results footer
222
		if ( $this->linkFurtherResults( $res ) ) {
223
			$link = $res->getQueryLink();
224
			if ( $this->getSearchLabel( $outputmode ) ) {
225
				$link->setCaption( $this->getSearchLabel( $outputmode ) );
226
			}
227
			$link->setParameter( 'outline', 'format' );
228
			if ( array_key_exists( 'outlineproperties', $this->params ) ) {
229
				$link->setParameter( $this->params['outlineproperties'], 'outlineproperties' );
230
			}
231
			$result .= $link->getText( $outputmode, $this->mLinker ) . "\n";
232
		}
233
		return $result;
234
	}
235
236
	/**
237
	 * @see SMWResultPrinter::getParamDefinitions
238
	 *
239
	 * @since 1.8
240
	 *
241
	 * @param $definitions array of IParamDefinition
242
	 *
243
	 * @return array of IParamDefinition|array
244
	 */
245
	public function getParamDefinitions( array $definitions ) {
246
		$params = parent::getParamDefinitions( $definitions );
247
248
		$params['outlineproperties'] = [
249
			'islist' => true,
250
			'default' => [],
251
			'message' => 'srf_paramdesc_outlineproperties',
252
		];
253
254
		return $params;
255
	}
256
257
}
258