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