repo/rest-api/src/RouteHandlers/RemoveItemLabelRouteHandler.php
<?php declare( strict_types=1 );
namespace Wikibase\Repo\RestApi\RouteHandlers;
use MediaWiki\HookContainer\HookRunner;
use MediaWiki\MediaWikiServices;
use MediaWiki\Rest\Handler;
use MediaWiki\Rest\RequestInterface;
use MediaWiki\Rest\Response;
use MediaWiki\Rest\ResponseInterface;
use MediaWiki\Rest\SimpleHandler;
use MediaWiki\Rest\StringStream;
use MediaWiki\Rest\Validator\Validator;
use Wikibase\Repo\RestApi\Application\UseCases\ItemRedirect;
use Wikibase\Repo\RestApi\Application\UseCases\RemoveItemLabel\RemoveItemLabel;
use Wikibase\Repo\RestApi\Application\UseCases\RemoveItemLabel\RemoveItemLabelRequest;
use Wikibase\Repo\RestApi\Application\UseCases\UseCaseError;
use Wikibase\Repo\RestApi\RouteHandlers\Middleware\AuthenticationMiddleware;
use Wikibase\Repo\RestApi\RouteHandlers\Middleware\BotRightCheckMiddleware;
use Wikibase\Repo\RestApi\RouteHandlers\Middleware\MiddlewareHandler;
use Wikibase\Repo\RestApi\RouteHandlers\Middleware\TempUserCreationResponseHeaderMiddleware;
use Wikibase\Repo\RestApi\RouteHandlers\Middleware\UserAgentCheckMiddleware;
use Wikibase\Repo\RestApi\WbRestApi;
use Wikimedia\ParamValidator\ParamValidator;
/**
* @license GPL-2.0-or-later
*/
class RemoveItemLabelRouteHandler extends SimpleHandler {
use AssertValidTopLevelFields;
private const ITEM_ID_PATH_PARAM = 'item_id';
private const LANGUAGE_CODE_PATH_PARAM = 'language_code';
private const TAGS_BODY_PARAM = 'tags';
private const BOT_BODY_PARAM = 'bot';
private const COMMENT_BODY_PARAM = 'comment';
private const TAGS_PARAM_DEFAULT = [];
private const BOT_PARAM_DEFAULT = false;
private const COMMENT_PARAM_DEFAULT = null;
private RemoveItemLabel $removeItemLabel;
private MiddlewareHandler $middlewareHandler;
private ResponseFactory $responseFactory;
public function __construct(
RemoveItemLabel $removeItemLabel,
MiddlewareHandler $middlewareHandler,
ResponseFactory $responseFactory
) {
$this->removeItemLabel = $removeItemLabel;
$this->middlewareHandler = $middlewareHandler;
$this->responseFactory = $responseFactory;
}
public static function factory(): Handler {
$responseFactory = new ResponseFactory();
return new self(
WbRestApi::getRemoveItemLabel(),
new MiddlewareHandler( [
WbRestApi::getUnexpectedErrorHandlerMiddleware(),
new UserAgentCheckMiddleware(),
new AuthenticationMiddleware( MediaWikiServices::getInstance()->getUserIdentityUtils() ),
new BotRightCheckMiddleware( MediaWikiServices::getInstance()->getPermissionManager(), $responseFactory ),
WbRestApi::getPreconditionMiddlewareFactory()->newPreconditionMiddleware(
fn( RequestInterface $request ): string => $request->getPathParam( self::ITEM_ID_PATH_PARAM )
),
new TempUserCreationResponseHeaderMiddleware( new HookRunner( MediaWikiServices::getInstance()->getHookContainer() ) ),
] ),
$responseFactory
);
}
/**
* @param mixed ...$args
*/
public function run( ...$args ): Response {
return $this->middlewareHandler->run( $this, [ $this, 'runUseCase' ], $args );
}
public function runUseCase( string $itemId, string $languageCode ): Response {
$requestBody = $this->getValidatedBody();
try {
$this->removeItemLabel->execute(
new RemoveItemLabelRequest(
$itemId,
$languageCode,
$requestBody[ self::TAGS_BODY_PARAM ] ?? self::TAGS_PARAM_DEFAULT,
$requestBody[ self::BOT_BODY_PARAM ] ?? self::BOT_PARAM_DEFAULT,
$requestBody[ self::COMMENT_BODY_PARAM ] ?? self::COMMENT_PARAM_DEFAULT,
$this->getUsername()
)
);
} catch ( UseCaseError $e ) {
return $this->responseFactory->newErrorResponseFromException( $e );
} catch ( ItemRedirect $e ) {
return $this->responseFactory->newErrorResponse(
UseCaseError::ITEM_REDIRECTED,
"Item $itemId has been redirected to {$e->getRedirectTargetId()}.",
[ UseCaseError::CONTEXT_REDIRECT_TARGET => $e->getRedirectTargetId() ]
);
}
return $this->newSuccessHttpResponse();
}
private function newSuccessHttpResponse(): Response {
$httpResponse = $this->getResponseFactory()->create();
$httpResponse->setStatus( 200 );
$httpResponse->setHeader( 'Content-Type', 'application/json' );
$httpResponse->setHeader( 'Content-Language', 'en' );
$httpResponse->setBody( new StringStream( '"Label deleted"' ) );
return $httpResponse;
}
public function validate( Validator $restValidator ): void {
$this->assertValidTopLevelTypes( $this->getRequest()->getParsedBody(), $this->getBodyParamSettings() );
parent::validate( $restValidator );
}
public function getParamSettings(): array {
return [
self::ITEM_ID_PATH_PARAM => [
self::PARAM_SOURCE => 'path',
ParamValidator::PARAM_TYPE => 'string',
ParamValidator::PARAM_REQUIRED => true,
],
self::LANGUAGE_CODE_PATH_PARAM => [
self::PARAM_SOURCE => 'path',
ParamValidator::PARAM_TYPE => 'string',
ParamValidator::PARAM_REQUIRED => true,
],
];
}
public function getBodyParamSettings(): array {
return [
self::TAGS_BODY_PARAM => [
self::PARAM_SOURCE => 'body',
ParamValidator::PARAM_TYPE => 'array',
ParamValidator::PARAM_REQUIRED => false,
ParamValidator::PARAM_DEFAULT => self::TAGS_PARAM_DEFAULT,
],
self::BOT_BODY_PARAM => [
self::PARAM_SOURCE => 'body',
ParamValidator::PARAM_TYPE => 'boolean',
ParamValidator::PARAM_REQUIRED => false,
ParamValidator::PARAM_DEFAULT => self::BOT_PARAM_DEFAULT,
],
self::COMMENT_BODY_PARAM => [
self::PARAM_SOURCE => 'body',
ParamValidator::PARAM_TYPE => 'string',
ParamValidator::PARAM_REQUIRED => false,
ParamValidator::PARAM_DEFAULT => self::COMMENT_PARAM_DEFAULT,
],
];
}
/**
* Preconditions are checked via {@link PreconditionMiddleware}
*/
public function checkPreconditions(): ?ResponseInterface {
return null;
}
private function getUsername(): ?string {
$mwUser = $this->getAuthority()->getUser();
return $mwUser->isRegistered() ? $mwUser->getName() : null;
}
}