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