From fc94ba26b810fc23210c49b8293cf7fc91ed524d Mon Sep 17 00:00:00 2001 From: Vitalii Bezsheiko Date: Mon, 24 Apr 2023 17:56:00 +0300 Subject: [PATCH] pkp/pkp-lib#8933 Restore original file after cancelling file upload wizard --- .../api/file/PKPManageFileApiHandler.php | 49 ++++++++++++++++++- .../fileUpload/FileUploadWizardHandler.php | 24 +++++++-- .../fileUpload/FileUploadWizardHandler.js | 34 ++++++++++--- .../wizard/fileUpload/fileUploadWizard.tpl | 3 +- 4 files changed, 97 insertions(+), 13 deletions(-) diff --git a/controllers/api/file/PKPManageFileApiHandler.php b/controllers/api/file/PKPManageFileApiHandler.php index c293e9bfa79..a2103837028 100644 --- a/controllers/api/file/PKPManageFileApiHandler.php +++ b/controllers/api/file/PKPManageFileApiHandler.php @@ -17,6 +17,8 @@ namespace PKP\controllers\api\file; use APP\core\Application; +use APP\core\Request; +use APP\core\Services; use APP\facades\Repo; use APP\handler\Handler; use APP\notification\NotificationManager; @@ -40,7 +42,7 @@ public function __construct() parent::__construct(); $this->addRoleAssignment( [Role::ROLE_ID_MANAGER, Role::ROLE_ID_SITE_ADMIN, Role::ROLE_ID_SUB_EDITOR, Role::ROLE_ID_ASSISTANT, Role::ROLE_ID_REVIEWER, Role::ROLE_ID_AUTHOR], - ['deleteFile', 'editMetadata', 'editMetadataTab', 'saveMetadata'] + ['deleteFile', 'editMetadata', 'editMetadataTab', 'saveMetadata', 'cancelFileUpload'] ); } @@ -88,6 +90,51 @@ public function deleteFile($args, $request) return \PKP\db\DAO::getDataChangedEvent(); } + /** + * Restore original file when cancelling the upload wizard + */ + public function cancelFileUpload(array $args, Request $request): JSONMessage + { + if (!$request->checkCSRF()) { + return new JSONMessage(false); + } + + $submissionFile = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_SUBMISSION_FILE); + $originalFile = $request->getUserVar('originalFile') ? (array) $request->getUserVar('originalFile') : null; + $revisedFileId = $request->getUserVar('fileId') ? (int) $request->getUserVar('fileId') : null; + + // Get revisions and check file IDs + $revisions = Repo::submissionFile()->getRevisions($submissionFile->getId()); + $revisionIds = []; + foreach ($revisions as $revision) { + $revisionIds[] = $revision->fileId; + } + + if (!$revisedFileId && !in_array($revisedFileId, $revisionIds)) { + return new JSONMessage(false); + } + + if (!isset($originalFile['fileId']) && !in_array($originalFile['fileId'], $revisionIds)) { + return new JSONMessage(false); + } + + // Restore original submission file + Repo::submissionFile()->edit( + $submissionFile, + [ + 'fileId' => $originalFile['fileId'], + 'name' => $originalFile['name'], + 'uploaderUserId' => $originalFile['uploaderUserId'], + ] + ); + + // Remove uploaded file + Services::get('file')->delete($revisedFileId); + + $this->setupTemplate($request); + return \PKP\db\DAO::getDataChangedEvent(); + } + /** * Edit submission file metadata modal. * diff --git a/controllers/wizard/fileUpload/FileUploadWizardHandler.php b/controllers/wizard/fileUpload/FileUploadWizardHandler.php index 5b5ece2c7a6..78e8ae72525 100644 --- a/controllers/wizard/fileUpload/FileUploadWizardHandler.php +++ b/controllers/wizard/fileUpload/FileUploadWizardHandler.php @@ -35,8 +35,6 @@ use PKP\security\authorization\SubmissionFileAccessPolicy; use PKP\security\authorization\WorkflowStageAccessPolicy; use PKP\security\Role; - -use PKP\security\Validation; use PKP\submission\GenreDAO; use PKP\submissionFile\SubmissionFile; @@ -418,13 +416,19 @@ public function uploadFile($args, $request) return new JSONMessage(false, $uploadForm->fetch($request)); } + $submissionFileId = $uploadForm->getRevisedFileId(); + // Store the data of the submission file before it's replaced by the revised file + if ($submissionFileId) { + $originalFile = Repo::submissionFile()->get($submissionFileId); + } + $uploadedFile = $uploadForm->execute(); /** @var SubmissionFile $uploadedFile */ if (!is_a($uploadedFile, 'SubmissionFile')) { return new JSONMessage(false, __('common.uploadFailed')); } // Retrieve file info to be used in a JSON response. - $uploadedFileInfo = $this->_getUploadedFileInfo($uploadedFile); + $uploadedFileInfo = $this->_getUploadedFileInfo($uploadedFile, $originalFile ?? null); $reviewRound = $this->getReviewRound(); // Advance to the next step (i.e. meta-data editing). @@ -552,9 +556,9 @@ public function _onlyNumbersDiffer($a, $b) * * @return array */ - public function _getUploadedFileInfo($uploadedFile) + public function _getUploadedFileInfo(SubmissionFile $uploadedFile, ?SubmissionFile $originalFile = null) { - return [ + $uploadedFile = [ 'uploadedFile' => [ 'id' => $uploadedFile->getId(), 'fileId' => $uploadedFile->getData('fileId'), @@ -562,5 +566,15 @@ public function _getUploadedFileInfo($uploadedFile) 'genreId' => $uploadedFile->getGenreId(), ] ]; + + if ($originalFile) { + $uploadedFile['uploadedFile']['originalFile'] = [ + 'fileId' => $originalFile->getData('fileId'), + 'name' => $originalFile->getData('name'), + 'uploaderUserId' => $originalFile->getData('uploaderUserId'), + ]; + } + + return $uploadedFile; } } diff --git a/js/controllers/wizard/fileUpload/FileUploadWizardHandler.js b/js/controllers/wizard/fileUpload/FileUploadWizardHandler.js index c5325fbd101..088f62fa973 100644 --- a/js/controllers/wizard/fileUpload/FileUploadWizardHandler.js +++ b/js/controllers/wizard/fileUpload/FileUploadWizardHandler.js @@ -39,6 +39,7 @@ this.deleteUrl_ = options.deleteUrl; this.metadataUrl_ = options.metadataUrl; this.finishUrl_ = options.finishUrl; + this.cancelUrl_ = options.cancelUrl; // Bind events of the nested upload forms. this.bind('fileUploaded', this.handleFileUploaded); @@ -65,7 +66,7 @@ /** - * The URL to be called when a cancel event occurs. + * The URL to be called when a delete event occurs. * @private * @type {string} */ @@ -90,6 +91,14 @@ $.pkp.controllers.wizard.fileUpload.FileUploadWizardHandler. prototype.finishUrl_ = ''; + /** + * he URL to be called when a cancel event occurs. + * @private + * @type {string} + */ + $.pkp.controllers.wizard.fileUpload.FileUploadWizardHandler. + prototype.cancelUrl_ = ''; + /** * Information about the uploaded file (once there is one). @@ -99,7 +108,13 @@ $.pkp.controllers.wizard.fileUpload.FileUploadWizardHandler. prototype.uploadedFile_ = null; - + /** + * Information about the file being revised. + * @private + * @type {{fileId: number, name: string, uploaderUserId: number}} + */ + $.pkp.controllers.wizard.fileUpload.FileUploadWizardHandler. + prototype.originalFile_ = null; // // Public methods // @@ -243,7 +258,8 @@ this.uploadedFile_.csrfToken = this.csrfToken_; // Authorization policy expects to find the submissionFileId para this.uploadedFile_.submissionFileId = this.uploadedFile_.id; - $.post(this.deleteUrl_, this.uploadedFile_, + this.uploadedFile_.originalFile = this.originalFile_; + $.post(this.cancelUrl_, this.uploadedFile_, $.pkp.classes.Helper.curry(this.wizardCancelSuccess, this, wizardElement, event), 'json'); @@ -298,7 +314,13 @@ $.pkp.controllers.wizard.fileUpload.FileUploadWizardHandler. prototype.handleFileUploaded = function(callingForm, event, uploadedFile) { - // Save the uploaded file information. + // Keep the original file data to restore if the wizard is canceled + if (this.originalFile_ === null) { + this.originalFile_ = uploadedFile.originalFile; + } + delete uploadedFile.originalFile; + + // Save the uploaded file information this.uploadedFile_ = uploadedFile; }; @@ -348,8 +370,8 @@ $.pkp.controllers.wizard.fileUpload.FileUploadWizardHandler. prototype.startWizard = function() { - // Reset the uploaded file. - this.uploadedFile_ = null; + // Reset the uploaded and original file. + this.uploadedFile_ = this.originalFile_= null; this.parent('startWizard'); }; diff --git a/templates/controllers/wizard/fileUpload/fileUploadWizard.tpl b/templates/controllers/wizard/fileUpload/fileUploadWizard.tpl index a8ba2f6a87b..b691241f7eb 100644 --- a/templates/controllers/wizard/fileUpload/fileUploadWizard.tpl +++ b/templates/controllers/wizard/fileUpload/fileUploadWizard.tpl @@ -26,7 +26,8 @@ finishButtonText: {translate|json_encode key="common.complete"}, deleteUrl: {url|json_encode component="api.file.ManageFileApiHandler" op="deleteFile" submissionId=$submissionId stageId=$stageId fileStage=$fileStage suppressNotification=true escape=false}, metadataUrl: {url|json_encode op="editMetadata" submissionId=$submissionId stageId=$stageId reviewRoundId=$reviewRoundId fileStage=$fileStage assocType=$assocType assocId=$assocId queryId=$queryId escape=false}, - finishUrl: {url|json_encode op="finishFileSubmission" submissionId=$submissionId stageId=$stageId reviewRoundId=$reviewRoundId fileStage=$fileStage assocType=$assocType assocId=$assocId queryId=$queryId escape=false} + finishUrl: {url|json_encode op="finishFileSubmission" submissionId=$submissionId stageId=$stageId reviewRoundId=$reviewRoundId fileStage=$fileStage assocType=$assocType assocId=$assocId queryId=$queryId escape=false}, + cancelUrl: {url|json_encode component="api.file.ManageFileApiHandler" op="cancelFileUpload" submissionId=$submissionId stageId=$stageId fileStage=$fileStage escape=false} {rdelim} ); {rdelim});