tao-test/app/taoMediaManager/controller/SharedStimulus.php

207 lines
6.9 KiB
PHP

<?php
/**
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; under version 2
* of the License (non-upgradable).
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Copyright (c) 2020-2021 (original work) Open Assessment Technologies SA;
*
*/
declare(strict_types=1);
namespace oat\taoMediaManager\controller;
use common_session_SessionManager;
use oat\oatbox\log\LoggerAwareTrait;
use oat\tao\model\accessControl\data\DataAccessControl;
use oat\tao\model\http\formatter\ResponseFormatter;
use oat\tao\model\http\response\ErrorJsonResponse;
use oat\tao\model\http\response\SuccessJsonResponse;
use oat\tao\model\resources\ResourceAccessDeniedException;
use oat\taoMediaManager\model\sharedStimulus\factory\CommandFactory;
use oat\taoMediaManager\model\sharedStimulus\factory\QueryFactory;
use oat\taoMediaManager\model\sharedStimulus\parser\JsonQtiAttributeParser;
use oat\taoMediaManager\model\sharedStimulus\repository\SharedStimulusRepository;
use oat\taoMediaManager\model\sharedStimulus\service\CreateService;
use oat\taoMediaManager\model\sharedStimulus\SharedStimulus as SharedStimulusObject;
use oat\taoMediaManager\model\sharedStimulus\service\PatchService;
use tao_actions_SaSModule;
use Throwable;
class SharedStimulus extends tao_actions_SaSModule
{
use LoggerAwareTrait;
private const PERMISSION_READ = 'READ';
/**
* @requiresRight classUri WRITE
*/
public function create(): void
{
$formatter = $this->getResponseFormatter()
->withJsonHeader();
try {
$command = $this->getCommandFactory()
->makeCreateCommandByRequest($this->getPsrRequest());
$this->validateWritePermission($command->getClassId());
$sharedStimulus = $this->getCreateService()
->create($command);
$this->renderSharedStimulus($formatter, $sharedStimulus);
} catch (Throwable $exception) {
$this->logError(sprintf('Error creating Shared Stimulus: %s', $exception->getMessage()));
$formatter->withStatusCode(400)
->withBody(new ErrorJsonResponse($exception->getCode(), $exception->getMessage()));
}
$this->setResponse($formatter->format($this->getPsrResponse()));
}
/**
* @requiresRight id READ
*/
public function get(): void
{
$formatter = $this->getResponseFormatter()
->withJsonHeader();
try {
$command = $this->getQueryFactory()
->makeFindQueryByRequest($this->getPsrRequest());
$this->validateReadPermission($command->getId());
$sharedStimulus = $this->getSharedStimulusRepository()
->find($command);
$this->renderSharedStimulus($formatter, $sharedStimulus);
} catch (Throwable $exception) {
$this->logError(sprintf('Error retrieving Shared Stimulus: %s', $exception->getMessage()));
$formatter->withStatusCode(400)
->withBody(new ErrorJsonResponse($exception->getCode(), $exception->getMessage()));
}
$this->setResponse($formatter->format($this->getPsrResponse()));
}
/**
* @requiresRight id WRITE
*/
public function patch(): void
{
$formatter = $this->getResponseFormatter()
->withJsonHeader();
try {
$request = $this->getPsrRequest();
$user = common_session_SessionManager::getSession()->getUser();
$id = $request->getQueryParams()['id'];
$body = json_decode((string)$request->getBody(), true)['body'];
$this->validateWritePermission($id);
$command = $this->getCommandFactory()->makePatchCommand($id, $body, $user);
$this->getPatchService()->patch($command);
$formatter->withBody(new SuccessJsonResponse([]));
} catch (Throwable $exception) {
$this->logError(sprintf('Error Updating Shared Stimulus: %s', $exception->getMessage()));
$formatter->withStatusCode(400)
->withBody(new ErrorJsonResponse($exception->getCode(), $exception->getMessage()));
}
$this->setResponse($formatter->format($this->getPsrResponse()));
}
private function renderSharedStimulus(ResponseFormatter $formatter, SharedStimulusObject $sharedStimulus): void
{
$data = $sharedStimulus->jsonSerialize();
if (isset($data['body'])) {
$data['body'] = $this->getSharedStimulusAttributesParser()->parse($sharedStimulus);
}
$data['permissions'] = $this->getPreviewPermission();
$formatter->withBody(new SuccessJsonResponse($data));
}
private function getPreviewPermission(): array
{
if ($this->hasAccess(MediaManager::class, 'getFile')) {
return [self::PERMISSION_READ];
}
return [];
}
private function getResponseFormatter(): ResponseFormatter
{
return $this->getServiceLocator()->get(ResponseFormatter::class);
}
private function getCommandFactory(): CommandFactory
{
return $this->getServiceLocator()->get(CommandFactory::class);
}
private function getQueryFactory(): QueryFactory
{
return $this->getServiceLocator()->get(QueryFactory::class);
}
private function getCreateService(): CreateService
{
return $this->getServiceLocator()->get(CreateService::class);
}
private function getPatchService(): PatchService
{
return $this->getServiceLocator()->get(PatchService::class);
}
private function getSharedStimulusRepository(): SharedStimulusRepository
{
return $this->getServiceLocator()->get(SharedStimulusRepository::class);
}
private function getSharedStimulusAttributesParser(): JsonQtiAttributeParser
{
return $this->getServiceLocator()->get(JsonQtiAttributeParser::class);
}
private function validateWritePermission(string $resourceId): void
{
if (!$this->hasWriteAccess($resourceId)) {
throw new ResourceAccessDeniedException($resourceId);
}
}
private function validateReadPermission(string $resourceId): void
{
$user = $this->getSession()->getUser();
$hasReadAccess = (new DataAccessControl())->hasPrivileges($user, [$resourceId => 'READ']);
if (!$hasReadAccess) {
throw new ResourceAccessDeniedException($resourceId);
}
}
}