2019-11-18 15:16:39 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace MediaWiki\Rest\Handler;
|
|
|
|
|
|
2020-03-16 20:52:39 +00:00
|
|
|
use File;
|
2019-11-18 15:16:39 +00:00
|
|
|
use MediaFileTrait;
|
|
|
|
|
use MediaWiki\Permissions\PermissionManager;
|
|
|
|
|
use MediaWiki\Rest\LocalizedHttpException;
|
|
|
|
|
use MediaWiki\Rest\Response;
|
|
|
|
|
use MediaWiki\Rest\SimpleHandler;
|
|
|
|
|
use RepoGroup;
|
|
|
|
|
use RequestContext;
|
|
|
|
|
use Title;
|
|
|
|
|
use User;
|
|
|
|
|
use Wikimedia\Message\MessageValue;
|
|
|
|
|
use Wikimedia\ParamValidator\ParamValidator;
|
|
|
|
|
|
|
|
|
|
/**
|
2020-03-16 20:52:39 +00:00
|
|
|
* Handler class for media meta-data
|
2019-11-18 15:16:39 +00:00
|
|
|
*/
|
|
|
|
|
class MediaFileHandler extends SimpleHandler {
|
|
|
|
|
use MediaFileTrait;
|
|
|
|
|
|
|
|
|
|
/** @var PermissionManager */
|
|
|
|
|
private $permissionManager;
|
|
|
|
|
|
|
|
|
|
/** @var RepoGroup */
|
|
|
|
|
private $repoGroup;
|
|
|
|
|
|
|
|
|
|
/** @var User */
|
|
|
|
|
private $user;
|
|
|
|
|
|
2020-03-16 20:52:39 +00:00
|
|
|
/**
|
|
|
|
|
* @var Title|bool|null
|
|
|
|
|
*/
|
|
|
|
|
private $title = null;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @var File|bool|null
|
|
|
|
|
*/
|
|
|
|
|
private $file = null;
|
|
|
|
|
|
2019-11-18 15:16:39 +00:00
|
|
|
/**
|
|
|
|
|
* @param PermissionManager $permissionManager
|
|
|
|
|
* @param RepoGroup $repoGroup
|
|
|
|
|
*/
|
|
|
|
|
public function __construct(
|
|
|
|
|
PermissionManager $permissionManager,
|
|
|
|
|
RepoGroup $repoGroup
|
|
|
|
|
) {
|
|
|
|
|
$this->permissionManager = $permissionManager;
|
|
|
|
|
$this->repoGroup = $repoGroup;
|
|
|
|
|
|
|
|
|
|
// @todo Inject this, when there is a good way to do that
|
|
|
|
|
$this->user = RequestContext::getMain()->getUser();
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-16 20:52:39 +00:00
|
|
|
/**
|
|
|
|
|
* @return Title|bool Title or false if unable to retrieve title
|
|
|
|
|
*/
|
|
|
|
|
private function getTitle() {
|
|
|
|
|
if ( $this->title === null ) {
|
|
|
|
|
$this->title =
|
|
|
|
|
Title::newFromText( $this->getValidatedParams()['title'], NS_FILE ) ?? false;
|
|
|
|
|
}
|
|
|
|
|
return $this->title;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return File|bool File or false if unable to retrieve file
|
|
|
|
|
*/
|
|
|
|
|
private function getFile() {
|
|
|
|
|
if ( $this->file === null ) {
|
|
|
|
|
$title = $this->getTitle();
|
|
|
|
|
$this->file =
|
|
|
|
|
$this->repoGroup->findFile( $title, [ 'private' => $this->user ] ) ?? false;
|
|
|
|
|
}
|
|
|
|
|
return $this->file;
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-18 15:16:39 +00:00
|
|
|
/**
|
|
|
|
|
* @param string $title
|
|
|
|
|
* @return Response
|
|
|
|
|
* @throws LocalizedHttpException
|
|
|
|
|
*/
|
|
|
|
|
public function run( $title ) {
|
2020-03-16 20:52:39 +00:00
|
|
|
$titleObj = $this->getTitle();
|
|
|
|
|
$fileObj = $this->getFile();
|
|
|
|
|
|
2020-03-26 16:16:17 +00:00
|
|
|
if ( !$titleObj || !$titleObj->exists() ) {
|
2019-11-18 15:16:39 +00:00
|
|
|
throw new LocalizedHttpException(
|
2020-03-16 20:52:39 +00:00
|
|
|
MessageValue::new( 'rest-nonexistent-title' )->plaintextParams(
|
|
|
|
|
$titleObj->getPrefixedDBkey()
|
|
|
|
|
),
|
2019-11-18 15:16:39 +00:00
|
|
|
404
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( !$this->permissionManager->userCan( 'read', $this->user, $titleObj ) ) {
|
|
|
|
|
throw new LocalizedHttpException(
|
2020-03-16 20:52:39 +00:00
|
|
|
MessageValue::new( 'rest-permission-denied-title' )->plaintextParams(
|
|
|
|
|
$titleObj->getPrefixedDBkey()
|
|
|
|
|
),
|
2019-11-18 15:16:39 +00:00
|
|
|
403
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-26 16:16:17 +00:00
|
|
|
if ( !$fileObj || !$fileObj->exists() ) {
|
|
|
|
|
throw new LocalizedHttpException(
|
|
|
|
|
MessageValue::new( 'rest-cannot-load-file' )->plaintextParams(
|
|
|
|
|
$titleObj->getPrefixedDBkey()
|
|
|
|
|
),
|
|
|
|
|
404
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-16 20:52:39 +00:00
|
|
|
$response = $this->getResponse( $fileObj );
|
2019-11-18 15:16:39 +00:00
|
|
|
return $this->getResponseFactory()->createJson( $response );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2020-03-16 20:52:39 +00:00
|
|
|
* @param File $file the file to load media links for
|
2019-11-18 15:16:39 +00:00
|
|
|
* @return array response data
|
|
|
|
|
*/
|
2020-03-16 20:52:39 +00:00
|
|
|
private function getResponse( File $file ) : array {
|
2019-11-18 15:16:39 +00:00
|
|
|
list( $maxWidth, $maxHeight ) = self::getImageLimitsFromOption(
|
|
|
|
|
$this->user, 'imagesize'
|
|
|
|
|
);
|
|
|
|
|
list( $maxThumbWidth, $maxThumbHeight ) = self::getImageLimitsFromOption(
|
|
|
|
|
$this->user, 'thumbsize'
|
|
|
|
|
);
|
|
|
|
|
$transforms = [
|
|
|
|
|
'preferred' => [
|
|
|
|
|
'maxWidth' => $maxWidth,
|
|
|
|
|
'maxHeight' => $maxHeight
|
|
|
|
|
],
|
|
|
|
|
'thumbnail' => [
|
|
|
|
|
'maxWidth' => $maxThumbWidth,
|
|
|
|
|
'maxHeight' => $maxThumbHeight
|
|
|
|
|
]
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
return $this->getFileInfo( $file, $this->user, $transforms );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function needsWriteAccess() {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function getParamSettings() {
|
|
|
|
|
return [
|
|
|
|
|
'title' => [
|
|
|
|
|
self::PARAM_SOURCE => 'path',
|
|
|
|
|
ParamValidator::PARAM_TYPE => 'string',
|
|
|
|
|
ParamValidator::PARAM_REQUIRED => true,
|
|
|
|
|
],
|
|
|
|
|
];
|
|
|
|
|
}
|
2020-03-16 20:52:39 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return string|null
|
|
|
|
|
* @throws LocalizedHttpException
|
|
|
|
|
*/
|
|
|
|
|
protected function getETag(): ?string {
|
|
|
|
|
$file = $this->getFile();
|
|
|
|
|
if ( !$file || !$file->exists() ) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return '"' . $file->getSha1() . '"';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return string|null
|
|
|
|
|
* @throws LocalizedHttpException
|
|
|
|
|
*/
|
|
|
|
|
protected function getLastModified(): ?string {
|
|
|
|
|
$file = $this->getFile();
|
|
|
|
|
if ( !$file || !$file->exists() ) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $file->getTimestamp();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return bool
|
|
|
|
|
*/
|
|
|
|
|
protected function hasRepresentation() {
|
|
|
|
|
$file = $this->getFile();
|
|
|
|
|
return $file ? $file->exists() : false;
|
|
|
|
|
}
|
2019-11-18 15:16:39 +00:00
|
|
|
}
|