Skip to content

Commit

Permalink
#7505 Support for JATS files/content added
Browse files Browse the repository at this point in the history
  • Loading branch information
defstat committed Dec 6, 2023
1 parent df63601 commit 3ba9171
Show file tree
Hide file tree
Showing 12 changed files with 697 additions and 7 deletions.
214 changes: 214 additions & 0 deletions api/v1/jats/PKPJatsController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
<?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\PublicationAccessPolicy;
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'] : 21;
$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
94 changes: 94 additions & 0 deletions classes/components/listPanels/JatsListPanel.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<?php
/**
* @file classes/components/listPanels/JatsListPanel.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 JatsListPanel
*
* @ingroup classes_components_list
*
* @brief A Panel component for viewing and managing publication's JATS Files
*/

namespace PKP\components\listPanels;

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 JatsListPanel extends ListPanel
{
public Submission $submission;
public Publication $publication;
public Context $context;

/** Whether the user can edit the current publication */
public bool $canEditPublication;

public function __construct(
string $id,
string $title,
Submission $submission,
Context $context,
bool $canEditPublication = false,
Publication $publication
) {
parent::__construct($id, $title);
$this->submission = $submission;
$this->context = $context;
$this->canEditPublication = $canEditPublication;
$this->publication = $publication;
}

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

// Remove some props not used in this list panel
unset($config['description']);
unset($config['expanded']);
unset($config['headingLevel']);

$config = array_merge(
$config,
[
'canEditPublication' => $this->canEditPublication,
'publicationApiUrlFormat' => $this->getPublicationUrlFormat(),
'uploadProgressLabel' => __('submission.upload.percentComplete'),
'fileStage' => SubmissionFile::SUBMISSION_FILE_JATS,
'i18nConfirmDeleteFileTitle' => __('publication.jats.confirmDeleteFileTitle'),
'i18nDeleteFileMessage' => __('publication.jats.confirmDeleteFileMessage'),
'i18nConfirmDeleteFileButton' => __('publication.jats.confirmDeleteFileButton'),
'i18nLastModifiedAt' => __('publication.jats.lastModified'),
'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'
);
}
}
45 changes: 45 additions & 0 deletions classes/jats/JatsFile.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?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\submissionFile\SubmissionFile;

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

public function __construct(
public int $publicationId,
public ?int $submissionId = null,
public ?SubmissionFile $submissionFile = null,
public array $genres = []
)
{
if ($submissionFile) {
$this->jatsContent = Repo::submissionFile()
->getSubmissionFileContent($submissionFile, $genres);

$this->isDefaultContent = false;
} else {
$this->jatsContent = Repo::jats()
->createDefaultJatsContent($publicationId, $submissionId);
}
}
}
Loading

0 comments on commit 3ba9171

Please sign in to comment.