Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 155 |
|
0.00% |
0 / 7 |
CRAP | |
0.00% |
0 / 1 |
PFTemplateDisplay | |
0.00% |
0 / 155 |
|
0.00% |
0 / 7 |
2756 | |
0.00% |
0 / 1 |
run | |
0.00% |
0 / 93 |
|
0.00% |
0 / 1 |
1406 | |||
mapText | |
0.00% |
0 / 21 |
|
0.00% |
0 / 1 |
30 | |||
pageListText | |
0.00% |
0 / 10 |
|
0.00% |
0 / 1 |
20 | |||
pageText | |
0.00% |
0 / 14 |
|
0.00% |
0 / 1 |
12 | |||
stringListText | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
2 | |||
ratingText | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
2 | |||
fileText | |
0.00% |
0 / 9 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | |
3 | use MediaWiki\MediaWikiServices; |
4 | |
5 | /** |
6 | * Defines the #template_display parser function. |
7 | * |
8 | * @author Yaron Koren |
9 | */ |
10 | |
11 | class PFTemplateDisplay { |
12 | |
13 | public static function run( &$parser, $frame, $args ) { |
14 | $title = $parser->getTitle(); |
15 | $params = []; |
16 | foreach ( $args as $arg ) { |
17 | $params[] = trim( $frame->expand( $arg ) ); |
18 | } |
19 | |
20 | $templateFields = []; |
21 | $format = 'infobox'; |
22 | $infoboxTitle = null; |
23 | $tableFieldValues = []; |
24 | |
25 | $templateTitle = $frame->title; |
26 | $template = PFTemplate::newFromName( $templateTitle->getText() ); |
27 | $templateParams = $template->getTemplateParams(); |
28 | if ( $templateParams == null ) { |
29 | return '<div class="error">' . 'Error: #template_params must be called in the template "' . $templateTitle->getText() . '".</div>'; |
30 | } |
31 | |
32 | $parser->getOutput()->addModules( [ 'ext.pageforms.templatedisplay' ] ); |
33 | |
34 | foreach ( $params as $param ) { |
35 | $parts = explode( '=', $param, 2 ); |
36 | if ( count( $parts ) == 1 ) { |
37 | // No such handled params at the moment. |
38 | } else { |
39 | $key = trim( $parts[0] ); |
40 | $value = trim( $parts[1] ); |
41 | if ( $key == '_format' ) { |
42 | $format = $value; |
43 | } elseif ( $key == '_title' ) { |
44 | $infoboxTitle = $value; |
45 | } else { |
46 | $tableFieldValues[$key] = $value; |
47 | } |
48 | } |
49 | } |
50 | |
51 | // Get all the values in this template call. |
52 | $templateFields = $template->getTemplateFields(); |
53 | foreach ( $templateFields as $fieldName => $templateField ) { |
54 | $curFieldValue = $frame->getArgument( $fieldName ); |
55 | if ( $curFieldValue == null ) { |
56 | $unescapedFieldName = str_replace( '_', ' ', $fieldName ); |
57 | $curFieldValue = $frame->getArgument( $unescapedFieldName ); |
58 | } |
59 | $tableFieldValues[$fieldName] = $parser->internalParse( $curFieldValue ); |
60 | } |
61 | |
62 | if ( $format == 'table' ) { |
63 | $text = '<table class="wikitable">' . "\n"; |
64 | } elseif ( $format == 'infobox' ) { |
65 | $text = '<table class="infoboxTable">' . "\n"; |
66 | // If it's blank (as opposed to null), it means the |
67 | // infobox title was deliberately set to empty, to avoid |
68 | // displaying a title row. |
69 | if ( $infoboxTitle !== '' ) { |
70 | if ( $infoboxTitle === null ) { |
71 | $pageProps = MediaWikiServices::getInstance()->getPageProps() |
72 | ->getProperties( $title, 'displaytitle' ); |
73 | $infoboxTitle = array_shift( $pageProps ) ?? |
74 | htmlspecialchars( $title->getFullText(), ENT_NOQUOTES ); |
75 | } |
76 | $text .= '<tr><th colspan="2" class="infoboxTitle">' . $infoboxTitle . '</th></tr>' . "\n"; |
77 | } |
78 | } else { |
79 | $text = ''; |
80 | } |
81 | foreach ( $tableFieldValues as $fieldName => $fieldValue ) { |
82 | if ( !array_key_exists( $fieldName, $templateFields ) ) { |
83 | continue; |
84 | } |
85 | $templateField = $templateFields[$fieldName]; |
86 | $fieldDisplay = $templateField->getDisplay(); |
87 | if ( $fieldDisplay == 'hidden' ) { |
88 | continue; |
89 | } |
90 | if ( $fieldDisplay == 'nonempty' && $fieldValue == '' ) { |
91 | continue; |
92 | } |
93 | |
94 | $fieldType = $templateField->getFieldType(); |
95 | // Ignore stuff like 'Enumeration' - we don't need it. |
96 | $realFieldType = $templateField->getRealFieldType(); |
97 | if ( $realFieldType !== null ) { |
98 | $fieldType = $realFieldType; |
99 | } |
100 | |
101 | $fieldLabel = $templateField->getLabel(); |
102 | if ( $fieldLabel == null ) { |
103 | $fieldLabel = $fieldName; |
104 | } |
105 | |
106 | // If this field holds a template, and it has a value, |
107 | // create a separate fieldset, outside of the table |
108 | // (if this is a table) to display that other set of |
109 | // data. |
110 | // Possibly it would be better to do this not based on |
111 | // whether this field holds a template, but rather on |
112 | // whether the field value contains a <table> tag. |
113 | // However, with the current parser, it may not be |
114 | // possible for this parser function to know that |
115 | // information. |
116 | $holdsTemplate = $templateField->getHoldsTemplate(); |
117 | if ( $format !== 'infobox' && $holdsTemplate !== null ) { |
118 | if ( trim( $fieldValue ) !== '' ) { |
119 | if ( $format == 'table' ) { |
120 | $text .= "</table>\n"; |
121 | } |
122 | $text .= "<fieldset><legend>$fieldLabel</legend>"; |
123 | $text .= $fieldValue; |
124 | $text .= '</fieldset>' . "\n"; |
125 | if ( $format == 'table' ) { |
126 | $text .= '<table class="wikitable">' . "\n"; |
127 | } |
128 | } |
129 | continue; |
130 | } |
131 | if ( trim( $fieldValue ) == '' ) { |
132 | $formattedFieldValue = ''; |
133 | } elseif ( $fieldType == 'Page' ) { |
134 | if ( $templateField->isList() ) { |
135 | $formattedFieldValue = self::pageListText( $fieldValue, $templateField ); |
136 | } else { |
137 | $formattedFieldValue = self::pageText( $fieldValue, $templateField ); |
138 | } |
139 | } elseif ( $fieldType == 'Coordinates' ) { |
140 | $formattedFieldValue = self::mapText( $fieldValue, $format, $parser ); |
141 | } elseif ( $fieldType == 'Rating' ) { |
142 | $formattedFieldValue = self::ratingText( $fieldValue ); |
143 | } elseif ( $fieldType == 'File' ) { |
144 | $formattedFieldValue = self::fileText( $fieldValue ); |
145 | } elseif ( $templateField->isList() ) { |
146 | $formattedFieldValue = self::stringListText( $fieldValue, $templateField ); |
147 | } else { |
148 | $formattedFieldValue = $fieldValue; |
149 | } |
150 | if ( $format == 'table' || $format == 'infobox' ) { |
151 | $text .= "<tr><th>$fieldLabel</th><td>$formattedFieldValue</td></tr>\n"; |
152 | } elseif ( $format == 'sections' ) { |
153 | $text .= "<h2>$fieldLabel</h2>\n$formattedFieldValue\n\n"; |
154 | } else { |
155 | $text .= "<strong>$fieldLabel:</strong> $formattedFieldValue\n\n"; |
156 | } |
157 | } |
158 | |
159 | if ( $format == 'table' || $format == 'infobox' ) { |
160 | $text .= "</table>\n"; |
161 | } |
162 | |
163 | return [ $text, 'noparse' => true, 'isHTML' => true ]; |
164 | } |
165 | |
166 | private static function mapText( $coordinatesStr, $format, $parser ) { |
167 | if ( $coordinatesStr == '' ) { |
168 | return ''; |
169 | } |
170 | |
171 | $mappingFormat = new CargoMapsFormat( $parser->getOutput() ); |
172 | |
173 | try { |
174 | list( $lat, $lon ) = CargoUtils::parseCoordinatesString( $coordinatesStr ); |
175 | } catch ( MWException $e ) { |
176 | return ''; |
177 | } |
178 | $valuesTable = [ [ 'Coords lat' => $lat, 'Coords lon' => $lon ] ]; |
179 | $formattedValuesTable = $valuesTable; |
180 | $coordsDesc = new CargoFieldDescription(); |
181 | $coordsDesc->mType = 'Coordinates'; |
182 | $fieldDescriptions = [ 'Coords' => $coordsDesc ]; |
183 | $displayParams = []; |
184 | if ( $format == 'infobox' ) { |
185 | $displayParams['width'] = '300'; |
186 | $displayParams['height'] = '300'; |
187 | } |
188 | |
189 | try { |
190 | $text = $mappingFormat->display( $valuesTable, |
191 | $formattedValuesTable, $fieldDescriptions, |
192 | $displayParams ); |
193 | } catch ( MWException $e ) { |
194 | return ''; |
195 | } |
196 | return $text; |
197 | } |
198 | |
199 | private static function pageListText( $value, $templateField ) { |
200 | $text = ''; |
201 | $delimiter = $templateField->getDelimiter(); |
202 | $fieldValues = explode( $delimiter, $value ); |
203 | foreach ( $fieldValues as $i => $fieldValue ) { |
204 | if ( trim( $fieldValue ) == '' ) { |
205 | continue; |
206 | } |
207 | if ( $i > 0 ) { |
208 | $text .= ' <span class="CargoDelimiter">•</span> '; |
209 | } |
210 | $text .= self::pageText( $fieldValue, $templateField ); |
211 | } |
212 | return $text; |
213 | } |
214 | |
215 | private static function pageText( $value, $templateField ) { |
216 | $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer(); |
217 | $namespace = $templateField->getNamespace(); |
218 | $title = Title::makeTitleSafe( $namespace, $value ); |
219 | if ( $title->exists() ) { |
220 | return PFUtils::makeLink( $linkRenderer, $title ); |
221 | } |
222 | $form = $templateField->getForm(); |
223 | if ( $form == null ) { |
224 | return PFUtils::makeLink( $linkRenderer, $title ); |
225 | } |
226 | // The page doesn't exist, and a form has been found for this |
227 | // template field - link to this form for this page. |
228 | $formSpecialPage = PFUtils::getSpecialPage( 'FormEdit' ); |
229 | $formSpecialPageTitle = $formSpecialPage->getPageTitle(); |
230 | $target = $title->getFullText(); |
231 | $formURL = $formSpecialPageTitle->getLocalURL() . |
232 | str_replace( ' ', '_', "/$form/$target" ); |
233 | return Html::rawElement( 'a', [ 'href' => $formURL, 'class' => 'new' ], $value ); |
234 | } |
235 | |
236 | private static function stringListText( $value, $templateField ) { |
237 | $delimiter = $templateField->getDelimiter(); |
238 | $fieldValues = explode( $delimiter, $value ); |
239 | return implode( ' <span class="CargoDelimiter">•</span> ', $fieldValues ); |
240 | } |
241 | |
242 | private static function ratingText( $value ) { |
243 | global $wgServer, $wgScriptPath; |
244 | |
245 | $rate = $value * 20; |
246 | $url = $wgServer . $wgScriptPath . '/' . 'extensions/Cargo/resources/images/star-rating-sprite-1.png'; |
247 | $text = '<span style="display: block; width: 65px; height: 13px; background: url(\'' . $url . '\') 0 0;"> |
248 | <span style="display: block; width: ' . $rate . '%; height: 13px; background: url(\'' . $url . '\') 0 -13px;"></span>'; |
249 | return $text; |
250 | } |
251 | |
252 | private static function fileText( $value ) { |
253 | $title = Title::newFromText( $value, NS_FILE ); |
254 | $file = MediaWikiServices::getInstance()->getRepoGroup()->findFile( $title ); |
255 | return Linker::makeThumbLinkObj( |
256 | $title, |
257 | $file, |
258 | $value, |
259 | '', |
260 | 'left' |
261 | ); |
262 | } |
263 | |
264 | } |