Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PKP-LIB][main] #4860 Add JAV support to publications #10666

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 77 additions & 1 deletion api/v1/submissions/PKPSubmissionController.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
use PKP\notification\NotificationSubscriptionSettingsDAO;
use PKP\plugins\Hook;
use PKP\plugins\PluginRegistry;
use PKP\publication\enums\JavStage;
use PKP\security\authorization\ContextAccessPolicy;
use PKP\security\authorization\DecisionWritePolicy;
use PKP\security\authorization\internal\SubmissionCompletePolicy;
Expand Down Expand Up @@ -111,7 +112,10 @@ class PKPSubmissionController extends PKPBaseController
'getPublicationIdentifierForm',
'getPublicationLicenseForm',
'getPublicationTitleAbstractForm',
'getChangeLanguageMetadata'
'getChangeLanguageMetadata',
'getJAVStageMetadata',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's inconsistency between these two lines on JAV vs. Jav; I don't have a strong preference but they should be consistent. In any case, I think it would be better to avoid the acronym, as most won't be familiar with it. And listing stage and numbering in the API name is overspecific. Instead, maybe changeVersionData?

'changeJavStageAndNumbering',
'getNextAvailableJavVersionNumberingForStage',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As above, maybe getNextAvailableVersionData?

];

/** @var array Handlers that must be authorized to write to a publication */
Expand All @@ -122,6 +126,7 @@ class PKPSubmissionController extends PKPBaseController
'editContributor',
'saveContributorsOrder',
'changeLocale',
'changeJavStageAndNumbering'
];

/** @var array Handlers that must be authorized to access a submission's production stage */
Expand Down Expand Up @@ -236,6 +241,14 @@ public function getGroupRoutes(): void
Route::put('{submissionId}/publications/{publicationId}/changeLocale', $this->changeLocale(...))
->name('submission.publication.changeLocale')
->whereNumber(['submissionId', 'publicationId']);

Route::put('{submissionId}/publications/{publicationId}/changeJavStageAndNumbering', $this->changeJavStageAndNumbering(...))
->name('submission.publication.changeJavStageAndNumbering')
->whereNumber(['submissionId', 'publicationId']);

Route::get('{submissionId}/getNextAvailableJavVersionNumberingForStage', $this->getNextAvailableJavVersionNumberingForStage(...))
->name('submission.getNextAvailableJavVersionNumberingForStage')
->whereNumber(['submissionId']);
});

Route::middleware([
Expand Down Expand Up @@ -301,6 +314,7 @@ public function getGroupRoutes(): void
Route::get('reference', $this->getPublicationReferenceForm(...))->name('submission.publication._components.reference');
Route::get('titleAbstract', $this->getPublicationTitleAbstractForm(...))->name('submission.publication._components.titleAbstract');
Route::get('changeLanguageMetadata', $this->getChangeLanguageMetadata(...))->name('submission.publication._components.changeLanguageMetadata');
Route::get('getJAVStageMetadata', $this->getJAVStageMetadata(...))->name('submission.publication._components.getJAVStageMetadata');
})->whereNumber(['submissionId', 'publicationId']);
});

Expand Down Expand Up @@ -943,6 +957,68 @@ public function changeLocale(Request $illuminateRequest): JsonResponse
return $this->edit($illuminateRequest);
}

/**
* Change version stage
*/
public function changeJavStageAndNumbering(Request $illuminateRequest): JsonResponse
{
$request = $this->getRequest();
$publication = Repo::publication()->get((int) $illuminateRequest->route('publicationId'));

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

// $submission = Repo::submission()->get((int) $illuminateRequest->route('submissionId'));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dead code should be removed

$submission = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_SUBMISSION);

if ($submission->getId() !== $publication->getData('submissionId')) {
return response()->json([
'error' => __('api.publications.403.submissionsDidNotMatch'),
], Response::HTTP_FORBIDDEN);
}

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

$submissionContext = $request->getContext();

$errors = Repo::publication()->validate($publication, $params, $submission, $submissionContext);

if (!empty($errors)) {
return response()->json($errors, Response::HTTP_BAD_REQUEST);
}

$versionStage = $params['javVersionStage'];
$versionStageIsMinor = (bool) $params['javVersionIsMinor'];

Repo::publication()->updateJavVersionStageAndNumbering($publication, JavStage::from($versionStage), $versionStageIsMinor);

return $this->edit($illuminateRequest);
}

/**
* Get next potential JAV version stage
*/
public function getNextAvailableJavVersionNumberingForStage(Request $illuminateRequest): JsonResponse
{
$submission = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_SUBMISSION);

$params = $illuminateRequest->input();
$potentialVersionStage = JavStage::from($params['javVersionStage']);
$potentialIsMinor = ($params['javVersionIsMinor'] === 'false') ? false : (bool) $params['javVersionIsMinor'];

$potentialVersionStage = $submission->getNextAvailableJavVersionNumberingForStage($potentialVersionStage, $potentialIsMinor);

$retValue = $potentialVersionStage->getVersionStageDisplay();

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

/**
* Get the decisions recorded on a submission
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php

/**
* @file classes/migration/upgrade/v3_5_0/I4860_AddJavStageDataToPublication.php
*
* Copyright (c) 2024 Simon Fraser University
* Copyright (c) 2024 John Willinsky
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
*
* @class I4860_AddJavStageDataToPublication
*
* @brief Add columns for JAV Versioning and migrate existing data
*/

namespace PKP\migration\upgrade\v3_5_0;

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
use PKP\migration\Migration;
use PKP\publication\enums\JavStage;
use PKP\publication\helpers\JavStageAndNumbering;

class I4860_AddJavStageDataToPublication extends Migration
{
/**
* Run the migration.
*/
public function up(): void
{
Schema::table('publications', function (Blueprint $table) {
// Adding the enum column for VersionStage
$table->enum('jav_version_stage', array_column(JavStage::cases(), 'value'))
->default(JavStage::VERSION_OF_RECORD);

// Adding minorVersion and majorVersion as integers
$table->integer('jav_version_minor')
->default(JavStageAndNumbering::JAV_DEFAULT_NUMBERING_MINOR);

$table->integer('jav_version_major')
->default(JavStageAndNumbering::JAV_DEFAULT_NUMBERING_MAJOR);
});

// Update the version_major column based on the version column
DB::table('publications')->update([
'jav_version_major' => DB::raw('version')
]);
}

/**
* Reverses the migration
*/
public function down(): void
{
Schema::table('publications', function (Blueprint $table) {
$table->dropColumn(['jav_version_stage', 'jav_version_minor', 'jav_version_major']);
});
}
}
47 changes: 46 additions & 1 deletion classes/publication/PKPPublication.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@
use PKP\core\Core;
use PKP\core\PKPString;
use PKP\facades\Locale;
use PKP\i18n\LocaleMetadata;
use PKP\publication\enums\JavStage;
use PKP\publication\helpers\JavStageAndNumbering;
use PKP\services\PKPSchemaService;
use PKP\userGroup\UserGroup;

Expand Down Expand Up @@ -470,6 +471,50 @@ public function getLanguages(?array ...$additionalLocales): array
->values()
->toArray();
}

/**
* Get the JAV string that describes the
* given publication.
*/
public function getJavStageAndNumberingDisplay(): ?string
{
$currentVersionStage = $this->getCurrentVersionStage();
if (!isset($currentVersionStage)) {
return null;
}

return $currentVersionStage->getVersionStageDisplay();
}

/**
* Get the current JAV stage object that describes the
* given publication version.
*/
public function getCurrentVersionStage(): ?JavStageAndNumbering
{
$versionStageStr = $this->getData('javVersionStage');
if (!isset($versionStageStr)) {
return null;
}

$versionStage = new JavStageAndNumbering();
$versionStage->javStage = JavStage::from($versionStageStr);
$versionStage->javVersionMajor = $this->getData('javVersionMajor');
$versionStage->javVersionMinor = $this->getData('javVersionMinor');

return $versionStage;
}

/**
* Set the current JAV stage of the publication
* given a JavStageAndNumbering object
*/
public function setVersionStage(JavStageAndNumbering $versionStage): void
{
$this->setData('javVersionStage', $versionStage->javStage->value);
$this->setData('javVersionMajor', $versionStage->javVersionMajor);
$this->setData('javVersionMinor', $versionStage->javVersionMinor);
}
}
if (!PKP_STRICT_MODE) {
class_alias('\PKP\publication\PKPPublication', '\PKPPublication');
Expand Down
47 changes: 45 additions & 2 deletions classes/publication/Repository.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
use PKP\observers\events\PublicationUnpublished;
use PKP\orcid\OrcidManager;
use PKP\plugins\Hook;
use PKP\publication\enums\JavStage;
use PKP\security\Validation;
use PKP\services\PKPSchemaService;
use PKP\submission\Genre;
Expand Down Expand Up @@ -335,6 +336,19 @@ public function version(Publication $publication): int
$newPublication->setData('datePublished', null);
$newPublication->setData('status', Submission::STATUS_QUEUED);
$newPublication->setData('version', $publication->getData('version') + 1);

// VersionStage Update
$currentVersionStage = $newPublication->getCurrentVersionStage();

if (isset($currentVersionStage)) {
$submission = Repo::submission()->get($publication->getData('submissionId'));

$newVersionStage = $submission->getNextAvailableJavVersionNumberingForStage($currentVersionStage->javStage);
$newPublication->setVersionStage($newVersionStage);

$newPublication->setData('versionDescription', null);
}

$newPublication->stampModified();

$request = Application::get()->getRequest();
Expand Down Expand Up @@ -380,8 +394,6 @@ public function version(Publication $publication): int

Hook::call('Publication::version', [&$newPublication, $publication]);

$submission = Repo::submission()->get($newPublication->getData('submissionId'));

$eventLog = Repo::eventLog()->newDataObject([
'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
'assocId' => $submission->getId(),
Expand Down Expand Up @@ -662,6 +674,37 @@ public function delete(Publication $publication)
Hook::call('Publication::delete', [&$publication]);
}

/**
* Given a JAV Stage and a flag of whether the Version isMinor,
* the publication's related data is being updated
*
* @hook 'Publication::updateJavVersionStageAndNumbering::before' [[ &$newPublication, $publication ]]
*/
public function updateJavVersionStageAndNumbering(Publication $publication, JavStage $versioningStage, bool $isMinor = true): Publication
{
$submission = Repo::submission()->get($publication->getData('submissionId'));
$nextAvailableVersionStage = $submission->getNextAvailableJavVersionNumberingForStage($versioningStage, $isMinor);

$newPublication = clone $publication;
$newPublication->setData('javVersionIsMinor', $isMinor);
$newPublication->setVersionStage($nextAvailableVersionStage);

$newPublication->stampModified();
Hook::call(
'Publication::updateJavVersionStageAndNumbering::before',
[
&$newPublication,
$publication
]
);

$this->dao->update($newPublication);

$newPublication = Repo::publication()->get($newPublication->getId());

return $newPublication;
}

/**
* Handle a publication setting for an uploaded file
*
Expand Down
24 changes: 24 additions & 0 deletions classes/publication/enums/JavStage.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

/**
* @file publication/enums/JavStage.php
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because this refers to an external standard, it would be good to add a URL to where it's specified.

*
* Copyright (c) 2023-2024 Simon Fraser University
* Copyright (c) 2023-2024 John Willinsky
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
*
* @class JavStage
*
* @brief Enumeration for JAV versioning stages
*/

namespace PKP\publication\enums;

enum JavStage: string
{
case AUTHOR_ORIGINAL = 'AO';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While these are fine to use in the codebase, we should be careful not to present them straight to the front end without having them map to translatable locale keys.

case ACCEPTED_MANUSCRIPT = 'AM';
case SUBMITTED_MANUSCRIPT = 'SM';
case PROOF = 'PF';
case VERSION_OF_RECORD = 'VoR';
}
35 changes: 35 additions & 0 deletions classes/publication/helpers/JavStageAndNumbering.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

/**
* @file classes/publication/JavStageAndNumbering.php
*
* Copyright (c) 2016-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 JavStageAndNumbering
*
* @brief Base class for JavStageAndNumbering.
*/

namespace PKP\publication\helpers;

use PKP\publication\enums\JavStage;

class JavStageAndNumbering extends \PKP\core\DataObject
{
public const JAV_DEFAULT_NUMBERING_MINOR = 0;
public const JAV_DEFAULT_NUMBERING_MAJOR = 1;

public JavStage $javStage;
public int $javVersionMajor;
public int $javVersionMinor;

public function getVersionStageDisplay(): string
{
$versionStageValue = $this->javStage->value;

return "$versionStageValue $this->javVersionMajor.$this->javVersionMinor";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably be localized.

}
}

3 changes: 3 additions & 0 deletions classes/publication/maps/Schema.php
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,9 @@ function ($citation) {
case 'fullTitle':
$output[$prop] = $publication->getFullTitles('html');
break;
case 'javStageDisplay':
$output[$prop] = $publication->getJavStageAndNumberingDisplay();
break;
default:
$output[$prop] = $publication->getData($prop);
break;
Expand Down
Loading