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

I6528 jarda #10655

Open
wants to merge 3 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
73 changes: 73 additions & 0 deletions api/v1/_submissions/PKPBackendSubmissionsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
use APP\core\Application;
use APP\facades\Repo;
use APP\submission\Collector;
use APP\submission\Submission;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
Expand Down Expand Up @@ -87,6 +88,14 @@ public function getGroupRoutes(): void
),
]);

Route::delete('', $this->bulkDeleteIncompleteSubmissions(...))
->name('_submission.incomplete.delete')
->middleware([
self::roleAuthorizer([
Role::ROLE_ID_SITE_ADMIN,
]),
]);

Route::delete('{submissionId}', $this->delete(...))
->name('_submission.delete')
->middleware([
Expand Down Expand Up @@ -430,6 +439,70 @@ public function delete(Request $illuminateRequest): JsonResponse
return response()->json([], Response::HTTP_OK);
}

/**
* Delete a list of incomplete submissions
*/
public function bulkDeleteIncompleteSubmissions(Request $illuminateRequest): JsonResponse
{
$submissionIdsRaw = paramToArray($illuminateRequest->query('ids') ?? []);

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

$submissionIds = [];

foreach ($submissionIdsRaw as $id) {
$integerId = intval($id);

if (!$integerId) {
return response()->json([
'error' => __('api.submission.400.invalidId', ['id' => $id])
], Response::HTTP_BAD_REQUEST);
}

$submissionIds[] = $id;
}

$submissions = $this->getSubmissionCollector($illuminateRequest->query())
->filterBySubmissionIds($submissionIds)
->filterByIncomplete(true)
->getMany()
->all();

$submissionIdsFound = array_map(fn (Submission $submission) => $submission->getData('id'), $submissions);

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

$context = $this->getRequest()->getContext();

foreach ($submissions as $submission) {
if ($context->getId() != $submission->getData('contextId')) {
return response()->json([
'error' => __('api.submissions.403.deleteSubmissionOutOfContext'),
], Response::HTTP_FORBIDDEN);
}

if (!Repo::submission()->canCurrentUserDelete($submission)) {
return response()->json([
'error' => __('api.submissions.403.unauthorizedDeleteSubmission'),
], Response::HTTP_FORBIDDEN);
}
}

foreach ($submissions as $submission) {
Repo::submission()->delete($submission);
}

return response()->json([], Response::HTTP_OK);
}

/**
* Configure a submission Collector based on the query params
*/
Expand Down
16 changes: 16 additions & 0 deletions classes/submission/Collector.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ abstract class Collector implements CollectorInterface, ViewsCount
public DAO $dao;
public ?array $categoryIds = null;
public ?array $contextIds = null;
public ?array $submissionIds = null;
public ?int $count = null;
public ?int $daysInactive = null;
public bool $isIncomplete = false;
Expand Down Expand Up @@ -250,6 +251,17 @@ public function filterByRevisionsSubmitted(?bool $revisionsSubmitted): AppCollec
return $this;
}

/**
* Limit results to only submissions with the specified IDs
*
* @param ?int[] $submissionIds Submission IDs
*/
public function filterBySubmissionIds(?array $submissionIds): static
{
$this->submissionIds = $submissionIds;
return $this;
}

/**
* Limit results to submissions assigned to these users
*
Expand Down Expand Up @@ -370,6 +382,10 @@ public function getQueryBuilder(): Builder
$q->whereIn('s.context_id', $this->contextIds);
}

if (isset($this->submissionIds)) {
$q->whereIn('s.submission_id', array_map(intval(...), $this->submissionIds));
}

// Prepare keywords (allows short and numeric words)
$keywords = collect(Application::getSubmissionSearchIndex()->filterKeywords($this->searchPhrase, false, true, true))
->unique()
Expand Down
19 changes: 19 additions & 0 deletions locale/en/admin.po
Original file line number Diff line number Diff line change
Expand Up @@ -1014,3 +1014,22 @@ msgstr "No matching scheduled task found."

msgid "admin.cli.tool.scheduler.run.prompt"
msgstr "Which command would you like to run?"

msgid "admin.submissions.incomplete.bulkDelete.button"
msgstr "Delete Incomplete Submissions"

msgid "admin.submissions.incomplete.bulkDelete.column.description"
msgstr "Select incomplete submissions to be deleted."


msgid "admin.submissions.incomplete.bulkDelete.confirm"
msgstr "Confirm Delete of Incomplete Submissions"

msgid "admin.submissions.incomplete.bulkDelete.body"
msgstr "Are you sure you want to delete the selected items? This action cannot be undone. Please confirm to proceed."

msgid "admin.submissions.incomplete.bulkDelete.selectionStatus"
msgstr "Incomplete Submissions Selected."

msgid "admin.submissions.incomplete.bulkDelete.success"
msgstr "Submissions deleted successfully!"
6 changes: 6 additions & 0 deletions locale/en/api.po
Original file line number Diff line number Diff line change
Expand Up @@ -347,5 +347,11 @@ msgstr "Only 'accept' and 'decline' are valid values"
msgid "api.submission.400.sectionDoesNotExist"
msgstr "The provided section does not exist."

msgid "api.submission.400.missingQueryParam"
msgstr "The request is missing the required query parameter `ids`. Please provide the `ids` of the submissions you wish to delete."

msgid "api.submission.400.invalidId"
msgstr "Invalid ID: \"{$id}\" provided."

msgid "api.publications.403.noEnabledIdentifiers"
msgstr "Publication identifiers form is unavailable as there are no enabled Identifiers."
5 changes: 4 additions & 1 deletion locale/en/common.po
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,9 @@ msgstr "Delete Selection"
msgid "common.deselect"
msgstr "Deselect"

msgid "common.deselectAll"
msgstr "Deselect All"

msgid "common.designation"
msgstr "Designation"

Expand Down Expand Up @@ -806,7 +809,7 @@ msgid "common.replaceFile"
msgstr "Replace file"

msgid "common.requiredField"
msgstr "Required fields are marked with an asterisk: <abbr class="required" title="required">*</abbr>"
msgstr "Required fields are marked with an asterisk: <abbr class=\"required\" title=\"required\">*</abbr>"

msgid "common.required"
msgstr "Required"
Expand Down