Skip to content

Commit 93a5546

Browse files
authored
Merge pull request #11431 from Hafsa-Naeem/i10263-main-fix
#10263 Relax editing metadata on published/posted materials
2 parents 700868c + 97d69f4 commit 93a5546

File tree

9 files changed

+56
-50
lines changed

9 files changed

+56
-50
lines changed

api/v1/submissions/PKPSubmissionController.php

Lines changed: 21 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,9 @@
7777
use PKP\submission\reviewAssignment\ReviewAssignment;
7878
use PKP\submissionFile\SubmissionFile;
7979
use PKP\userGroup\UserGroup;
80+
use PKP\observers\events\MetadataChanged;
81+
use PKP\stageAssignment\StageAssignment;
82+
8083

8184
class PKPSubmissionController extends PKPBaseController
8285
{
@@ -1337,16 +1340,12 @@ public function editPublication(Request $illuminateRequest): JsonResponse
13371340
], Response::HTTP_FORBIDDEN);
13381341
}
13391342

1340-
// Publications can not be edited when they are published
1341-
if ($publication->getData('status') === PKPPublication::STATUS_PUBLISHED) {
1342-
return response()->json([
1343-
'error' => __('api.publication.403.cantEditPublished'),
1344-
], Response::HTTP_FORBIDDEN);
1345-
}
1346-
1347-
// Prevent users from editing publications if they do not have permission. Except for admins.
1343+
// only proceed if user is allowed to edit publications
13481344
$userRoles = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_USER_ROLES);
1349-
if (!in_array(Role::ROLE_ID_SITE_ADMIN, $userRoles) && !Repo::submission()->canEditPublication($submission->getId(), $currentUser->getId())) {
1345+
if (
1346+
!in_array(Role::ROLE_ID_SITE_ADMIN, $userRoles) &&
1347+
!Repo::submission()->canEditPublication($submission->getId(), $currentUser->getId())
1348+
) {
13501349
return response()->json([
13511350
'error' => __('api.submissions.403.userCantEdit'),
13521351
], Response::HTTP_FORBIDDEN);
@@ -1396,6 +1395,8 @@ public function editPublication(Request $illuminateRequest): JsonResponse
13961395

13971396
Repo::publication()->edit($publication, $params);
13981397
$publication = Repo::publication()->get($publication->getId());
1398+
event(new MetadataChanged($submission));
1399+
13991400

14001401
$userGroups = UserGroup::withContextIds($submission->getData('contextId'))->cursor();
14011402

@@ -1455,6 +1456,17 @@ public function publishPublication(Request $illuminateRequest): JsonResponse
14551456

14561457
Repo::publication()->publish($publication);
14571458

1459+
$stageAssignments = StageAssignment::withSubmissionIds([$submission->getId()])
1460+
->get();
1461+
1462+
foreach ($stageAssignments as $stageAssignment) {
1463+
$userGroup = $stageAssignment->userGroup;
1464+
if ($userGroup && $userGroup->roleId === Role::ROLE_ID_AUTHOR){
1465+
$stageAssignment->canChangeMetadata = 0;
1466+
$stageAssignment->save();
1467+
}
1468+
}
1469+
14581470
$publication = Repo::publication()->get($publication->getId());
14591471

14601472
$userGroups = UserGroup::withContextIds($submission->getData('contextId'))->cursor();
@@ -1745,12 +1757,6 @@ public function deleteContributor(Request $illuminateRequest): JsonResponse
17451757
], Response::HTTP_NOT_FOUND);
17461758
}
17471759

1748-
// Publications can not be edited when they are published
1749-
if ($publication->getData('status') === PKPPublication::STATUS_PUBLISHED) {
1750-
return response()->json([
1751-
'error' => __('api.publication.403.cantEditPublished'),
1752-
], Response::HTTP_FORBIDDEN);
1753-
}
17541760

17551761
if ($submission->getId() !== $publication->getData('submissionId')) {
17561762
return response()->json([
@@ -1807,13 +1813,6 @@ public function editContributor(Request $illuminateRequest): JsonResponse
18071813
], Response::HTTP_FORBIDDEN);
18081814
}
18091815

1810-
// Publications can not be edited when they are published
1811-
if ($publication->getData('status') === PKPPublication::STATUS_PUBLISHED) {
1812-
return response()->json([
1813-
'error' => __('api.publication.403.cantEditPublished'),
1814-
], Response::HTTP_FORBIDDEN);
1815-
}
1816-
18171816
$params = $this->convertStringsToSchema(PKPSchemaService::SCHEMA_AUTHOR, $illuminateRequest->input());
18181817
$params['id'] = $author->getId();
18191818

@@ -1900,13 +1899,6 @@ public function saveContributorsOrder(Request $illuminateRequest): JsonResponse
19001899
], Response::HTTP_FORBIDDEN);
19011900
}
19021901

1903-
// Publications can not be edited when they are published
1904-
if ($publication->getData('status') === PKPPublication::STATUS_PUBLISHED) {
1905-
return response()->json([
1906-
'error' => __('api.publication.403.cantEditPublished'),
1907-
], Response::HTTP_FORBIDDEN);
1908-
}
1909-
19101902
if (!empty($params['sortedAuthors'])) {
19111903
$authors = [];
19121904
foreach ($params['sortedAuthors'] as $author) {

classes/author/Repository.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,6 @@ public function validate($author, $props, Submission $submission, Context $conte
138138
$publication = Repo::publication()->get($props['publicationId']);
139139
if (!$publication) {
140140
$validator->errors()->add('publicationId', __('author.publicationNotFound'));
141-
} elseif ($publication->getData('status') === PKPPublication::STATUS_PUBLISHED) {
142-
$validator->errors()->add('publicationId', __('author.editPublishedDisabled'));
143141
}
144142
}
145143
// userGroupId must be an Author group within the current context

classes/galley/Repository.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,8 +153,6 @@ public function validate(?Galley $object, array $props, array $allowedLocales, s
153153
$publication = Repo::publication()->get($props['publicationId']);
154154
if (!$publication) {
155155
$validator->errors()->add('publicationId', __('galley.publicationNotFound'));
156-
} elseif (in_array($publication->getData('status'), [Publication::STATUS_PUBLISHED, Publication::STATUS_SCHEDULED])) {
157-
$validator->errors()->add('publicationId', __('galley.editPublishedDisabled'));
158156
}
159157
}
160158
});

classes/security/authorization/PublicationWritePolicy.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,9 @@ public function __construct($request, &$args, $roleAssignments, $submissionIdPar
3737
// Can the user access this publication?
3838
$this->addPolicy(new PublicationAccessPolicy($request, $args, $roleAssignments, $submissionIdParameter, $publicationIdParameter));
3939

40-
// Is the user assigned to this submission in one of these roles, and does this role
41-
// have access to the _current_ stage of the submission?
42-
$this->addPolicy(new StageRolePolicy([Role::ROLE_ID_MANAGER, Role::ROLE_ID_SITE_ADMIN, Role::ROLE_ID_SUB_EDITOR, Role::ROLE_ID_ASSISTANT, Role::ROLE_ID_AUTHOR]));
40+
// only require stage assignment for non-privileged roles.
41+
// managers and Site Admins can edit without being participants.
42+
$this->addPolicy(new StageRolePolicy([Role::ROLE_ID_SUB_EDITOR, Role::ROLE_ID_ASSISTANT, Role::ROLE_ID_AUTHOR]));
4343

4444
// Can the user edit the publication?
4545
$this->addPolicy(new PublicationCanBeEditedPolicy($request, 'api.submissions.403.userCantEdit'));

classes/security/authorization/internal/RepresentationUploadAccessPolicy.php

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -90,12 +90,6 @@ public function dataObjectEffect()
9090
return AuthorizationPolicy::AUTHORIZATION_DENY;
9191
}
9292

93-
// Representations can not be modified on published publications
94-
if ($publication->getData('status') === PKPPublication::STATUS_PUBLISHED) {
95-
$this->setAdvice(AuthorizationPolicy::AUTHORIZATION_ADVICE_DENY_MESSAGE, 'galley.editPublishedDisabled');
96-
return AuthorizationPolicy::AUTHORIZATION_DENY;
97-
}
98-
9993
$this->addAuthorizedContextObject(Application::ASSOC_TYPE_REPRESENTATION, $representation);
10094

10195
return AuthorizationPolicy::AUTHORIZATION_PERMIT;

classes/submission/Repository.php

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -524,18 +524,39 @@ public function canCurrentUserDelete(Submission $submission): bool
524524
*/
525525
public function canEditPublication(int $submissionId, int $userId): bool
526526
{
527-
// Replaces StageAssignmentDAO::getBySubmissionAndUserIdAndStageId
528-
$stageAssignments = StageAssignment::withSubmissionIds([$submissionId])
527+
// block authors can never edit a published publication even if an editor granted them canChangeMetadata
528+
$assignments = StageAssignment::withSubmissionIds([$submissionId])
529529
->withUserId($userId)
530530
->get();
531531

532-
// Check for permission from stage assignments
533-
if ($stageAssignments->contains(fn ($stageAssignment) => $stageAssignment->canChangeMetadata)) {
532+
$submission = $this->get($submissionId);
533+
534+
// if user has no stage assigments, check if user can edit anyway ie. is manager
535+
$context = Application::get()->getRequest()->getContext();
536+
if ($this->_canUserAccessUnassignedSubmissions($context->getId(), $userId)) {
537+
return true;
538+
}
539+
540+
// any published or scheduled then probe
541+
$hasLockedPublication = $submission?->getData('publications')
542+
->contains(
543+
fn (Publication $p) =>
544+
in_array(
545+
$p->getData('status'),
546+
[Submission::STATUS_PUBLISHED, Submission::STATUS_SCHEDULED]
547+
)
548+
);
549+
550+
if ($hasLockedPublication && !$assignments->contains(fn (StageAssignment $sa) => $sa->userGroup && $sa->userGroup->roleId != Role::ROLE_ID_AUTHOR)) {
551+
return false;
552+
}
553+
554+
if ($assignments->contains(fn($sa) => $sa->canChangeMetadata)) {
534555
return true;
535556
}
536557
// If user has no stage assigments, check if user can edit anyway ie. is manager
537558
$context = Application::get()->getRequest()->getContext();
538-
if ($stageAssignments->isEmpty() && $this->_canUserAccessUnassignedSubmissions($context->getId(), $userId)) {
559+
if ($assignments->isEmpty() && $this->_canUserAccessUnassignedSubmissions($context->getId(), $userId)) {
539560
return true;
540561
}
541562
// Else deny access

classes/task/PublishSubmissions.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
use APP\submission\Submission;
2121
use PKP\core\Core;
2222
use PKP\scheduledTask\ScheduledTask;
23+
use PKP\observers\events\MetadataChanged;
2324

2425
class PublishSubmissions extends ScheduledTask
2526
{
@@ -50,6 +51,8 @@ public function executeActions(): bool
5051
$datePublished = $submission->getCurrentPublication()->getData('datePublished');
5152
if ($datePublished && strtotime($datePublished) <= strtotime(Core::getCurrentDate())) {
5253
Repo::publication()->publish($submission->getCurrentPublication());
54+
// dispatch the MetadataChanged event after publishing
55+
event(new MetadataChanged($submission));
5356
}
5457
}
5558
}

controllers/grid/users/author/AuthorGridHandler.php

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -276,9 +276,6 @@ public function canAdminister($user)
276276
$submission = $this->getSubmission();
277277
$userRoles = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_USER_ROLES);
278278

279-
if ($publication->getData('status') === PKPPublication::STATUS_PUBLISHED) {
280-
return false;
281-
}
282279

283280
if (in_array(Role::ROLE_ID_SITE_ADMIN, $userRoles)) {
284281
return true;

locale/en/submission.po

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ msgstr "Please provide a ROR affiliation or at least one affiliation name."
3939
msgid "author.affiliationNamePrimaryLocaleMissing"
4040
msgstr "Please provide affiliation name in the submission primary locale."
4141

42+
msgid "publication.editorEditWarning"
43+
msgstr "Warning: This version has been published. Editing it may impact the published content."
44+
4245
msgid "ror.nameRequired"
4346
msgstr "A ROR name is required."
4447

0 commit comments

Comments
 (0)