Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
68.09% |
32 / 47 |
|
50.00% |
6 / 12 |
CRAP | |
0.00% |
0 / 1 |
RevisionSourceHandler | |
68.09% |
32 / 47 |
|
50.00% |
6 / 12 |
35.34 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
postValidationSetup | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
constructHtmlUrl | |
85.71% |
6 / 7 |
|
0.00% |
0 / 1 |
2.01 | |||
run | |
85.71% |
18 / 21 |
|
0.00% |
0 / 1 |
5.07 | |||
getTargetFormat | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getResponseBodySchemaFileName | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
20 | |||
getETag | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getLastModified | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getOutputMode | |
66.67% |
2 / 3 |
|
0.00% |
0 / 1 |
2.15 | |||
needsWriteAccess | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getParamSettings | |
100.00% |
1 / 1 |
|
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\PageRestHelperFactory; |
7 | use MediaWiki\Rest\Handler\Helper\RevisionContentHelper; |
8 | use MediaWiki\Rest\LocalizedHttpException; |
9 | use MediaWiki\Rest\Response; |
10 | use MediaWiki\Rest\SimpleHandler; |
11 | use MediaWiki\Revision\RevisionRecord; |
12 | use Wikimedia\Message\MessageValue; |
13 | |
14 | /** |
15 | * A handler that returns page source and metadata for the following routes: |
16 | * - /revision/{revision} |
17 | * - /revision/{revision}/bare |
18 | */ |
19 | class RevisionSourceHandler extends SimpleHandler { |
20 | |
21 | private RevisionContentHelper $contentHelper; |
22 | |
23 | public function __construct( PageRestHelperFactory $helperFactory ) { |
24 | $this->contentHelper = $helperFactory->newRevisionContentHelper(); |
25 | } |
26 | |
27 | protected function postValidationSetup() { |
28 | $this->contentHelper->init( $this->getAuthority(), $this->getValidatedParams() ); |
29 | } |
30 | |
31 | /** |
32 | * @param RevisionRecord $rev |
33 | * @return string |
34 | */ |
35 | private function constructHtmlUrl( RevisionRecord $rev ): string { |
36 | // TODO: once legacy "v1" routes are removed, just use the path prefix from the module. |
37 | $pathPrefix = $this->getModule()->getPathPrefix(); |
38 | if ( strlen( $pathPrefix ) == 0 ) { |
39 | $pathPrefix = 'v1'; |
40 | } |
41 | |
42 | return $this->getRouter()->getRouteUrl( |
43 | '/' . $pathPrefix . '/revision/{id}/html', |
44 | [ 'id' => $rev->getId() ] |
45 | ); |
46 | } |
47 | |
48 | /** |
49 | * @return Response |
50 | * @throws LocalizedHttpException |
51 | */ |
52 | public function run() { |
53 | $this->contentHelper->checkAccess(); |
54 | |
55 | $outputMode = $this->getOutputMode(); |
56 | switch ( $outputMode ) { |
57 | case 'restbase': // compatibility for restbase migration |
58 | $body = [ 'items' => [ $this->contentHelper->constructRestbaseCompatibleMetadata() ] ]; |
59 | break; |
60 | case 'bare': |
61 | $revisionRecord = $this->contentHelper->getTargetRevision(); |
62 | $body = $this->contentHelper->constructMetadata(); |
63 | // @phan-suppress-next-line PhanTypeMismatchArgumentNullable revisionRecord is set when used |
64 | $body['html_url'] = $this->constructHtmlUrl( $revisionRecord ); |
65 | $response = $this->getResponseFactory()->createJson( $body ); |
66 | $this->contentHelper->setCacheControl( $response ); |
67 | break; |
68 | case 'source': |
69 | $content = $this->contentHelper->getContent(); |
70 | $body = $this->contentHelper->constructMetadata(); |
71 | $body['source'] = $content->getText(); |
72 | break; |
73 | default: |
74 | throw new LogicException( "Unknown output mode $outputMode" ); |
75 | } |
76 | |
77 | $response = $this->getResponseFactory()->createJson( $body ); |
78 | $this->contentHelper->setCacheControl( $response ); |
79 | |
80 | return $response; |
81 | } |
82 | |
83 | private function getTargetFormat(): string { |
84 | return $this->getConfig()['format']; |
85 | } |
86 | |
87 | protected function getResponseBodySchemaFileName( string $method ): ?string { |
88 | switch ( $this->getTargetFormat() ) { |
89 | case 'bare': |
90 | return 'includes/Rest/Handler/Schema/RevisionMetaDataBare.json'; |
91 | |
92 | case 'source': |
93 | return 'includes/Rest/Handler/Schema/RevisionMetaDataWithSource.json'; |
94 | |
95 | default: |
96 | throw new LocalizedHttpException( |
97 | new MessageValue( "rest-unsupported-target-format" ), 500 |
98 | ); |
99 | } |
100 | } |
101 | |
102 | /** |
103 | * @return string|null |
104 | */ |
105 | protected function getETag(): ?string { |
106 | return $this->contentHelper->getETag(); |
107 | } |
108 | |
109 | /** |
110 | * @return string|null |
111 | */ |
112 | protected function getLastModified(): ?string { |
113 | return $this->contentHelper->getLastModified(); |
114 | } |
115 | |
116 | private function getOutputMode(): string { |
117 | if ( $this->getRouter()->isRestbaseCompatEnabled( $this->getRequest() ) ) { |
118 | return 'restbase'; |
119 | } |
120 | return $this->getConfig()['format']; |
121 | } |
122 | |
123 | public function needsWriteAccess(): bool { |
124 | return false; |
125 | } |
126 | |
127 | public function getParamSettings(): array { |
128 | return $this->contentHelper->getParamSettings(); |
129 | } |
130 | |
131 | /** |
132 | * @return bool |
133 | */ |
134 | protected function hasRepresentation() { |
135 | return $this->contentHelper->hasContent(); |
136 | } |
137 | } |