Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
96.15% |
50 / 52 |
|
77.78% |
7 / 9 |
CRAP | |
0.00% |
0 / 1 |
RevisionHTMLHandler | |
96.15% |
50 / 52 |
|
77.78% |
7 / 9 |
18 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
postValidationSetup | |
100.00% |
12 / 12 |
|
100.00% |
1 / 1 |
5 | |||
run | |
96.00% |
24 / 25 |
|
0.00% |
0 / 1 |
4 | |||
getETag | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 | |||
getLastModified | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 | |||
getOutputMode | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
needsWriteAccess | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getParamSettings | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
1 | |||
hasRepresentation | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 |
1 | <?php |
2 | |
3 | namespace MediaWiki\Rest\Handler; |
4 | |
5 | use LogicException; |
6 | use MediaWiki\Rest\Handler\Helper\HtmlOutputRendererHelper; |
7 | use MediaWiki\Rest\Handler\Helper\PageRestHelperFactory; |
8 | use MediaWiki\Rest\Handler\Helper\RevisionContentHelper; |
9 | use MediaWiki\Rest\LocalizedHttpException; |
10 | use MediaWiki\Rest\Response; |
11 | use MediaWiki\Rest\SimpleHandler; |
12 | use MediaWiki\Rest\StringStream; |
13 | use Wikimedia\Assert\Assert; |
14 | |
15 | /** |
16 | * A handler that returns Parsoid HTML for the following routes: |
17 | * - /revision/{revision}/html, |
18 | * - /revision/{revision}/with_html |
19 | * |
20 | * Class RevisionHTMLHandler |
21 | * @package MediaWiki\Rest\Handler |
22 | */ |
23 | class RevisionHTMLHandler extends SimpleHandler { |
24 | |
25 | /** @var HtmlOutputRendererHelper */ |
26 | private $htmlHelper; |
27 | |
28 | /** @var RevisionContentHelper */ |
29 | private $contentHelper; |
30 | |
31 | public function __construct( PageRestHelperFactory $helperFactory ) { |
32 | $this->contentHelper = $helperFactory->newRevisionContentHelper(); |
33 | $this->htmlHelper = $helperFactory->newHtmlOutputRendererHelper(); |
34 | } |
35 | |
36 | protected function postValidationSetup() { |
37 | $authority = $this->getAuthority(); |
38 | $this->contentHelper->init( $authority, $this->getValidatedParams() ); |
39 | |
40 | $page = $this->contentHelper->getPage(); |
41 | $revision = $this->contentHelper->getTargetRevision(); |
42 | |
43 | if ( $page && $revision ) { |
44 | $this->htmlHelper->init( $page, $this->getValidatedParams(), $authority, $revision ); |
45 | |
46 | $request = $this->getRequest(); |
47 | $acceptLanguage = $request->getHeaderLine( 'Accept-Language' ) ?: null; |
48 | if ( $acceptLanguage ) { |
49 | $this->htmlHelper->setVariantConversionLanguage( |
50 | $acceptLanguage |
51 | ); |
52 | } |
53 | } |
54 | } |
55 | |
56 | /** |
57 | * @return Response |
58 | * @throws LocalizedHttpException |
59 | */ |
60 | public function run(): Response { |
61 | $this->contentHelper->checkAccess(); |
62 | |
63 | $page = $this->contentHelper->getPage(); |
64 | $revisionRecord = $this->contentHelper->getTargetRevision(); |
65 | |
66 | // The call to $this->contentHelper->getPage() should not return null if |
67 | // $this->contentHelper->checkAccess() did not throw. |
68 | Assert::invariant( $page !== null, 'Page should be known' ); |
69 | |
70 | // The call to $this->contentHelper->getTargetRevision() should not return null if |
71 | // $this->contentHelper->checkAccess() did not throw. |
72 | Assert::invariant( $revisionRecord !== null, 'Revision should be known' ); |
73 | |
74 | $outputMode = $this->getOutputMode(); |
75 | $setContentLanguageHeader = true; |
76 | switch ( $outputMode ) { |
77 | case 'html': |
78 | $parserOutput = $this->htmlHelper->getHtml(); |
79 | $response = $this->getResponseFactory()->create(); |
80 | // TODO: need to respect content-type returned by Parsoid. |
81 | $response->setHeader( 'Content-Type', 'text/html' ); |
82 | $this->htmlHelper->putHeaders( $response, $setContentLanguageHeader ); |
83 | $this->contentHelper->setCacheControl( $response, $parserOutput->getCacheExpiry() ); |
84 | $response->setBody( new StringStream( $parserOutput->getRawText() ) ); |
85 | break; |
86 | case 'with_html': |
87 | $parserOutput = $this->htmlHelper->getHtml(); |
88 | $body = $this->contentHelper->constructMetadata(); |
89 | $body['html'] = $parserOutput->getRawText(); |
90 | $response = $this->getResponseFactory()->createJson( $body ); |
91 | // For JSON content, it doesn't make sense to set content language header |
92 | $this->htmlHelper->putHeaders( $response, !$setContentLanguageHeader ); |
93 | $this->contentHelper->setCacheControl( $response, $parserOutput->getCacheExpiry() ); |
94 | break; |
95 | default: |
96 | throw new LogicException( "Unknown HTML type $outputMode" ); |
97 | } |
98 | |
99 | return $response; |
100 | } |
101 | |
102 | /** |
103 | * Returns an ETag representing a page's source. The ETag assumes a page's source has changed |
104 | * if the latest revision of a page has been made private, un-readable for another reason, |
105 | * or a newer revision exists. |
106 | * @return string|null |
107 | */ |
108 | protected function getETag(): ?string { |
109 | if ( !$this->contentHelper->isAccessible() ) { |
110 | return null; |
111 | } |
112 | |
113 | // Vary eTag based on output mode |
114 | return $this->htmlHelper->getETag( $this->getOutputMode() ); |
115 | } |
116 | |
117 | /** |
118 | * @return string|null |
119 | */ |
120 | protected function getLastModified(): ?string { |
121 | if ( !$this->contentHelper->isAccessible() ) { |
122 | return null; |
123 | } |
124 | |
125 | return $this->htmlHelper->getLastModified(); |
126 | } |
127 | |
128 | private function getOutputMode(): string { |
129 | return $this->getConfig()['format']; |
130 | } |
131 | |
132 | public function needsWriteAccess(): bool { |
133 | return false; |
134 | } |
135 | |
136 | public function getParamSettings(): array { |
137 | return array_merge( |
138 | $this->contentHelper->getParamSettings(), |
139 | $this->htmlHelper->getParamSettings() |
140 | ); |
141 | } |
142 | |
143 | /** |
144 | * @return bool |
145 | */ |
146 | protected function hasRepresentation() { |
147 | return $this->contentHelper->hasContent(); |
148 | } |
149 | } |