2020-12-14 12:26:02 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace MediaWiki\Rest\Handler;
|
|
|
|
|
|
|
|
|
|
use Config;
|
|
|
|
|
use LogicException;
|
2022-05-16 16:56:20 +00:00
|
|
|
use MediaWiki\Edit\ParsoidOutputStash;
|
2021-05-04 20:45:30 +00:00
|
|
|
use MediaWiki\Page\PageLookup;
|
2020-12-14 12:26:02 +00:00
|
|
|
use MediaWiki\Parser\ParserCacheFactory;
|
|
|
|
|
use MediaWiki\Rest\LocalizedHttpException;
|
|
|
|
|
use MediaWiki\Rest\Response;
|
|
|
|
|
use MediaWiki\Rest\SimpleHandler;
|
|
|
|
|
use MediaWiki\Rest\StringStream;
|
|
|
|
|
use MediaWiki\Revision\RevisionLookup;
|
|
|
|
|
use TitleFormatter;
|
|
|
|
|
use Wikimedia\Assert\Assert;
|
|
|
|
|
use Wikimedia\UUID\GlobalIdGenerator;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* A handler that returns Parsoid HTML for the following routes:
|
|
|
|
|
* - /revision/{revision}/html,
|
|
|
|
|
* - /revision/{revision}/with_html
|
|
|
|
|
*
|
|
|
|
|
* Class RevisionHTMLHandler
|
|
|
|
|
* @package MediaWiki\Rest\Handler
|
|
|
|
|
*/
|
|
|
|
|
class RevisionHTMLHandler extends SimpleHandler {
|
|
|
|
|
|
|
|
|
|
/** @var ParsoidHTMLHelper */
|
|
|
|
|
private $htmlHelper;
|
|
|
|
|
|
|
|
|
|
/** @var RevisionContentHelper */
|
|
|
|
|
private $contentHelper;
|
|
|
|
|
|
2022-05-16 16:56:20 +00:00
|
|
|
/**
|
|
|
|
|
* @param Config $config
|
|
|
|
|
* @param RevisionLookup $revisionLookup
|
|
|
|
|
* @param TitleFormatter $titleFormatter
|
|
|
|
|
* @param ParserCacheFactory $parserCacheFactory
|
|
|
|
|
* @param GlobalIdGenerator $globalIdGenerator
|
|
|
|
|
* @param PageLookup $pageLookup
|
|
|
|
|
* @param ParsoidOutputStash $parsoidOutputStash
|
|
|
|
|
*/
|
2020-12-14 12:26:02 +00:00
|
|
|
public function __construct(
|
|
|
|
|
Config $config,
|
|
|
|
|
RevisionLookup $revisionLookup,
|
|
|
|
|
TitleFormatter $titleFormatter,
|
|
|
|
|
ParserCacheFactory $parserCacheFactory,
|
2021-05-04 20:45:30 +00:00
|
|
|
GlobalIdGenerator $globalIdGenerator,
|
2022-05-16 16:56:20 +00:00
|
|
|
PageLookup $pageLookup,
|
|
|
|
|
ParsoidOutputStash $parsoidOutputStash
|
2020-12-14 12:26:02 +00:00
|
|
|
) {
|
|
|
|
|
$this->contentHelper = new RevisionContentHelper(
|
|
|
|
|
$config,
|
|
|
|
|
$revisionLookup,
|
|
|
|
|
$titleFormatter,
|
2021-05-04 20:45:30 +00:00
|
|
|
$pageLookup
|
2020-12-14 12:26:02 +00:00
|
|
|
);
|
|
|
|
|
$this->htmlHelper = new ParsoidHTMLHelper(
|
|
|
|
|
$parserCacheFactory->getParserCache( 'parsoid' ),
|
2020-12-15 22:12:49 +00:00
|
|
|
$parserCacheFactory->getRevisionOutputCache( 'parsoid' ),
|
2022-05-16 16:56:20 +00:00
|
|
|
$globalIdGenerator,
|
|
|
|
|
$parsoidOutputStash
|
2020-12-14 12:26:02 +00:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected function postValidationSetup() {
|
2021-01-06 18:12:43 +00:00
|
|
|
$this->contentHelper->init( $this->getAuthority(), $this->getValidatedParams() );
|
2020-12-14 12:26:02 +00:00
|
|
|
|
2021-05-04 20:45:30 +00:00
|
|
|
$page = $this->contentHelper->getPage();
|
2020-12-14 12:26:02 +00:00
|
|
|
$revision = $this->contentHelper->getTargetRevision();
|
|
|
|
|
|
2021-05-04 20:45:30 +00:00
|
|
|
if ( $page && $revision ) {
|
2022-05-16 16:56:20 +00:00
|
|
|
$this->htmlHelper->init( $page, $this->getValidatedParams(), $revision );
|
2020-12-14 12:26:02 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return Response
|
|
|
|
|
* @throws LocalizedHttpException
|
|
|
|
|
*/
|
|
|
|
|
public function run(): Response {
|
|
|
|
|
$this->contentHelper->checkAccess();
|
|
|
|
|
|
2021-05-04 20:45:30 +00:00
|
|
|
$page = $this->contentHelper->getPage();
|
2020-12-14 12:26:02 +00:00
|
|
|
$revisionRecord = $this->contentHelper->getTargetRevision();
|
|
|
|
|
|
2021-05-04 20:45:30 +00:00
|
|
|
// The call to $this->contentHelper->getPage() should not return null if
|
2020-12-14 12:26:02 +00:00
|
|
|
// $this->contentHelper->checkAccess() did not throw.
|
2021-05-04 20:45:30 +00:00
|
|
|
Assert::invariant( $page !== null, 'Page should be known' );
|
2020-12-14 12:26:02 +00:00
|
|
|
|
|
|
|
|
// The call to $this->contentHelper->getTargetRevision() should not return null if
|
|
|
|
|
// $this->contentHelper->checkAccess() did not throw.
|
|
|
|
|
Assert::invariant( $revisionRecord !== null, 'Revision should be known' );
|
|
|
|
|
|
|
|
|
|
$outputMode = $this->getOutputMode();
|
|
|
|
|
switch ( $outputMode ) {
|
|
|
|
|
case 'html':
|
|
|
|
|
$parserOutput = $this->htmlHelper->getHtml();
|
|
|
|
|
$response = $this->getResponseFactory()->create();
|
|
|
|
|
// TODO: need to respect content-type returned by Parsoid.
|
|
|
|
|
$response->setHeader( 'Content-Type', 'text/html' );
|
|
|
|
|
$this->contentHelper->setCacheControl( $response, $parserOutput->getCacheExpiry() );
|
|
|
|
|
$response->setBody( new StringStream( $parserOutput->getText() ) );
|
|
|
|
|
break;
|
|
|
|
|
case 'with_html':
|
|
|
|
|
$parserOutput = $this->htmlHelper->getHtml();
|
|
|
|
|
$body = $this->contentHelper->constructMetadata();
|
|
|
|
|
$body['html'] = $parserOutput->getText();
|
|
|
|
|
$response = $this->getResponseFactory()->createJson( $body );
|
|
|
|
|
$this->contentHelper->setCacheControl( $response, $parserOutput->getCacheExpiry() );
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
throw new LogicException( "Unknown HTML type $outputMode" );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $response;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns an ETag representing a page's source. The ETag assumes a page's source has changed
|
|
|
|
|
* if the latest revision of a page has been made private, un-readable for another reason,
|
|
|
|
|
* or a newer revision exists.
|
|
|
|
|
* @return string|null
|
|
|
|
|
*/
|
|
|
|
|
protected function getETag(): ?string {
|
|
|
|
|
if ( !$this->contentHelper->isAccessible() ) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $this->htmlHelper->getETag();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return string|null
|
|
|
|
|
*/
|
|
|
|
|
protected function getLastModified(): ?string {
|
|
|
|
|
if ( !$this->contentHelper->isAccessible() ) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $this->htmlHelper->getLastModified();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private function getOutputMode(): string {
|
|
|
|
|
return $this->getConfig()['format'];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function needsWriteAccess(): bool {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function getParamSettings(): array {
|
2022-05-16 16:56:20 +00:00
|
|
|
return array_merge(
|
|
|
|
|
$this->contentHelper->getParamSettings(),
|
|
|
|
|
$this->htmlHelper->getParamSettings()
|
|
|
|
|
);
|
2020-12-14 12:26:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return bool
|
|
|
|
|
*/
|
|
|
|
|
protected function hasRepresentation() {
|
|
|
|
|
return $this->contentHelper->hasContent();
|
|
|
|
|
}
|
|
|
|
|
}
|