Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 32 |
|
0.00% |
0 / 3 |
CRAP | |
0.00% |
0 / 1 |
ParsoidFormatHelper | |
0.00% |
0 / 32 |
|
0.00% |
0 / 3 |
210 | |
0.00% |
0 / 1 |
getContentType | |
0.00% |
0 / 16 |
|
0.00% |
0 / 1 |
56 | |||
setContentType | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
parseContentTypeHeader | |
0.00% |
0 / 15 |
|
0.00% |
0 / 1 |
42 |
1 | <?php |
2 | /** |
3 | * Copyright (C) 2011-2020 Wikimedia Foundation and others. |
4 | * |
5 | * This program is free software; you can redistribute it and/or modify |
6 | * it under the terms of the GNU General Public License as published by |
7 | * the Free Software Foundation; either version 2 of the License, or |
8 | * (at your option) any later version. |
9 | * |
10 | * This program is distributed in the hope that it will be useful, |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 | * GNU General Public License for more details. |
14 | * |
15 | * You should have received a copy of the GNU General Public License along |
16 | * with this program; if not, write to the Free Software Foundation, Inc., |
17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
18 | */ |
19 | |
20 | namespace MediaWiki\Rest\Handler\Helper; |
21 | |
22 | use InvalidArgumentException; |
23 | use MediaWiki\Rest\ResponseInterface; |
24 | |
25 | /** |
26 | * Format-related REST API helper. |
27 | * Probably should be turned into an object encapsulating format and content version at some point. |
28 | */ |
29 | class ParsoidFormatHelper { |
30 | |
31 | public const FORMAT_WIKITEXT = 'wikitext'; |
32 | public const FORMAT_HTML = 'html'; |
33 | public const FORMAT_PAGEBUNDLE = 'pagebundle'; |
34 | public const FORMAT_LINT = 'lint'; |
35 | |
36 | public const ERROR_ENCODING = [ |
37 | self::FORMAT_WIKITEXT => 'plain', |
38 | self::FORMAT_HTML => 'html', |
39 | self::FORMAT_PAGEBUNDLE => 'json', |
40 | self::FORMAT_LINT => 'json', |
41 | ]; |
42 | |
43 | public const VALID_PAGE = [ |
44 | self::FORMAT_WIKITEXT, self::FORMAT_HTML, self::FORMAT_PAGEBUNDLE, self::FORMAT_LINT |
45 | ]; |
46 | |
47 | public const VALID_TRANSFORM = [ |
48 | self::FORMAT_WIKITEXT => [ self::FORMAT_HTML, self::FORMAT_PAGEBUNDLE, self::FORMAT_LINT ], |
49 | self::FORMAT_HTML => [ self::FORMAT_WIKITEXT ], |
50 | self::FORMAT_PAGEBUNDLE => [ self::FORMAT_WIKITEXT, self::FORMAT_PAGEBUNDLE ], |
51 | ]; |
52 | |
53 | /** |
54 | * Get the content type appropriate for a given response format. |
55 | * @param string $format One of the FORMAT_* constants |
56 | * @param ?string $contentVersion Output version, only for HTML and pagebundle |
57 | * formats. See Env::getcontentVersion(). |
58 | * @return string |
59 | */ |
60 | public static function getContentType( |
61 | string $format, ?string $contentVersion = null |
62 | ): string { |
63 | if ( $format !== self::FORMAT_WIKITEXT && !$contentVersion ) { |
64 | throw new InvalidArgumentException( '$contentVersion is required for this format' ); |
65 | } |
66 | |
67 | switch ( $format ) { |
68 | case self::FORMAT_WIKITEXT: |
69 | $contentType = 'text/plain'; |
70 | // PORT-FIXME in the original the version number is from MWParserEnvironment.wikitextVersion |
71 | // but it did not seem to be used anywhere |
72 | $profile = 'https://www.mediawiki.org/wiki/Specs/wikitext/1.0.0'; |
73 | break; |
74 | case self::FORMAT_HTML: |
75 | $contentType = 'text/html'; |
76 | $profile = 'https://www.mediawiki.org/wiki/Specs/HTML/' . $contentVersion; |
77 | break; |
78 | case self::FORMAT_PAGEBUNDLE: |
79 | $contentType = 'application/json'; |
80 | $profile = 'https://www.mediawiki.org/wiki/Specs/pagebundle/' . $contentVersion; |
81 | break; |
82 | default: |
83 | throw new InvalidArgumentException( "Invalid format $format" ); |
84 | } |
85 | return "$contentType; charset=utf-8; profile=\"$profile\""; |
86 | } |
87 | |
88 | /** |
89 | * Set the Content-Type header appropriate for a given response format. |
90 | * @param ResponseInterface $response |
91 | * @param string $format One of the FORMAT_* constants |
92 | * @param ?string $contentVersion Output version, only for HTML and pagebundle |
93 | * formats. See Env::getcontentVersion(). |
94 | */ |
95 | public static function setContentType( |
96 | ResponseInterface $response, string $format, |
97 | ?string $contentVersion = null |
98 | ): void { |
99 | $response->setHeader( 'Content-Type', self::getContentType( $format, $contentVersion ) ); |
100 | } |
101 | |
102 | /** |
103 | * Parse a Content-Type header and return the format type and version. |
104 | * Mostly the inverse of getContentType() but also accounts for legacy formats. |
105 | * @param string $contentTypeHeader The value of the Content-Type header. |
106 | * @param ?string &$format Format type will be set here (as a FORMAT_* constant). |
107 | * @return ?string Format version, or null if it couldn't be identified. |
108 | * @see Env::getInputContentVersion() |
109 | */ |
110 | public static function parseContentTypeHeader( |
111 | string $contentTypeHeader, ?string &$format = null |
112 | ): ?string { |
113 | $newProfileSyntax = 'https://www.mediawiki.org/wiki/Specs/(HTML|pagebundle)/'; |
114 | $oldProfileSyntax = 'mediawiki.org/specs/(html)/'; |
115 | $profileRegex = "#\bprofile=\"(?:$newProfileSyntax|$oldProfileSyntax)(\d+\.\d+\.\d+)\"#"; |
116 | preg_match( $profileRegex, $contentTypeHeader, $m ); |
117 | if ( $m ) { |
118 | switch ( $m[1] ?: $m[2] ) { |
119 | case 'HTML': |
120 | case 'html': |
121 | $format = self::FORMAT_HTML; |
122 | break; |
123 | case 'pagebundle': |
124 | $format = self::FORMAT_PAGEBUNDLE; |
125 | break; |
126 | } |
127 | return $m[3]; |
128 | } |
129 | return null; |
130 | } |
131 | |
132 | } |