Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 91 |
|
0.00% |
0 / 3 |
CRAP | |
0.00% |
0 / 1 |
CargoTableFormat | |
0.00% |
0 / 91 |
|
0.00% |
0 / 3 |
1482 | |
0.00% |
0 / 1 |
allowedParameters | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
2 | |||
getHelperDataForMerging | |
0.00% |
0 / 22 |
|
0.00% |
0 / 1 |
132 | |||
display | |
0.00% |
0 / 65 |
|
0.00% |
0 / 1 |
702 |
1 | <?php |
2 | /** |
3 | * @author Yaron Koren |
4 | * @ingroup Cargo |
5 | */ |
6 | |
7 | use MediaWiki\Html\Html; |
8 | use MediaWiki\MediaWikiServices; |
9 | use MediaWiki\Title\Title; |
10 | |
11 | class CargoTableFormat extends CargoDisplayFormat { |
12 | |
13 | public static function allowedParameters() { |
14 | return [ |
15 | 'merge similar cells' => [ 'type' => 'boolean' ], |
16 | 'edit link' => [ 'type' => 'boolean' ], |
17 | ]; |
18 | } |
19 | |
20 | /** |
21 | * Creates helper data structures that make merging cells |
22 | * easier, if it's going to be done. |
23 | */ |
24 | private function getHelperDataForMerging( $formattedValuesTable ) { |
25 | $duplicateValuesInTable = []; |
26 | $blankedCells = []; |
27 | $numRows = count( $formattedValuesTable ); |
28 | foreach ( $formattedValuesTable as $rowNum => $row ) { |
29 | foreach ( $row as $columnNum => $value ) { |
30 | if ( strpos( $columnNum, '__' ) !== false ) { |
31 | continue; |
32 | } |
33 | if ( array_key_exists( $rowNum, $blankedCells ) && in_array( $columnNum, $blankedCells[$rowNum] ) ) { |
34 | continue; |
35 | } |
36 | $numMatches = 0; |
37 | $nextRowNum = $rowNum; |
38 | while ( |
39 | ( ++$nextRowNum < $numRows ) && |
40 | ( $formattedValuesTable[$nextRowNum][$columnNum] == $value ) |
41 | ) { |
42 | $numMatches++; |
43 | if ( !array_key_exists( $nextRowNum, $blankedCells ) ) { |
44 | $blankedCells[$nextRowNum] = []; |
45 | } |
46 | $blankedCells[$nextRowNum][] = $columnNum; |
47 | } |
48 | if ( $numMatches > 0 ) { |
49 | if ( !array_key_exists( $rowNum, $duplicateValuesInTable ) ) { |
50 | $duplicateValuesInTable[$rowNum] = []; |
51 | } |
52 | $duplicateValuesInTable[$rowNum][$columnNum] = $numMatches + 1; |
53 | } |
54 | } |
55 | } |
56 | |
57 | return [ $duplicateValuesInTable, $blankedCells ]; |
58 | } |
59 | |
60 | /** |
61 | * @param array $valuesTable Unused |
62 | * @param array $formattedValuesTable |
63 | * @param array $fieldDescriptions |
64 | * @param array $displayParams Unused |
65 | * @return string HTML |
66 | */ |
67 | public function display( $valuesTable, $formattedValuesTable, $fieldDescriptions, $displayParams ) { |
68 | $this->mOutput->addModules( [ 'ext.cargo.main', 'jquery.tablesorter' ] ); |
69 | $this->mOutput->addModuleStyles( [ 'jquery.tablesorter.styles' ] ); |
70 | |
71 | $mergeSimilarCells = false; |
72 | if ( array_key_exists( 'merge similar cells', $displayParams ) ) { |
73 | $mergeSimilarCells = strtolower( $displayParams['merge similar cells'] ) == 'yes'; |
74 | } |
75 | $editLink = false; |
76 | $linkRenderer = null; |
77 | if ( array_key_exists( 'edit link', $displayParams ) ) { |
78 | $editLink = strtolower( $displayParams['edit link'] ) == 'yes'; |
79 | $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer(); |
80 | } |
81 | |
82 | $tableClass = 'cargoTable'; |
83 | if ( $mergeSimilarCells ) { |
84 | $tableClass .= ' mergeSimilarCells'; |
85 | } else { |
86 | $tableClass .= ' noMerge sortable'; |
87 | } |
88 | |
89 | $text = "<table class=\"$tableClass\">"; |
90 | $text .= '<thead><tr>'; |
91 | foreach ( array_keys( $fieldDescriptions ) as $field ) { |
92 | if ( strpos( $field, 'Blank value ' ) === false ) { |
93 | // We add a class to enable special CSS and/or |
94 | // JS handling. |
95 | $className = 'field_' . str_replace( ' ', '_', $field ); |
96 | $text .= Html::rawElement( 'th', [ 'class' => $className ], $field ) . "\n"; |
97 | } |
98 | } |
99 | $text .= "</tr></thead>\n<tbody>"; |
100 | |
101 | if ( $mergeSimilarCells ) { |
102 | [ $duplicateValuesInTable, $blankedCells ] = $this->getHelperDataForMerging( $formattedValuesTable ); |
103 | } |
104 | |
105 | $columnIsOdd = []; |
106 | |
107 | foreach ( $formattedValuesTable as $rowNum => $row ) { |
108 | $text .= "<tr>\n"; |
109 | foreach ( array_keys( $fieldDescriptions ) as $field ) { |
110 | if ( |
111 | $mergeSimilarCells && |
112 | array_key_exists( $rowNum, $blankedCells ) && |
113 | in_array( $field, $blankedCells[$rowNum] ) |
114 | ) { |
115 | continue; |
116 | } |
117 | |
118 | if ( !array_key_exists( $field, $columnIsOdd ) ) { |
119 | $columnIsOdd[$field] = true; |
120 | } |
121 | |
122 | // Add a unique class to enable special CSS |
123 | // and/or JS handling. |
124 | $className = 'field_' . str_replace( ' ', '_', $field ); |
125 | |
126 | if ( $mergeSimilarCells ) { |
127 | // If there are merged cells, we can't |
128 | // use the standard "nth-child" CSS |
129 | // approach, so add a class to indicate |
130 | // whether this is an odd or even row. |
131 | if ( $columnIsOdd[$field] ) { |
132 | $className .= ' odd'; |
133 | $columnIsOdd[$field] = false; |
134 | } else { |
135 | $className .= ' even'; |
136 | $columnIsOdd[$field] = true; |
137 | } |
138 | } |
139 | |
140 | $attrs = [ 'class' => $className ]; |
141 | if ( |
142 | $mergeSimilarCells && |
143 | array_key_exists( $rowNum, $duplicateValuesInTable ) && |
144 | array_key_exists( $field, $duplicateValuesInTable[$rowNum] ) |
145 | ) { |
146 | $attrs['rowspan'] = $duplicateValuesInTable[$rowNum][$field]; |
147 | } |
148 | |
149 | if ( array_key_exists( $field, $row ) ) { |
150 | $value = $row[$field]; |
151 | if ( $fieldDescriptions[$field]->isDateOrDatetime() ) { |
152 | $attrs['data-sort-value'] = $valuesTable[$rowNum][$field]; |
153 | } |
154 | } else { |
155 | $value = null; |
156 | } |
157 | |
158 | $valueText = $value == null ? '' : $value; |
159 | |
160 | // Cargo reuses the "Page" system message of the main namespace |
161 | $pageMsg = wfMessage( "nstab-main" )->text(); |
162 | if ( ( $field == "Page" || $field == $pageMsg || $field == '_pageName' ) && |
163 | $editLink ) { |
164 | $rawValue = $valuesTable[$rowNum][$field]; |
165 | $title = Title::newFromText( $rawValue ); |
166 | if ( $title === null ) { |
167 | continue; |
168 | } |
169 | $link = CargoUtils::makeLink( |
170 | $linkRenderer, $title, wfMessage( 'editold' ), [], [ 'action' => 'edit', ] |
171 | ); |
172 | $valueText .= ' (' . $link . ')'; |
173 | } |
174 | |
175 | $text .= Html::rawElement( 'td', $attrs, $valueText ) . "\n"; |
176 | } |
177 | $text .= "</tr>\n"; |
178 | } |
179 | $text .= "</tbody></table>"; |
180 | return $text; |
181 | } |
182 | |
183 | } |