Skip to content

Commit

Permalink
[PKP-LIB][main] #7505 Initial Commit Upload - Delete - Download JATS …
Browse files Browse the repository at this point in the history
…File (#9536)

* #7505 Support for JATS files/content added

* #7505 Review Fixes

* #7505 Remove locale keys as vue component props

* #7505 Remove new Jats Component dependency from ListPanel

* #7505 Handle Jats creation Errors

* #7505 Fix UI in error cases

* #7505 Remove JATS Component from PKPWorkflow

* #7505 Review Changes
  • Loading branch information
defstat authored Dec 18, 2023
1 parent 809a142 commit af8ad0f
Show file tree
Hide file tree
Showing 14 changed files with 757 additions and 7 deletions.
213 changes: 213 additions & 0 deletions api/v1/jats/PKPJatsController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
<?php

/**
* @file api/v1/jats/PKPJatsController.php
*
* Copyright (c) 2023 Simon Fraser University
* Copyright (c) 2023 John Willinsky
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
*
* @class PKPJatsController
*
* @ingroup api_v1_jats
*
* @brief Handle API requests for JATS File operations.
*
*/

namespace PKP\API\v1\jats;

use APP\core\Application;
use APP\facades\Repo;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Route;
use PKP\core\PKPBaseController;
use PKP\core\PKPRequest;
use PKP\db\DAORegistry;
use PKP\security\authorization\ContextAccessPolicy;
use PKP\security\authorization\internal\SubmissionFileStageAccessPolicy;
use PKP\security\authorization\PublicationWritePolicy;
use PKP\security\authorization\SubmissionFileAccessPolicy;
use PKP\security\authorization\UserRolesRequiredPolicy;
use PKP\security\Role;
use PKP\services\PKPSchemaService;
use PKP\submissionFile\SubmissionFile;

class PKPJatsController extends PKPBaseController
{
/**
* @copydoc \PKP\core\PKPBaseController::getHandlerPath()
*/
public function getHandlerPath(): string
{
return 'submissions/{submissionId}/publications/{publicationId}/jats';
}

/**
* @copydoc \PKP\core\PKPBaseController::getRouteGroupMiddleware()
*/
public function getRouteGroupMiddleware(): array
{
return [
'has.user',
'has.context',
];
}

public function getGroupRoutes(): void
{
Route::middleware([
self::roleAuthorizer([
Role::ROLE_ID_MANAGER,
Role::ROLE_ID_SITE_ADMIN,
Role::ROLE_ID_SUB_EDITOR,
Role::ROLE_ID_ASSISTANT,
Role::ROLE_ID_AUTHOR,
]),
])->group(function () {

Route::get('', $this->get(...))
->name('publication.jats.get');

Route::post('', $this->add(...))
->name('publication.jats.add');

Route::delete('', $this->delete(...))
->name('publication.jats.delete');

})->whereNumber(['submissionId', 'publicationId']);
}

/**
* @copydoc \PKP\core\PKPBaseController::authorize()
*/
public function authorize(PKPRequest $request, array &$args, array $roleAssignments): bool
{
$illuminateRequest = $args[0]; /** @var \Illuminate\Http\Request $illuminateRequest */
$actionName = static::getRouteActionName($illuminateRequest);

$this->addPolicy(new UserRolesRequiredPolicy($request), true);

$this->addPolicy(new ContextAccessPolicy($request, $roleAssignments));

$this->addPolicy(new PublicationWritePolicy($request, $args, $roleAssignments));

if ($actionName === 'add') {
$params = $illuminateRequest->input();
$fileStage = isset($params['fileStage']) ? (int) $params['fileStage'] : SubmissionFile::SUBMISSION_FILE_JATS;
$this->addPolicy(
new SubmissionFileStageAccessPolicy(
$fileStage,
SubmissionFileAccessPolicy::SUBMISSION_FILE_ACCESS_MODIFY,
'api.submissionFiles.403.unauthorizedFileStageIdWrite'
)
);
}

return parent::authorize($request, $args, $roleAssignments);
}

/**
* Get JATS XML Files
*/
public function get(Request $illuminateRequest): JsonResponse
{
$submission = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_SUBMISSION);
$publication = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_PUBLICATION);

if (!$publication) {
return response()->json([
'error' => __('api.404.resourceNotFound'),
], Response::HTTP_NOT_FOUND);
}

$context = Application::get()->getRequest()->getContext();
$genreDao = DAORegistry::getDAO('GenreDAO');
$genres = $genreDao->getEnabledByContextId($context->getId());

$jatsFile = Repo::jats()
->getJatsFile($publication->getId(), $submission->getId(), $genres->toArray());

$jatsFilesProp = Repo::jats()
->summarize($jatsFile);

return response()->json($jatsFilesProp, Response::HTTP_OK);
}

/**
* Add a JATS XML Submission File to a publication
*/
public function add(Request $illuminateRequest): JsonResponse
{
$submission = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_SUBMISSION);
$publication = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_PUBLICATION);

if (empty($_FILES)) {
return response()->json([
'error' => __('api.files.400.noUpload'),
], Response::HTTP_BAD_REQUEST);
}

if ($_FILES['file']['error'] !== UPLOAD_ERR_OK) {
return $this->getUploadErrorResponse($_FILES['file']['error']);
}

$params = $this->convertStringsToSchema(PKPSchemaService::SCHEMA_SUBMISSION_FILE, $illuminateRequest->input());

Repo::jats()
->addJatsFile(
$_FILES['file']['tmp_name'],
$_FILES['file']['name'],
$publication->getId(),
$submission->getId(),
SubmissionFile::SUBMISSION_FILE_JATS,
$params);

$context = Application::get()->getRequest()->getContext();
$genreDao = DAORegistry::getDAO('GenreDAO');
$genres = $genreDao->getEnabledByContextId($context->getId());

$jatsFile = Repo::jats()
->getJatsFile($publication->getId(), $submission->getId(), $genres->toArray());

$jatsFilesProp = Repo::jats()
->summarize($jatsFile);

return response()->json($jatsFilesProp, Response::HTTP_OK);
}

/**
* Delete the publication's JATS Submission file
*/
public function delete(Request $illuminateRequest): JsonResponse
{
$submission = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_SUBMISSION);
$publication = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_PUBLICATION);

$context = Application::get()->getRequest()->getContext();
$genreDao = DAORegistry::getDAO('GenreDAO');
$genres = $genreDao->getEnabledByContextId($context->getId());

$jatsFile = Repo::jats()
->getJatsFile($publication->getId(), $submission->getId(), $genres->toArray());

if (!$jatsFile->submissionFile) {
return response()->json([
'error' => __('api.404.resourceNotFound'),
], Response::HTTP_NOT_FOUND);
}

Repo::submissionFile()
->delete($jatsFile->submissionFile);

$jatsFile = Repo::jats()
->getJatsFile($publication->getId(), $submission->getId(), $genres->toArray());

$jatsFilesProp = Repo::jats()
->summarize($jatsFile);

return response()->json($jatsFilesProp, Response::HTTP_OK);
}
}
9 changes: 5 additions & 4 deletions api/v1/submissions/PKPSubmissionController.php
Original file line number Diff line number Diff line change
Expand Up @@ -292,9 +292,6 @@ public function getGroupRoutes(): void
]);
}




/**
* @copydoc \PKP\core\PKPBaseController::authorize()
*/
Expand Down Expand Up @@ -838,6 +835,7 @@ public function getParticipants(Request $illuminateRequest): JsonResponse
$request = Application::get()->getRequest();
$context = $request->getContext();
$submission = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_SUBMISSION);
$args = $illuminateRequest->input();
$stageId = $args['stageId'] ?? null;

if (!$submission || $submission->getData('contextId') !== $context->getId()) {
Expand Down Expand Up @@ -1591,8 +1589,11 @@ public function saveContributorsOrder(Request $illuminateRequest): JsonResponse
->filterByPublicationIds([$publication->getId()])
->getMany();

$authorsArray = Repo::author()->getSchemaMap()->summarizeMany($authors)->toArray();
$indexedArray = array_values($authorsArray);

return response()->json(
Repo::author()->getSchemaMap()->summarizeMany($authors),
$indexedArray,
Response::HTTP_OK
);
}
Expand Down
74 changes: 74 additions & 0 deletions classes/components/PublicationSectionJats.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<?php
/**
* @file classes/components/PublicationSectionJats.php
*
* Copyright (c) 2014-2021 Simon Fraser University
* Copyright (c) 2000-2021 John Willinsky
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
*
* @class PublicationSectionJats
*
* @ingroup classes_components
*
* @brief A Panel component for viewing and managing publication's JATS Files
*/

namespace PKP\components;

use APP\core\Application;
use APP\facades\Repo;
use APP\publication\Publication;
use APP\submission\Submission;
use PKP\context\Context;
use PKP\submissionFile\SubmissionFile;

class PublicationSectionJats
{
public function __construct(
public string $id,
public string $title,
public Submission $submission,
public Context $context,
public bool $canEditPublication = false,
public Publication $publication
) {
}

/**
* @copydoc ListPanel::getConfig()
*/
public function getConfig()
{
$config = [];

$config = array_merge(
$config,
[
'title' => $this->title,
'id' => $this->id,
'canEditPublication' => $this->canEditPublication,
'publicationApiUrlFormat' => $this->getPublicationUrlFormat(),
'fileStage' => SubmissionFile::SUBMISSION_FILE_JATS,
'downloadDefaultJatsFileName' => Repo::jats()->getDefaultJatsFileName($this->publication->getId()),
]
);

return $config;
}

/**
* Get an example of the url to a publication's API endpoint,
* with a placeholder instead of the publication id, eg:
*
* http://example.org/api/v1/submissions/1/publications/{$publicationId}
*/
protected function getPublicationUrlFormat(): string
{
return Application::get()->getRequest()->getDispatcher()->url(
Application::get()->getRequest(),
Application::ROUTE_API,
$this->context->getPath(),
'submissions/' . $this->submission->getId() . '/publications/{$publicationId}/jats'
);
}
}
53 changes: 53 additions & 0 deletions classes/jats/JatsFile.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php

/**
* @file classes/jats/JatsFile.php
*
* Copyright (c) 2014-2021 Simon Fraser University
* Copyright (c) 2003-2021 John Willinsky
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
*
* @class JatsFile
*
* @ingroup jats
*
* @brief JatsFile file class.
*/

namespace PKP\jats;

use APP\facades\Repo;
use PKP\jats\exceptions\UnableToCreateJATSContentException;
use PKP\submissionFile\exceptions\UnableToCreateFileContentException;
use PKP\submissionFile\SubmissionFile;

class JatsFile
{
public ?string $loadingContentError = null;
public ?string $jatsContent = null;
public bool $isDefaultContent = true;
public array $props = [];

public function __construct(
public int $publicationId,
public ?int $submissionId = null,
public ?SubmissionFile $submissionFile = null,
public array $genres = []
)
{
try {
if ($submissionFile) {
$this->isDefaultContent = false;

$this->jatsContent = Repo::submissionFile()
->getSubmissionFileContent($submissionFile);
} else {
$this->jatsContent = Repo::jats()
->createDefaultJatsContent($publicationId, $submissionId);
}
} catch (UnableToCreateFileContentException | UnableToCreateJATSContentException $e) {
$this->loadingContentError = $e->getMessage();
}

}
}
Loading

0 comments on commit af8ad0f

Please sign in to comment.