first commit
This commit is contained in:
@@ -0,0 +1,215 @@
|
||||
<?php
|
||||
/**
|
||||
* @defgroup controllers_api_file File API controller
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file controllers/api/file/FileApiHandler.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 FileApiHandler
|
||||
*
|
||||
* @ingroup controllers_api_file
|
||||
*
|
||||
* @brief Class defining an AJAX API for supplying file information.
|
||||
*/
|
||||
|
||||
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 Exception;
|
||||
use PKP\config\Config;
|
||||
use PKP\core\JSONMessage;
|
||||
use PKP\db\DAORegistry;
|
||||
use PKP\file\FileArchive;
|
||||
use PKP\file\FileManager;
|
||||
use PKP\pages\libraryFiles\LibraryFileHandler;
|
||||
use PKP\security\authorization\ContextAccessPolicy;
|
||||
use PKP\security\authorization\PolicySet;
|
||||
use PKP\security\authorization\SubmissionFileAccessPolicy;
|
||||
use PKP\security\Role;
|
||||
use PKP\submission\GenreDAO;
|
||||
use PKP\submission\reviewAssignment\ReviewAssignment;
|
||||
use PKP\submissionFile\SubmissionFile;
|
||||
|
||||
class FileApiHandler extends Handler
|
||||
{
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
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],
|
||||
['downloadFile', 'downloadLibraryFile', 'downloadAllFiles', 'recordDownload', 'enableLinkAction']
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// Implement methods from PKPHandler
|
||||
//
|
||||
public function authorize($request, &$args, $roleAssignments)
|
||||
{
|
||||
$submissionId = (int) $request->getUserVar('submissionId');
|
||||
$submissionFileId = (int) $request->getUserVar('submissionFileId');
|
||||
$fileStage = (int) $request->getUserVar('fileStage');
|
||||
$libraryFileId = $request->getUserVar('libraryFileId');
|
||||
|
||||
if (!empty($submissionFileId)) {
|
||||
$this->addPolicy(new SubmissionFileAccessPolicy($request, $args, $roleAssignments, SubmissionFileAccessPolicy::SUBMISSION_FILE_ACCESS_READ, $submissionFileId));
|
||||
} elseif (is_numeric($libraryFileId)) {
|
||||
$this->addPolicy(new ContextAccessPolicy($request, $roleAssignments));
|
||||
} elseif (!empty($fileStage) && empty($submissionFileId)) {
|
||||
$submissionFileIds = Repo::submissionFile()
|
||||
->getCollector()
|
||||
->filterBySubmissionIds([$submissionId])
|
||||
->filterByFileStages([$fileStage])
|
||||
->includeDependentFiles($fileStage === SubmissionFile::SUBMISSION_FILE_DEPENDENT)
|
||||
->getIds();
|
||||
$allFilesAccessPolicy = new PolicySet(PolicySet::COMBINING_DENY_OVERRIDES);
|
||||
foreach ($submissionFileIds as $submissionFileId) {
|
||||
$allFilesAccessPolicy->addPolicy(new SubmissionFileAccessPolicy($request, $args, $roleAssignments, SubmissionFileAccessPolicy::SUBMISSION_FILE_ACCESS_READ, $submissionFileId));
|
||||
}
|
||||
$this->addPolicy($allFilesAccessPolicy);
|
||||
}
|
||||
|
||||
return parent::authorize($request, $args, $roleAssignments);
|
||||
}
|
||||
|
||||
//
|
||||
// Public handler methods
|
||||
//
|
||||
/**
|
||||
* Download a file.
|
||||
*
|
||||
* @param array $args
|
||||
* @param Request $request
|
||||
*/
|
||||
public function downloadFile($args, $request)
|
||||
{
|
||||
$submissionFile = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_SUBMISSION_FILE);
|
||||
$fileId = $request->getUserVar('fileId') ?? $submissionFile->getData('fileId');
|
||||
$revisions = Repo::submissionFile()
|
||||
->getRevisions($submissionFile->getId());
|
||||
$file = null;
|
||||
foreach ($revisions as $revision) {
|
||||
if ($revision->fileId == $fileId) {
|
||||
$file = $revision;
|
||||
}
|
||||
}
|
||||
if (!$file) {
|
||||
throw new Exception('File ' . $fileId . ' is not a revision of submission file ' . $submissionFile->getId());
|
||||
}
|
||||
if (!Services::get('file')->fs->has($file->path)) {
|
||||
$request->getDispatcher()->handle404();
|
||||
}
|
||||
|
||||
$filename = $request->getUserVar('filename') ?? $submissionFile->getLocalizedData('name');
|
||||
|
||||
// Enforce anonymous filenames for anonymous review assignments
|
||||
$reviewAssignment = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_REVIEW_ASSIGNMENT);
|
||||
if ($reviewAssignment
|
||||
&& $reviewAssignment->getReviewMethod() == ReviewAssignment::SUBMISSION_REVIEW_METHOD_DOUBLEANONYMOUS
|
||||
&& $reviewAssignment->getReviewerId() == $request->getUser()->getId()) {
|
||||
$genreDao = DAORegistry::getDAO('GenreDAO'); /** @var GenreDAO $genreDao */
|
||||
$genre = $genreDao->getById($submissionFile->getData('genreId'));
|
||||
$filename = sprintf(
|
||||
'%s-%s-%d-%s-%d',
|
||||
\Stringy\Stringy::create($request->getContext()->getLocalizedData('acronym'))->toLowerCase(),
|
||||
\Stringy\Stringy::create(__('submission.list.reviewAssignment'))->dasherize(),
|
||||
$submissionFile->getData('submissionId'),
|
||||
$genre ? $genre->getLocalizedName() : 'none',
|
||||
$submissionFile->getId()
|
||||
);
|
||||
}
|
||||
|
||||
$filename = Services::get('file')->formatFilename($file->path, $filename);
|
||||
Services::get('file')->download((int) $fileId, $filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Download a library file.
|
||||
*
|
||||
* @param array $args
|
||||
* @param Request $request
|
||||
*/
|
||||
public function downloadLibraryFile($args, $request)
|
||||
{
|
||||
$libraryFileHandler = new LibraryFileHandler($this);
|
||||
return $libraryFileHandler->downloadLibraryFile($args, $request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Download all passed files.
|
||||
*
|
||||
* @param array $args
|
||||
* @param Request $request
|
||||
*/
|
||||
public function downloadAllFiles($args, $request)
|
||||
{
|
||||
// Retrieve the authorized objects.
|
||||
$submissionFiles = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_SUBMISSION_FILES);
|
||||
|
||||
$files = [];
|
||||
foreach ($submissionFiles as $submissionFile) {
|
||||
$path = $submissionFile->getData('path');
|
||||
$files[$path] = Services::get('file')->formatFilename($path, $submissionFile->getLocalizedData('name'));
|
||||
}
|
||||
|
||||
$filename = !empty($args['nameLocaleKey'])
|
||||
? __($args['nameLocaleKey'])
|
||||
: __('submission.files');
|
||||
$filename = $args['submissionId'] . '-' . $filename;
|
||||
$filename = \Stringy\Stringy::create($filename)->toLowerCase()->dasherize()->regexReplace('[^a-z0-9\-\_.]', '');
|
||||
|
||||
$fileArchive = new FileArchive();
|
||||
$archivePath = $fileArchive->create($files, rtrim(Config::getVar('files', 'files_dir'), '/'));
|
||||
if (file_exists($archivePath)) {
|
||||
$fileManager = new FileManager();
|
||||
if ($fileArchive->zipFunctional()) {
|
||||
$fileManager->downloadByPath($archivePath, 'application/x-zip', false, $filename . '.zip');
|
||||
} else {
|
||||
$fileManager->downloadByPath($archivePath, 'application/x-gtar', false, $filename . '.tar.gz');
|
||||
}
|
||||
$fileManager->deleteByPath($archivePath);
|
||||
} else {
|
||||
throw new Exception('Creating archive with submission files failed!');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Record file download and return js event to update grid rows.
|
||||
*
|
||||
* @param array $args
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JSONMessage
|
||||
*/
|
||||
public function recordDownload($args, $request)
|
||||
{
|
||||
return $this->enableLinkAction($args, $request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a data changd event to re-enable the link action. Refactored out of
|
||||
* recordDownload since library files do not have downloads recorded and are in a
|
||||
* different context.
|
||||
*
|
||||
* @param array $args
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function enableLinkAction($args, $request)
|
||||
{
|
||||
return \PKP\db\DAO::getDataChangedEvent();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,307 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/api/file/PKPManageFileApiHandler.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 PKPManageFileApiHandler
|
||||
*
|
||||
* @ingroup controllers_api_file
|
||||
*
|
||||
* @brief Class defining an AJAX API for file manipulation.
|
||||
*/
|
||||
|
||||
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;
|
||||
use APP\template\TemplateManager;
|
||||
use PKP\controllers\wizard\fileUpload\form\SubmissionFilesMetadataForm;
|
||||
use PKP\core\JSONMessage;
|
||||
use PKP\core\PKPApplication;
|
||||
use PKP\db\DAORegistry;
|
||||
use PKP\log\event\EventLogEntry;
|
||||
use PKP\notification\NotificationDAO;
|
||||
use PKP\notification\PKPNotification;
|
||||
use PKP\observers\events\MetadataChanged;
|
||||
use PKP\security\authorization\SubmissionFileAccessPolicy;
|
||||
use PKP\security\Role;
|
||||
use PKP\stageAssignment\StageAssignmentDAO;
|
||||
use PKP\submissionFile\SubmissionFile;
|
||||
|
||||
abstract class PKPManageFileApiHandler extends Handler
|
||||
{
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
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', 'cancelFileUpload']
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// Implement methods from PKPHandler
|
||||
//
|
||||
public function authorize($request, &$args, $roleAssignments)
|
||||
{
|
||||
$this->addPolicy(new SubmissionFileAccessPolicy($request, $args, $roleAssignments, SubmissionFileAccessPolicy::SUBMISSION_FILE_ACCESS_MODIFY, (int) $args['submissionFileId']));
|
||||
|
||||
return parent::authorize($request, $args, $roleAssignments);
|
||||
}
|
||||
|
||||
//
|
||||
// Public handler methods
|
||||
//
|
||||
/**
|
||||
* Delete a file or revision
|
||||
*
|
||||
* @param array $args
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function deleteFile($args, $request)
|
||||
{
|
||||
if (!$request->checkCSRF()) {
|
||||
return new JSONMessage(false);
|
||||
}
|
||||
|
||||
$submissionFile = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_SUBMISSION_FILE);
|
||||
Repo::submissionFile()->delete($submissionFile);
|
||||
|
||||
$this->setupTemplate($request);
|
||||
$user = $request->getUser();
|
||||
if (!$request->getUserVar('suppressNotification')) {
|
||||
$notificationMgr = new NotificationManager();
|
||||
$notificationMgr->createTrivialNotification(
|
||||
$user->getId(),
|
||||
PKPNotification::NOTIFICATION_TYPE_SUCCESS,
|
||||
['contents' => __('notification.removedFile')]
|
||||
);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
$originalFileId = (int) $originalFile['fileId'];
|
||||
|
||||
// Get the file name and uploader user ID
|
||||
$originalUserId = $originalFile['uploaderUserId'] ? (int)$originalFile['uploaderUserId'] : null;
|
||||
$originalFileName = $originalFile['name'] ? (array)$originalFile['name'] : null;
|
||||
if (!$originalUserId || !$originalFileName) {
|
||||
return new JSONMessage(false);
|
||||
}
|
||||
|
||||
$originalUser = Repo::user()->get($originalUserId);
|
||||
if (!$originalUser) {
|
||||
return new JSONMessage(false);
|
||||
}
|
||||
|
||||
$originalUsername = $originalUser->getUsername();
|
||||
$matchedLogEntry = $this->findMatchedLogEntry($submissionFile, $originalFileId, $originalUsername, $originalFileName);
|
||||
if (!$matchedLogEntry) {
|
||||
return new JSONMessage(false);
|
||||
}
|
||||
|
||||
// Restore original submission file
|
||||
Repo::submissionFile()->edit(
|
||||
$submissionFile,
|
||||
[
|
||||
'fileId' => $matchedLogEntry->getData('fileId'),
|
||||
'name' => $matchedLogEntry->getData('filename'),
|
||||
'uploaderUserId' => Repo::user()->getByUsername($matchedLogEntry->getData('username'))->getId(),
|
||||
]
|
||||
);
|
||||
|
||||
// Remove uploaded file
|
||||
Services::get('file')->delete($revisedFileId);
|
||||
|
||||
$this->setupTemplate($request);
|
||||
return \PKP\db\DAO::getDataChangedEvent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit submission file metadata modal.
|
||||
*
|
||||
* @param array $args
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function editMetadata($args, $request)
|
||||
{
|
||||
$submissionFile = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_SUBMISSION_FILE);
|
||||
if ($submissionFile->getFileStage() == SubmissionFile::SUBMISSION_FILE_PROOF) {
|
||||
$templateMgr = TemplateManager::getManager($request);
|
||||
$templateMgr->assign('submissionFile', $submissionFile);
|
||||
$templateMgr->assign('stageId', $request->getUserVar('stageId'));
|
||||
return new JSONMessage(true, $templateMgr->fetch('controllers/api/file/editMetadata.tpl'));
|
||||
} else {
|
||||
return $this->editMetadataTab($args, $request);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit submission file metadata tab.
|
||||
*
|
||||
* @param array $args
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function editMetadataTab($args, $request)
|
||||
{
|
||||
$submissionFile = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_SUBMISSION_FILE);
|
||||
$reviewRound = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_REVIEW_ROUND);
|
||||
$stageId = $request->getUserVar('stageId');
|
||||
$form = new SubmissionFilesMetadataForm($submissionFile, $stageId, $reviewRound);
|
||||
$form->setShowButtons(true);
|
||||
return new JSONMessage(true, $form->fetch($request));
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the metadata of the latest revision of
|
||||
* the requested submission file.
|
||||
*
|
||||
* @param array $args
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function saveMetadata($args, $request)
|
||||
{
|
||||
$submission = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_SUBMISSION);
|
||||
$submissionFile = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_SUBMISSION_FILE);
|
||||
$reviewRound = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_REVIEW_ROUND);
|
||||
$stageId = $request->getUserVar('stageId');
|
||||
$form = new SubmissionFilesMetadataForm($submissionFile, $stageId, $reviewRound);
|
||||
$form->readInputData();
|
||||
if ($form->validate()) {
|
||||
$form->execute();
|
||||
$submissionFile = $form->getSubmissionFile();
|
||||
|
||||
// Get a list of author user IDs
|
||||
$authorUserIds = [];
|
||||
$stageAssignmentDao = DAORegistry::getDAO('StageAssignmentDAO'); /** @var StageAssignmentDAO $stageAssignmentDao */
|
||||
$submitterAssignments = $stageAssignmentDao->getBySubmissionAndRoleIds($submission->getId(), [Role::ROLE_ID_AUTHOR]);
|
||||
while ($assignment = $submitterAssignments->next()) {
|
||||
$authorUserIds[] = $assignment->getUserId();
|
||||
}
|
||||
|
||||
// Update the notifications
|
||||
$notificationMgr = new NotificationManager(); /** @var NotificationManager $notificationMgr */
|
||||
$notificationMgr->updateNotification(
|
||||
$request,
|
||||
$this->getUpdateNotifications(),
|
||||
$authorUserIds,
|
||||
Application::ASSOC_TYPE_SUBMISSION,
|
||||
$submission->getId()
|
||||
);
|
||||
|
||||
if ($reviewRound) {
|
||||
// Delete any 'revision requested' notifications since revisions are now in.
|
||||
$context = $request->getContext();
|
||||
$notificationDao = DAORegistry::getDAO('NotificationDAO'); /** @var NotificationDAO $notificationDao */
|
||||
$stageAssignmentDao = DAORegistry::getDAO('StageAssignmentDAO'); /** @var StageAssignmentDAO $stageAssignmentDao */
|
||||
$submitterAssignments = $stageAssignmentDao->getBySubmissionAndRoleIds($submission->getId(), [Role::ROLE_ID_AUTHOR]);
|
||||
while ($assignment = $submitterAssignments->next()) {
|
||||
$notificationDao->deleteByAssoc(Application::ASSOC_TYPE_SUBMISSION, $submission->getId(), $assignment->getUserId(), PKPNotification::NOTIFICATION_TYPE_EDITOR_DECISION_PENDING_REVISIONS, $context->getId());
|
||||
}
|
||||
}
|
||||
|
||||
// Inform SearchIndex of changes
|
||||
event(new MetadataChanged($submission));
|
||||
|
||||
return \PKP\db\DAO::getDataChangedEvent();
|
||||
} else {
|
||||
return new JSONMessage(true, $form->fetch($request));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of notifications to be updated on metadata form submission.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getUpdateNotifications()
|
||||
{
|
||||
return [PKPNotification::NOTIFICATION_TYPE_PENDING_EXTERNAL_REVISIONS];
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare user supplied data when cancelling file upload with saved in the event log;
|
||||
* assuming we found the right entry if they match
|
||||
*/
|
||||
protected function findMatchedLogEntry(
|
||||
SubmissionFile $submissionFile,
|
||||
int $originalFileId,
|
||||
string $originalUsername,
|
||||
array $originalFileName
|
||||
): ?EventLogEntry
|
||||
{
|
||||
$logEntries = Repo::eventLog()->getCollector()
|
||||
->filterByAssoc(PKPApplication::ASSOC_TYPE_SUBMISSION_FILE, [$submissionFile->getId()])
|
||||
->getMany();
|
||||
|
||||
$match = null;
|
||||
foreach ($logEntries as $logEntry) {
|
||||
|
||||
$loggedUsername = $logEntry->getData('username');
|
||||
$loggedFileName = $logEntry->getData('filename');
|
||||
$loggedFileId = $logEntry->getData('fileId');
|
||||
if (!$loggedUsername || !$loggedFileName || !$loggedFileId) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (
|
||||
$loggedUsername === $originalUsername &&
|
||||
$loggedFileName == $originalFileName &&
|
||||
$loggedFileId === $originalFileId
|
||||
) {
|
||||
$match = $logEntry;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $match;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,167 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/api/file/linkAction/AddFileLinkAction.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 AddFileLinkAction
|
||||
*
|
||||
* @ingroup controllers_api_file_linkAction
|
||||
*
|
||||
* @brief An action to add a submission file.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\api\file\linkAction;
|
||||
|
||||
use APP\core\Request;
|
||||
use PKP\submissionFile\SubmissionFile;
|
||||
|
||||
class AddFileLinkAction extends BaseAddFileLinkAction
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param Request $request
|
||||
* @param int $submissionId The submission the file should be
|
||||
* uploaded to.
|
||||
* @param int $stageId The workflow stage in which the file
|
||||
* uploader is being instantiated (one of the WORKFLOW_STAGE_ID_*
|
||||
* constants).
|
||||
* @param array $uploaderRoles The ids of all roles allowed to upload
|
||||
* in the context of this action.
|
||||
* @param int $fileStage The file stage the file should be
|
||||
* uploaded to (one of the SubmissionFile::SUBMISSION_FILE_* constants).
|
||||
* @param int $assocType The type of the element the file should
|
||||
* be associated with (one fo the Application::ASSOC_TYPE_* constants).
|
||||
* @param int $assocId The id of the element the file should be
|
||||
* associated with.
|
||||
* @param int $reviewRoundId The current review round ID (if any)
|
||||
* @param int $revisedFileId Revised file ID, if any
|
||||
* @param bool $dependentFilesOnly whether to only include dependent
|
||||
* files in the Genres dropdown.
|
||||
* @param int $queryId The query id. Use when the assoc details point
|
||||
* to a note
|
||||
*/
|
||||
public function __construct(
|
||||
$request,
|
||||
$submissionId,
|
||||
$stageId,
|
||||
$uploaderRoles,
|
||||
$fileStage,
|
||||
$assocType = null,
|
||||
$assocId = null,
|
||||
$reviewRoundId = null,
|
||||
$revisedFileId = null,
|
||||
$dependentFilesOnly = false,
|
||||
$queryId = null
|
||||
) {
|
||||
// Create the action arguments array.
|
||||
$actionArgs = ['fileStage' => $fileStage, 'reviewRoundId' => $reviewRoundId];
|
||||
if (is_numeric($assocType) && is_numeric($assocId)) {
|
||||
$actionArgs['assocType'] = (int)$assocType;
|
||||
$actionArgs['assocId'] = (int)$assocId;
|
||||
}
|
||||
if ($revisedFileId) {
|
||||
$actionArgs['revisedFileId'] = $revisedFileId;
|
||||
$actionArgs['revisionOnly'] = true;
|
||||
}
|
||||
if ($dependentFilesOnly) {
|
||||
$actionArgs['dependentFilesOnly'] = true;
|
||||
}
|
||||
|
||||
if ($queryId) {
|
||||
$actionArgs['queryId'] = $queryId;
|
||||
}
|
||||
|
||||
// Identify text labels based on the file stage.
|
||||
$textLabels = AddFileLinkAction::_getTextLabels($fileStage);
|
||||
|
||||
// Call the parent class constructor.
|
||||
parent::__construct(
|
||||
$request,
|
||||
$submissionId,
|
||||
$stageId,
|
||||
$uploaderRoles,
|
||||
$actionArgs,
|
||||
__($textLabels['wizardTitle']),
|
||||
__($textLabels['buttonLabel'])
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Private methods
|
||||
//
|
||||
/**
|
||||
* Static method to return text labels
|
||||
* for upload to different file stages.
|
||||
*
|
||||
* @param int $fileStage One of the
|
||||
* SubmissionFile::SUBMISSION_FILE_* constants.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function _getTextLabels($fileStage)
|
||||
{
|
||||
static $textLabels = [
|
||||
SubmissionFile::SUBMISSION_FILE_SUBMISSION => [
|
||||
'wizardTitle' => 'submission.submit.uploadSubmissionFile',
|
||||
'buttonLabel' => 'submission.addFile'
|
||||
],
|
||||
SubmissionFile::SUBMISSION_FILE_REVIEW_FILE => [
|
||||
'wizardTitle' => 'editor.submissionReview.uploadFile',
|
||||
'buttonLabel' => 'editor.submissionReview.uploadFile'
|
||||
],
|
||||
SubmissionFile::SUBMISSION_FILE_INTERNAL_REVIEW_FILE => [
|
||||
'wizardTitle' => 'editor.submissionReview.uploadFile',
|
||||
'buttonLabel' => 'editor.submissionReview.uploadFile'
|
||||
],
|
||||
SubmissionFile::SUBMISSION_FILE_REVIEW_ATTACHMENT => [
|
||||
'wizardTitle' => 'editor.submissionReview.uploadAttachment',
|
||||
'buttonLabel' => 'editor.submissionReview.uploadAttachment'
|
||||
],
|
||||
SubmissionFile::SUBMISSION_FILE_ATTACHMENT => [
|
||||
'wizardTitle' => 'editor.submissionReview.uploadFile',
|
||||
'buttonLabel' => 'submission.addFile'
|
||||
],
|
||||
SubmissionFile::SUBMISSION_FILE_REVIEW_REVISION => [
|
||||
'wizardTitle' => 'editor.submissionReview.uploadFile',
|
||||
'buttonLabel' => 'submission.addFile'
|
||||
],
|
||||
SubmissionFile::SUBMISSION_FILE_INTERNAL_REVIEW_REVISION => [
|
||||
'wizardTitle' => 'editor.submissionReview.uploadFile',
|
||||
'buttonLabel' => 'submission.addFile'
|
||||
],
|
||||
SubmissionFile::SUBMISSION_FILE_FINAL => [
|
||||
'wizardTitle' => 'submission.upload.finalDraft',
|
||||
'buttonLabel' => 'submission.addFile'
|
||||
],
|
||||
SubmissionFile::SUBMISSION_FILE_COPYEDIT => [
|
||||
'wizardTitle' => 'submission.upload.copyeditedVersion',
|
||||
'buttonLabel' => 'submission.addFile'
|
||||
],
|
||||
SubmissionFile::SUBMISSION_FILE_PRODUCTION_READY => [
|
||||
'wizardTitle' => 'submission.upload.productionReady',
|
||||
'buttonLabel' => 'submission.addFile'
|
||||
],
|
||||
SubmissionFile::SUBMISSION_FILE_PROOF => [
|
||||
'wizardTitle' => 'submission.upload.proof',
|
||||
'buttonLabel' => 'submission.changeFile'
|
||||
],
|
||||
SubmissionFile::SUBMISSION_FILE_DEPENDENT => [
|
||||
'wizardTitle' => 'submission.upload.dependent',
|
||||
'buttonLabel' => 'submission.addFile'
|
||||
],
|
||||
SubmissionFile::SUBMISSION_FILE_QUERY => [
|
||||
'wizardTitle' => 'submission.upload.query',
|
||||
'buttonLabel' => 'submission.addFile'
|
||||
],
|
||||
];
|
||||
|
||||
assert(isset($textLabels[$fileStage]));
|
||||
return $textLabels[$fileStage];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/api/file/linkAction/AddRevisionLinkAction.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 AddRevisionLinkAction
|
||||
*
|
||||
* @ingroup controllers_api_file_linkAction
|
||||
*
|
||||
* @brief An action to upload a revision of file currently under review.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\api\file\linkAction;
|
||||
|
||||
use APP\core\Request;
|
||||
use PKP\submission\reviewRound\ReviewRound;
|
||||
use PKP\submissionFile\SubmissionFile;
|
||||
|
||||
class AddRevisionLinkAction extends BaseAddFileLinkAction
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param Request $request
|
||||
* @param ReviewRound $reviewRound The review round to upload to.
|
||||
* @param array $uploaderRoles The ids of all roles allowed to upload
|
||||
* in the context of this action.
|
||||
*/
|
||||
public function __construct($request, $reviewRound, $uploaderRoles)
|
||||
{
|
||||
// Create the action arguments array.
|
||||
$actionArgs = [
|
||||
'fileStage' => SubmissionFile::SUBMISSION_FILE_REVIEW_REVISION,
|
||||
'stageId' => $reviewRound->getStageId(),
|
||||
'reviewRoundId' => $reviewRound->getId(),
|
||||
'revisionOnly' => '1'
|
||||
];
|
||||
|
||||
// Call the parent class constructor.
|
||||
parent::__construct(
|
||||
$request,
|
||||
$reviewRound->getSubmissionId(),
|
||||
$reviewRound->getStageId(),
|
||||
$uploaderRoles,
|
||||
$actionArgs,
|
||||
__('submission.review.uploadRevisionToRound', ['round' => $reviewRound->getRound()]),
|
||||
__('submission.addFile')
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
/**
|
||||
* @defgroup controllers_api_file_linkAction Link action API controller
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file controllers/api/file/linkAction/BaseAddFileLinkAction.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 BaseAddFileLinkAction
|
||||
*
|
||||
* @ingroup controllers_api_file_linkAction
|
||||
*
|
||||
* @brief Abstract base class for file upload actions.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\api\file\linkAction;
|
||||
|
||||
use APP\core\Request;
|
||||
use PKP\core\PKPApplication;
|
||||
use PKP\linkAction\LinkAction;
|
||||
use PKP\linkAction\request\WizardModal;
|
||||
|
||||
class BaseAddFileLinkAction extends LinkAction
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param Request $request
|
||||
* @param int $submissionId The submission the file should be
|
||||
* uploaded to.
|
||||
* @param int $stageId The workflow stage in which the file
|
||||
* uploader is being instantiated (one of the WORKFLOW_STAGE_ID_*
|
||||
* constants).
|
||||
* @param array $uploaderRoles The ids of all roles allowed to upload
|
||||
* in the context of this action.
|
||||
* @param array $actionArgs The arguments to be passed into the file
|
||||
* upload wizard.
|
||||
* @param string $wizardTitle The title to be displayed in the file
|
||||
* upload wizard.
|
||||
* @param string $buttonLabel The link action's button label.
|
||||
*/
|
||||
public function __construct(
|
||||
$request,
|
||||
$submissionId,
|
||||
$stageId,
|
||||
$uploaderRoles,
|
||||
$actionArgs,
|
||||
$wizardTitle,
|
||||
$buttonLabel
|
||||
) {
|
||||
// Augment the action arguments array.
|
||||
$actionArgs['submissionId'] = $submissionId;
|
||||
$actionArgs['stageId'] = $stageId;
|
||||
assert(is_array($uploaderRoles) && count($uploaderRoles) >= 1);
|
||||
$actionArgs['uploaderRoles'] = implode('-', (array) $uploaderRoles);
|
||||
|
||||
// Instantiate the file upload modal.
|
||||
$dispatcher = $request->getDispatcher();
|
||||
$modal = new WizardModal(
|
||||
$dispatcher->url(
|
||||
$request,
|
||||
PKPApplication::ROUTE_COMPONENT,
|
||||
null,
|
||||
'wizard.fileUpload.FileUploadWizardHandler',
|
||||
'startWizard',
|
||||
null,
|
||||
$actionArgs
|
||||
),
|
||||
$wizardTitle,
|
||||
'modal_add_file'
|
||||
);
|
||||
|
||||
// Configure the link action.
|
||||
parent::__construct('addFile', $modal, $buttonLabel, 'add');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
/**
|
||||
* @file controllers/api/file/linkAction/DeleteFileLinkAction.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 DeleteFileLinkAction
|
||||
*
|
||||
* @ingroup controllers_api_file_linkAction
|
||||
*
|
||||
* @brief An action to delete a file.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\api\file\linkAction;
|
||||
|
||||
use APP\core\Request;
|
||||
use PKP\linkAction\request\RemoteActionConfirmationModal;
|
||||
use PKP\submissionFile\SubmissionFile;
|
||||
|
||||
class DeleteFileLinkAction extends FileLinkAction
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param Request $request
|
||||
* @param SubmissionFile $submissionFile the submission file to be deleted
|
||||
* @param int $stageId (optional)
|
||||
* @param string $localeKey (optional) Locale key to use for delete link
|
||||
* be deleted.
|
||||
*/
|
||||
public function __construct($request, $submissionFile, $stageId, $localeKey = 'grid.action.delete')
|
||||
{
|
||||
$router = $request->getRouter();
|
||||
parent::__construct(
|
||||
'deleteFile',
|
||||
new RemoteActionConfirmationModal(
|
||||
$request->getSession(),
|
||||
__('common.confirmDelete'),
|
||||
__('common.delete'),
|
||||
$router->url(
|
||||
$request,
|
||||
null,
|
||||
'api.file.ManageFileApiHandler',
|
||||
'deleteFile',
|
||||
null,
|
||||
$this->getActionArgs($submissionFile, $stageId)
|
||||
),
|
||||
'modal_delete'
|
||||
),
|
||||
__($localeKey),
|
||||
'delete'
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
/**
|
||||
* @file controllers/api/file/linkAction/DownloadFileLinkAction.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 DownloadFileLinkAction
|
||||
*
|
||||
* @ingroup controllers_api_file_linkAction
|
||||
*
|
||||
* @brief An action to download a file.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\api\file\linkAction;
|
||||
|
||||
use APP\core\Request;
|
||||
use PKP\linkAction\request\PostAndRedirectAction;
|
||||
use PKP\submissionFile\SubmissionFile;
|
||||
|
||||
class DownloadFileLinkAction extends FileLinkAction
|
||||
{
|
||||
/** @var string Optional label to use instead of file name */
|
||||
public $label;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param Request $request
|
||||
* @param SubmissionFile $submissionFile the submission file to
|
||||
* link to.
|
||||
* @param int $stageId (optional)
|
||||
* @param string $label (optional) Label to use instead of filename
|
||||
* @param int $fileId (optional) Download a specific revision of a file
|
||||
* @param string $filename (optional) The filename to use for the file
|
||||
*/
|
||||
public function __construct($request, $submissionFile, $stageId = null, $label = null, $fileId = null, $filename = null)
|
||||
{
|
||||
// Instantiate the redirect action request.
|
||||
$router = $request->getRouter();
|
||||
$this->label = $label;
|
||||
$actionArgs = $this->getActionArgs($submissionFile, $stageId);
|
||||
if ($fileId) {
|
||||
$actionArgs['fileId'] = $fileId;
|
||||
}
|
||||
if ($filename) {
|
||||
$actionArgs['filename'] = $filename;
|
||||
}
|
||||
$redirectRequest = new PostAndRedirectAction(
|
||||
$router->url(
|
||||
$request,
|
||||
null,
|
||||
'api.file.FileApiHandler',
|
||||
'recordDownload',
|
||||
null,
|
||||
$actionArgs
|
||||
),
|
||||
$router->url(
|
||||
$request,
|
||||
null,
|
||||
'api.file.FileApiHandler',
|
||||
'downloadFile',
|
||||
null,
|
||||
$actionArgs
|
||||
)
|
||||
);
|
||||
|
||||
// Configure the file link action.
|
||||
parent::__construct(
|
||||
'downloadFile',
|
||||
$redirectRequest,
|
||||
htmlspecialchars($this->getLabel($submissionFile))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the label for the file download action.
|
||||
*
|
||||
* @param SubmissionFile $submissionFile
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getLabel($submissionFile)
|
||||
{
|
||||
if ($this->label !== null) {
|
||||
return $this->label;
|
||||
}
|
||||
return $submissionFile->getLocalizedData('name');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
/**
|
||||
* @file controllers/api/file/linkAction/DownloadLibraryFileLinkAction.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 DownloadLibraryFileLinkAction
|
||||
*
|
||||
* @ingroup controllers_api_file_linkAction
|
||||
*
|
||||
* @brief An action to download a library file.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\api\file\linkAction;
|
||||
|
||||
use APP\core\Request;
|
||||
use PKP\context\LibraryFile;
|
||||
use PKP\linkAction\LinkAction;
|
||||
use PKP\linkAction\request\PostAndRedirectAction;
|
||||
|
||||
class DownloadLibraryFileLinkAction extends LinkAction
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param Request $request
|
||||
* @param LibraryFile $libraryFile the library file to
|
||||
* link to.
|
||||
*/
|
||||
public function __construct($request, $libraryFile)
|
||||
{
|
||||
// Instantiate the redirect action request.
|
||||
$router = $request->getRouter();
|
||||
$redirectRequest = new PostAndRedirectAction(
|
||||
$router->url(
|
||||
$request,
|
||||
null,
|
||||
'api.file.FileApiHandler',
|
||||
'enableLinkAction',
|
||||
null,
|
||||
$this->getActionArgs($libraryFile)
|
||||
),
|
||||
$router->url(
|
||||
$request,
|
||||
null,
|
||||
'api.file.FileApiHandler',
|
||||
'downloadLibraryFile',
|
||||
null,
|
||||
$this->getActionArgs($libraryFile)
|
||||
)
|
||||
);
|
||||
|
||||
// Configure the file link action.
|
||||
parent::__construct(
|
||||
'downloadFile',
|
||||
$redirectRequest,
|
||||
htmlspecialchars($libraryFile->getLocalizedName()),
|
||||
$libraryFile->getDocumentType()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the action arguments to address a file.
|
||||
*
|
||||
* @param LibraryFile $libraryFile
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getActionArgs(&$libraryFile)
|
||||
{
|
||||
assert($libraryFile instanceof LibraryFile);
|
||||
|
||||
// Create the action arguments array.
|
||||
$args = ['libraryFileId' => $libraryFile->getId()];
|
||||
|
||||
if ($libraryFile->getSubmissionId()) {
|
||||
$args['submissionId'] = $libraryFile->getSubmissionId();
|
||||
}
|
||||
|
||||
return $args;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
/**
|
||||
* @file controllers/api/file/linkAction/EditFileLinkAction.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 EditFileLinkAction
|
||||
*
|
||||
* @ingroup controllers_api_file_linkAction
|
||||
*
|
||||
* @brief An action to edit a file's metadata.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\api\file\linkAction;
|
||||
|
||||
use APP\core\Request;
|
||||
use PKP\core\PKPApplication;
|
||||
use PKP\linkAction\request\AjaxModal;
|
||||
use PKP\submissionFile\SubmissionFile;
|
||||
|
||||
class EditFileLinkAction extends FileLinkAction
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param Request $request
|
||||
* @param SubmissionFile $submissionFile the submission file to edit.
|
||||
* @param int $stageId Stage ID
|
||||
*/
|
||||
public function __construct($request, $submissionFile, $stageId)
|
||||
{
|
||||
// Instantiate the AJAX modal request.
|
||||
$router = $request->getRouter();
|
||||
$dispatcher = $router->getDispatcher();
|
||||
$modal = new AjaxModal(
|
||||
$dispatcher->url(
|
||||
$request,
|
||||
PKPApplication::ROUTE_COMPONENT,
|
||||
null,
|
||||
'api.file.ManageFileApiHandler',
|
||||
'editMetadata',
|
||||
null,
|
||||
$this->getActionArgs($submissionFile, $stageId)
|
||||
),
|
||||
__('grid.action.editFile'),
|
||||
'modal_information'
|
||||
);
|
||||
|
||||
// Configure the file link action.
|
||||
parent::__construct(
|
||||
'editFile',
|
||||
$modal,
|
||||
__('common.edit'),
|
||||
'edit'
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
/**
|
||||
* @file controllers/api/file/linkAction/FileLinkAction.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 FileLinkAction
|
||||
*
|
||||
* @ingroup controllers_api_file_linkAction
|
||||
*
|
||||
* @brief An abstract file action.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\api\file\linkAction;
|
||||
|
||||
use PKP\linkAction\LinkAction;
|
||||
use PKP\submissionFile\SubmissionFile;
|
||||
|
||||
class FileLinkAction extends LinkAction
|
||||
{
|
||||
//
|
||||
// Protected helper function
|
||||
//
|
||||
/**
|
||||
* Return the action arguments to address a file.
|
||||
*
|
||||
* @param SubmissionFile $submissionFile
|
||||
* @param int $stageId (optional)
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getActionArgs($submissionFile, $stageId = null)
|
||||
{
|
||||
assert($submissionFile instanceof SubmissionFile);
|
||||
|
||||
// Create the action arguments array.
|
||||
$args = [
|
||||
'submissionFileId' => $submissionFile->getId(),
|
||||
'submissionId' => $submissionFile->getData('submissionId')
|
||||
];
|
||||
if ($stageId) {
|
||||
$args['stageId'] = $stageId;
|
||||
}
|
||||
|
||||
return $args;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/api/task/SendReminderLinkAction.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 SendReminderLinkAction
|
||||
*
|
||||
* @ingroup controllers_api_task
|
||||
*
|
||||
* @brief An action to open up a modal to send a reminder to users assigned to a task.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\api\task;
|
||||
|
||||
use APP\core\Request;
|
||||
use PKP\linkAction\LinkAction;
|
||||
use PKP\linkAction\request\AjaxModal;
|
||||
|
||||
class SendReminderLinkAction extends LinkAction
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param Request $request
|
||||
* @param array $actionArgs The action arguments.
|
||||
*/
|
||||
public function __construct($request, $modalTitle, $actionArgs)
|
||||
{
|
||||
// Instantiate the send review modal.
|
||||
$router = $request->getRouter();
|
||||
|
||||
$ajaxModal = new AjaxModal(
|
||||
$router->url($request, null, null, 'editReminder', null, $actionArgs),
|
||||
__($modalTitle),
|
||||
'review_reminder'
|
||||
);
|
||||
|
||||
// Configure the link action.
|
||||
parent::__construct(
|
||||
'sendReminder',
|
||||
$ajaxModal,
|
||||
__('editor.review.sendReminder'),
|
||||
'overdue'
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/api/task/SendThankYouLinkAction.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 SendThankYouLinkAction
|
||||
*
|
||||
* @ingroup controllers_api_task
|
||||
*
|
||||
* @brief An action to open up a modal to send a thank you email to users assigned to a review task.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\api\task;
|
||||
|
||||
use APP\core\Request;
|
||||
use PKP\linkAction\LinkAction;
|
||||
use PKP\linkAction\request\AjaxModal;
|
||||
|
||||
class SendThankYouLinkAction extends LinkAction
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param Request $request
|
||||
* @param array $actionArgs The action arguments.
|
||||
*/
|
||||
public function __construct($request, $modalTitle, $actionArgs)
|
||||
{
|
||||
// Instantiate the send thank you modal.
|
||||
$router = $request->getRouter();
|
||||
|
||||
$ajaxModal = new AjaxModal(
|
||||
$router->url($request, null, null, 'editThankReviewer', null, $actionArgs),
|
||||
__($modalTitle),
|
||||
'modal_email'
|
||||
);
|
||||
|
||||
// Configure the link action.
|
||||
parent::__construct(
|
||||
'thankReviewer',
|
||||
$ajaxModal,
|
||||
__('editor.review.thankReviewer'),
|
||||
'accepted'
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
/**
|
||||
* @defgroup controllers_api_user User API controller
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file controllers/api/user/UserApiHandler.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 UserApiHandler
|
||||
*
|
||||
* @ingroup controllers_api_user
|
||||
*
|
||||
* @brief Class defining the headless AJAX API for backend user manipulation.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\api\user;
|
||||
|
||||
use PKP\core\JSONMessage;
|
||||
use PKP\core\PKPRequest;
|
||||
use PKP\handler\PKPHandler;
|
||||
use PKP\security\authorization\PKPSiteAccessPolicy;
|
||||
use PKP\security\Validation;
|
||||
|
||||
class UserApiHandler extends PKPHandler
|
||||
{
|
||||
//
|
||||
// Implement template methods from PKPHandler
|
||||
//
|
||||
/**
|
||||
* @copydoc PKPHandler::authorize()
|
||||
*/
|
||||
public function authorize($request, &$args, $roleAssignments)
|
||||
{
|
||||
$this->addPolicy(new PKPSiteAccessPolicy(
|
||||
$request,
|
||||
['suggestUsername'],
|
||||
PKPSiteAccessPolicy::SITE_ACCESS_ALL_ROLES
|
||||
));
|
||||
return parent::authorize($request, $args, $roleAssignments);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Public handler methods
|
||||
//
|
||||
/**
|
||||
* Get a suggested username, making sure it's not already used.
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function suggestUsername($args, $request)
|
||||
{
|
||||
$suggestion = Validation::suggestUsername(
|
||||
$request->getUserVar('givenName'),
|
||||
$request->getUserVar('familyName')
|
||||
);
|
||||
|
||||
return new JSONMessage(true, $suggestion);
|
||||
}
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/confirmationModal/linkAction/ViewCompetingInterestGuidelinesLinkAction.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 ViewCompetingInterestGuidelinesLinkAction
|
||||
*
|
||||
* @ingroup controllers_confirmationModal_linkAction
|
||||
*
|
||||
* @brief An action to open the competing interests confirmation modal.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\confirmationModal\linkAction;
|
||||
|
||||
use APP\core\Request;
|
||||
use PKP\linkAction\LinkAction;
|
||||
use PKP\linkAction\request\ConfirmationModal;
|
||||
|
||||
class ViewCompetingInterestGuidelinesLinkAction extends LinkAction
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param Request $request
|
||||
*/
|
||||
public function __construct($request)
|
||||
{
|
||||
$context = $request->getContext();
|
||||
// Instantiate the view competing interests modal.
|
||||
$viewCompetingInterestsModal = new ConfirmationModal(
|
||||
$context->getLocalizedData('competingInterests'),
|
||||
__('reviewer.submission.competingInterests'),
|
||||
null,
|
||||
null,
|
||||
false,
|
||||
false
|
||||
);
|
||||
|
||||
// Configure the link action.
|
||||
parent::__construct('viewCompetingInterestGuidelines', $viewCompetingInterestsModal, __('reviewer.submission.competingInterests'));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
/**
|
||||
* @defgroup controllers_confirmationModal_linkAction Confirmation Modal Link Action
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file controllers/confirmationModal/linkAction/ViewReviewGuidelinesLinkAction.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 ViewReviewGuidelinesLinkAction
|
||||
*
|
||||
* @ingroup controllers_confirmationModal_linkAction
|
||||
*
|
||||
* @brief An action to open the review guidelines confirmation modal.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\confirmationModal\linkAction;
|
||||
|
||||
use APP\core\Request;
|
||||
use PKP\context\Context;
|
||||
use PKP\linkAction\LinkAction;
|
||||
use PKP\linkAction\request\ConfirmationModal;
|
||||
|
||||
class ViewReviewGuidelinesLinkAction extends LinkAction
|
||||
{
|
||||
/** @var Context */
|
||||
public $_context;
|
||||
|
||||
/** @var int WORKFLOW_STAGE_ID_... */
|
||||
public $_stageId;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param Request $request
|
||||
* @param int $stageId Stage ID of review assignment
|
||||
*/
|
||||
public function __construct($request, $stageId)
|
||||
{
|
||||
$this->_context = $request->getContext();
|
||||
$this->_stageId = $stageId;
|
||||
|
||||
$viewGuidelinesModal = new ConfirmationModal(
|
||||
$this->getGuidelines(),
|
||||
__('reviewer.submission.guidelines'),
|
||||
null,
|
||||
null,
|
||||
false
|
||||
);
|
||||
|
||||
// Configure the link action.
|
||||
parent::__construct('viewReviewGuidelines', $viewGuidelinesModal, __('reviewer.submission.guidelines'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the guidelines for the specified stage.
|
||||
*
|
||||
* @return ?string
|
||||
*/
|
||||
public function getGuidelines()
|
||||
{
|
||||
return $this->_context->getLocalizedData(
|
||||
$this->_stageId == WORKFLOW_STAGE_ID_EXTERNAL_REVIEW ? 'reviewGuidelines' : 'internalReviewGuidelines'
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/admin/context/ContextGridCellProvider.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 ContextGridCellProvider
|
||||
*
|
||||
* @ingroup controllers_grid_admin_context
|
||||
*
|
||||
* @brief Subclass for a context grid column's cell provider
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\admin\context;
|
||||
|
||||
use PKP\controllers\grid\GridCellProvider;
|
||||
use PKP\controllers\grid\GridColumn;
|
||||
|
||||
class ContextGridCellProvider extends GridCellProvider
|
||||
{
|
||||
/**
|
||||
* Extracts variables for a given column from a data element
|
||||
* so that they may be assigned to template before rendering.
|
||||
*
|
||||
* @param \PKP\controllers\grid\GridRow $row
|
||||
* @param GridColumn $column
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getTemplateVarsFromRowColumn($row, $column)
|
||||
{
|
||||
$element = $row->getData();
|
||||
$columnId = $column->getId();
|
||||
assert($element instanceof \PKP\context\Context && !empty($columnId));
|
||||
switch ($columnId) {
|
||||
case 'name':
|
||||
$label = $element->getLocalizedName() != '' ? $element->getLocalizedName() : __('common.untitled');
|
||||
return ['label' => $label];
|
||||
case 'urlPath':
|
||||
$label = $element->getPath();
|
||||
return ['label' => $label];
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,309 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/admin/context/ContextGridHandler.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 ContextGridHandler
|
||||
*
|
||||
* @ingroup controllers_grid_admin_context
|
||||
*
|
||||
* @brief Handle context grid requests.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\admin\context;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\core\Request;
|
||||
use APP\core\Services;
|
||||
use APP\template\TemplateManager;
|
||||
use PKP\controllers\grid\feature\OrderGridItemsFeature;
|
||||
use PKP\controllers\grid\GridColumn;
|
||||
use PKP\controllers\grid\GridHandler;
|
||||
use PKP\core\JSONMessage;
|
||||
use PKP\core\PKPApplication;
|
||||
use PKP\linkAction\LinkAction;
|
||||
use PKP\linkAction\request\AjaxModal;
|
||||
use PKP\security\authorization\PolicySet;
|
||||
use PKP\security\authorization\RoleBasedHandlerOperationPolicy;
|
||||
use PKP\security\Role;
|
||||
|
||||
class ContextGridHandler extends GridHandler
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->addRoleAssignment(
|
||||
[
|
||||
Role::ROLE_ID_SITE_ADMIN],
|
||||
['fetchGrid', 'fetchRow', 'createContext', 'editContext', 'updateContext', 'users',
|
||||
'deleteContext', 'saveSequence']
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Implement template methods from PKPHandler.
|
||||
//
|
||||
/**
|
||||
* @copydoc PKPHandler::authorize()
|
||||
*/
|
||||
public function authorize($request, &$args, $roleAssignments)
|
||||
{
|
||||
$rolePolicy = new PolicySet(PolicySet::COMBINING_PERMIT_OVERRIDES);
|
||||
|
||||
foreach ($roleAssignments as $role => $operations) {
|
||||
$rolePolicy->addPolicy(new RoleBasedHandlerOperationPolicy($request, $role, $operations));
|
||||
}
|
||||
$this->addPolicy($rolePolicy);
|
||||
|
||||
return parent::authorize($request, $args, $roleAssignments);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::initialize()
|
||||
*
|
||||
* @param null|mixed $args
|
||||
*/
|
||||
public function initialize($request, $args = null)
|
||||
{
|
||||
parent::initialize($request, $args);
|
||||
|
||||
$this->setTitle('context.contexts');
|
||||
|
||||
// Grid actions.
|
||||
$router = $request->getRouter();
|
||||
|
||||
$this->addAction(
|
||||
new LinkAction(
|
||||
'createContext',
|
||||
new AjaxModal(
|
||||
$router->url($request, null, null, 'createContext', null, null),
|
||||
__('admin.contexts.create'),
|
||||
'modal_add_item',
|
||||
true,
|
||||
'context',
|
||||
['editContext']
|
||||
),
|
||||
__('admin.contexts.create'),
|
||||
'add_item'
|
||||
)
|
||||
);
|
||||
|
||||
//
|
||||
// Grid columns.
|
||||
//
|
||||
$contextGridCellProvider = new ContextGridCellProvider();
|
||||
|
||||
// Context name.
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'name',
|
||||
'common.name',
|
||||
null,
|
||||
null,
|
||||
$contextGridCellProvider
|
||||
)
|
||||
);
|
||||
|
||||
// Context path.
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'urlPath',
|
||||
'context.path',
|
||||
null,
|
||||
null,
|
||||
$contextGridCellProvider
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Implement methods from GridHandler.
|
||||
//
|
||||
/**
|
||||
* @copydoc GridHandler::getRowInstance()
|
||||
*
|
||||
* @return ContextGridRow
|
||||
*/
|
||||
protected function getRowInstance()
|
||||
{
|
||||
return new ContextGridRow();
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::loadData()
|
||||
*
|
||||
* @param null|mixed $filter
|
||||
*/
|
||||
protected function loadData($request, $filter = null)
|
||||
{
|
||||
// Get all contexts.
|
||||
$contextDao = Application::getContextDAO();
|
||||
$contexts = $contextDao->getAll();
|
||||
|
||||
return $contexts->toAssociativeArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::setDataElementSequence()
|
||||
*/
|
||||
public function setDataElementSequence($request, $rowId, $gridDataElement, $newSequence)
|
||||
{
|
||||
$contextDao = Application::getContextDAO();
|
||||
$gridDataElement->setSequence($newSequence);
|
||||
$contextDao->updateObject($gridDataElement);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::getDataElementSequence()
|
||||
*/
|
||||
public function getDataElementSequence($gridDataElement)
|
||||
{
|
||||
return $gridDataElement->getSequence();
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::addFeatures()
|
||||
*/
|
||||
public function initFeatures($request, $args)
|
||||
{
|
||||
return [new OrderGridItemsFeature()];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of "publish data changed" events.
|
||||
* Used to update the site context switcher upon create/delete.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getPublishChangeEvents()
|
||||
{
|
||||
return ['updateHeader'];
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Public grid actions.
|
||||
//
|
||||
/**
|
||||
* Add a new context.
|
||||
*
|
||||
* @param array $args
|
||||
* @param Request $request
|
||||
*/
|
||||
public function createContext($args, $request)
|
||||
{
|
||||
// Calling editContext with an empty row id will add a new context.
|
||||
return $this->editContext($args, $request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit an existing context.
|
||||
*
|
||||
* @param array $args
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function editContext($args, $request)
|
||||
{
|
||||
$contextService = Services::get('context');
|
||||
$context = null;
|
||||
|
||||
if ($request->getUserVar('rowId')) {
|
||||
$context = $contextService->get((int) $request->getUserVar('rowId'));
|
||||
if (!$context) {
|
||||
return new JSONMessage(false);
|
||||
}
|
||||
}
|
||||
|
||||
$dispatcher = $request->getDispatcher();
|
||||
if ($context) {
|
||||
$apiUrl = $dispatcher->url($request, PKPApplication::ROUTE_API, $context->getPath(), 'contexts/' . $context->getId());
|
||||
$locales = $context->getSupportedFormLocaleNames();
|
||||
} else {
|
||||
$apiUrl = $dispatcher->url($request, PKPApplication::ROUTE_API, Application::CONTEXT_ID_ALL, 'contexts');
|
||||
$locales = $request->getSite()->getSupportedLocaleNames();
|
||||
}
|
||||
|
||||
$locales = array_map(fn (string $locale, string $name) => ['key' => $locale, 'label' => $name], array_keys($locales), $locales);
|
||||
|
||||
$contextForm = new \APP\components\forms\context\ContextForm($apiUrl, $locales, $request->getBaseUrl(), $context);
|
||||
$contextFormConfig = $contextForm->getConfig();
|
||||
|
||||
// Pass the URL to the context settings wizard so that the AddContextForm
|
||||
// component can redirect to it when a new context is added.
|
||||
if (!$context) {
|
||||
$contextFormConfig['editContextUrl'] = $request->getDispatcher()->url($request, PKPApplication::ROUTE_PAGE, 'index', 'admin', 'wizard', '__id__');
|
||||
}
|
||||
|
||||
$templateMgr = TemplateManager::getManager($request);
|
||||
|
||||
$containerData = [
|
||||
'components' => [
|
||||
FORM_CONTEXT => $contextFormConfig,
|
||||
],
|
||||
'tinyMCE' => [
|
||||
'skinUrl' => $templateMgr->getTinyMceSkinUrl($request),
|
||||
],
|
||||
];
|
||||
|
||||
$templateMgr->assign([
|
||||
'containerData' => $containerData,
|
||||
'isAddingNewContext' => !$context,
|
||||
]);
|
||||
|
||||
return new JSONMessage(true, $templateMgr->fetch('admin/editContext.tpl'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a context.
|
||||
*
|
||||
* @param array $args
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function deleteContext($args, $request)
|
||||
{
|
||||
if (!$request->checkCSRF()) {
|
||||
return new JSONMessage(false);
|
||||
}
|
||||
|
||||
$contextService = Services::get('context');
|
||||
|
||||
$context = $contextService->get((int) $request->getUserVar('rowId'));
|
||||
|
||||
if (!$context) {
|
||||
return new JSONMessage(false);
|
||||
}
|
||||
|
||||
$contextService->delete($context);
|
||||
|
||||
return \PKP\db\DAO::getDataChangedEvent($context->getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Display users management grid for the given context.
|
||||
*
|
||||
* @param array $args
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function users($args, $request)
|
||||
{
|
||||
$templateMgr = TemplateManager::getManager($request);
|
||||
$templateMgr->assign('oldUserId', (int) $request->getUserVar('oldUserId')); // for merging users.
|
||||
parent::setupTemplate($request);
|
||||
return $templateMgr->fetchJson('management/accessUsers.tpl');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/admin/context/ContextGridRow.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 ContextGridRow
|
||||
*
|
||||
* @ingroup controllers_grid_admin_context
|
||||
*
|
||||
* @brief Context grid row definition
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\admin\context;
|
||||
|
||||
use PKP\controllers\grid\GridRow;
|
||||
use PKP\core\PKPApplication;
|
||||
use PKP\linkAction\LinkAction;
|
||||
use PKP\linkAction\request\AjaxModal;
|
||||
use PKP\linkAction\request\RedirectAction;
|
||||
use PKP\linkAction\request\RemoteActionConfirmationModal;
|
||||
|
||||
class ContextGridRow extends GridRow
|
||||
{
|
||||
//
|
||||
// Overridden methods from GridRow
|
||||
//
|
||||
/**
|
||||
* @copydoc GridRow::initialize()
|
||||
*
|
||||
* @param null|mixed $template
|
||||
*/
|
||||
public function initialize($request, $template = null)
|
||||
{
|
||||
parent::initialize($request, $template);
|
||||
|
||||
// Is this a new row or an existing row?
|
||||
$element = $this->getData();
|
||||
assert($element instanceof \PKP\context\Context);
|
||||
|
||||
$rowId = $this->getId();
|
||||
|
||||
$router = $request->getRouter();
|
||||
$this->addAction(
|
||||
new LinkAction(
|
||||
'edit',
|
||||
new AjaxModal(
|
||||
$router->url($request, null, null, 'editContext', null, ['rowId' => $rowId]),
|
||||
__('grid.action.edit'),
|
||||
'modal_edit',
|
||||
true,
|
||||
'context',
|
||||
['editContext']
|
||||
),
|
||||
__('grid.action.edit'),
|
||||
'edit'
|
||||
)
|
||||
);
|
||||
$this->addAction(
|
||||
new LinkAction(
|
||||
'delete',
|
||||
new RemoteActionConfirmationModal(
|
||||
$request->getSession(),
|
||||
__('admin.contexts.confirmDelete', ['contextName' => $element->getLocalizedName()]),
|
||||
null,
|
||||
$router->url($request, null, null, 'deleteContext', null, ['rowId' => $rowId])
|
||||
),
|
||||
__('grid.action.remove'),
|
||||
'delete'
|
||||
)
|
||||
);
|
||||
$dispatcher = $router->getDispatcher();
|
||||
$this->addAction(
|
||||
new LinkAction(
|
||||
'wizard',
|
||||
new RedirectAction($dispatcher->url($request, PKPApplication::ROUTE_PAGE, 'index', 'admin', 'wizard', $element->getId())),
|
||||
__('grid.action.wizard'),
|
||||
'wrench'
|
||||
)
|
||||
);
|
||||
$this->addAction(
|
||||
new LinkAction(
|
||||
'users',
|
||||
new AjaxModal(
|
||||
$router->url($request, $element->getPath(), null, 'users', null),
|
||||
__('manager.users'),
|
||||
'modal_edit',
|
||||
true
|
||||
),
|
||||
__('manager.users'),
|
||||
'users'
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,467 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/admin/languages/AdminLanguageGridHandler.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 AdminLanguageGridHandler
|
||||
*
|
||||
* @ingroup controllers_grid_admin_languages
|
||||
*
|
||||
* @brief Handle administrative language grid requests. If in single context (e.g.
|
||||
* press) installation, this grid can also handle language management requests.
|
||||
* See _canManage().
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\admin\languages;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\core\Request;
|
||||
use APP\core\Services;
|
||||
use APP\facades\Repo;
|
||||
use APP\notification\NotificationManager;
|
||||
use PKP\controllers\grid\GridColumn;
|
||||
use PKP\controllers\grid\languages\form\InstallLanguageForm;
|
||||
use PKP\controllers\grid\languages\LanguageGridHandler;
|
||||
use PKP\core\JSONMessage;
|
||||
use PKP\core\PKPRequest;
|
||||
use PKP\db\DAORegistry;
|
||||
use PKP\facades\Locale;
|
||||
use PKP\linkAction\LinkAction;
|
||||
use PKP\linkAction\request\AjaxModal;
|
||||
use PKP\notification\PKPNotification;
|
||||
use PKP\security\authorization\PolicySet;
|
||||
use PKP\security\authorization\RoleBasedHandlerOperationPolicy;
|
||||
use PKP\security\Role;
|
||||
use PKP\services\interfaces\EntityWriteInterface;
|
||||
use PKP\site\Site;
|
||||
use PKP\site\SiteDAO;
|
||||
|
||||
class AdminLanguageGridHandler extends LanguageGridHandler
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->addRoleAssignment(
|
||||
[Role::ROLE_ID_SITE_ADMIN],
|
||||
[
|
||||
'fetchGrid', 'fetchRow',
|
||||
'installLocale', 'saveInstallLocale', 'uninstallLocale',
|
||||
'disableLocale', 'enableLocale', 'setPrimaryLocale'
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Implement template methods from PKPHandler.
|
||||
//
|
||||
/**
|
||||
* @copydoc GridHandler::authorize()
|
||||
*/
|
||||
public function authorize($request, &$args, $roleAssignments)
|
||||
{
|
||||
$rolePolicy = new PolicySet(PolicySet::COMBINING_PERMIT_OVERRIDES);
|
||||
|
||||
foreach ($roleAssignments as $role => $operations) {
|
||||
$rolePolicy->addPolicy(new RoleBasedHandlerOperationPolicy($request, $role, $operations));
|
||||
}
|
||||
$this->addPolicy($rolePolicy);
|
||||
|
||||
return parent::authorize($request, $args, $roleAssignments);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc LanguageGridHandler::initialize()
|
||||
*
|
||||
* @param null|mixed $args
|
||||
*/
|
||||
public function initialize($request, $args = null)
|
||||
{
|
||||
parent::initialize($request, $args);
|
||||
|
||||
// Grid actions.
|
||||
$router = $request->getRouter();
|
||||
|
||||
$this->addAction(
|
||||
new LinkAction(
|
||||
'installLocale',
|
||||
new AjaxModal(
|
||||
$router->url($request, null, null, 'installLocale', null, null),
|
||||
__('admin.languages.installLocale'),
|
||||
null,
|
||||
true
|
||||
),
|
||||
__('admin.languages.installLocale'),
|
||||
'add'
|
||||
)
|
||||
);
|
||||
|
||||
// Columns.
|
||||
// Enable locale.
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'enable',
|
||||
'common.enable',
|
||||
null,
|
||||
'controllers/grid/common/cell/selectStatusCell.tpl',
|
||||
$this->getCellProvider(),
|
||||
['width' => 10]
|
||||
)
|
||||
);
|
||||
|
||||
$this->addNameColumn(); // Locale name.
|
||||
$this->addLocaleCodeColumn(); // Locale code.
|
||||
|
||||
// Primary locale.
|
||||
if ($this->_canManage($request)) {
|
||||
$primaryId = 'contextPrimary';
|
||||
} else {
|
||||
$primaryId = 'sitePrimary';
|
||||
}
|
||||
$this->addPrimaryColumn($primaryId);
|
||||
|
||||
if ($this->_canManage($request)) {
|
||||
$this->addManagementColumns();
|
||||
}
|
||||
|
||||
$this->setFootNote('admin.locale.maybeIncomplete');
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Implement methods from GridHandler.
|
||||
//
|
||||
/**
|
||||
* @copydoc GridHandler::loadData()
|
||||
*/
|
||||
protected function loadData($request, $filter)
|
||||
{
|
||||
$site = $request->getSite(); /** @var Site $site */
|
||||
$data = [];
|
||||
|
||||
$installedLocales = $site->getInstalledLocaleNames();
|
||||
$supportedLocales = $site->getSupportedLocales();
|
||||
$primaryLocale = $site->getPrimaryLocale();
|
||||
|
||||
foreach ($installedLocales as $localeKey => $localeName) {
|
||||
$data[$localeKey] = [];
|
||||
$data[$localeKey]['code'] = $localeKey;
|
||||
$data[$localeKey]['name'] = $localeName;
|
||||
$data[$localeKey]['incomplete'] = !Locale::getMetadata($localeKey)->isComplete();
|
||||
$data[$localeKey]['supported'] = in_array($localeKey, $supportedLocales);
|
||||
|
||||
if ($this->_canManage($request)) {
|
||||
$context = $request->getContext();
|
||||
$primaryLocale = $context->getPrimaryLocale();
|
||||
}
|
||||
|
||||
$data[$localeKey]['primary'] = $localeKey === $primaryLocale;
|
||||
}
|
||||
|
||||
if ($this->_canManage($request)) {
|
||||
$data = $this->addManagementData($request, $data);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Public grid actions.
|
||||
//
|
||||
/**
|
||||
* Open a form to select locales for installation.
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function installLocale($args, $request)
|
||||
{
|
||||
// Form handling.
|
||||
$installLanguageForm = new InstallLanguageForm();
|
||||
$installLanguageForm->initData();
|
||||
return new JSONMessage(true, $installLanguageForm->fetch($request));
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the install language form.
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function saveInstallLocale($args, $request)
|
||||
{
|
||||
$installLanguageForm = new InstallLanguageForm();
|
||||
$installLanguageForm->readInputData();
|
||||
|
||||
if ($installLanguageForm->validate()) {
|
||||
$installLanguageForm->execute();
|
||||
$this->_updateContextLocaleSettings($request);
|
||||
|
||||
$notificationManager = new NotificationManager();
|
||||
$user = $request->getUser();
|
||||
$notificationManager->createTrivialNotification(
|
||||
$user->getId(),
|
||||
PKPNotification::NOTIFICATION_TYPE_SUCCESS,
|
||||
['contents' => __('notification.localeInstalled')]
|
||||
);
|
||||
}
|
||||
return \PKP\db\DAO::getDataChangedEvent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Uninstall a locale.
|
||||
*
|
||||
* @param array $args
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function uninstallLocale($args, $request)
|
||||
{
|
||||
$site = $request->getSite();
|
||||
$locale = $request->getUserVar('rowId');
|
||||
$gridData = $this->getGridDataElements($request);
|
||||
|
||||
if ($request->checkCSRF() && array_key_exists($locale, $gridData)) {
|
||||
$localeData = $gridData[$locale];
|
||||
if ($localeData['primary']) {
|
||||
return new JSONMessage(false);
|
||||
}
|
||||
|
||||
$installedLocales = $site->getInstalledLocales();
|
||||
if (in_array($locale, $installedLocales)) {
|
||||
$installedLocales = array_diff($installedLocales, [$locale]);
|
||||
$site->setInstalledLocales($installedLocales);
|
||||
$supportedLocales = $site->getSupportedLocales();
|
||||
$supportedLocales = array_diff($supportedLocales, [$locale]);
|
||||
$site->setSupportedLocales($supportedLocales);
|
||||
$siteDao = DAORegistry::getDAO('SiteDAO'); /** @var SiteDAO $siteDao */
|
||||
$siteDao->updateObject($site);
|
||||
|
||||
$this->_updateContextLocaleSettings($request);
|
||||
Locale::uninstallLocale($locale);
|
||||
|
||||
$notificationManager = new NotificationManager();
|
||||
$user = $request->getUser();
|
||||
$notificationManager->createTrivialNotification(
|
||||
$user->getId(),
|
||||
PKPNotification::NOTIFICATION_TYPE_SUCCESS,
|
||||
['contents' => __('notification.localeUninstalled', ['locale' => $localeData['name']])]
|
||||
);
|
||||
}
|
||||
return \PKP\db\DAO::getDataChangedEvent($locale);
|
||||
}
|
||||
|
||||
return new JSONMessage(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable an existing locale.
|
||||
*
|
||||
* @param array $args
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function enableLocale($args, $request)
|
||||
{
|
||||
$rowId = $request->getUserVar('rowId');
|
||||
$gridData = $this->getGridDataElements($request);
|
||||
|
||||
if (array_key_exists($rowId, $gridData)) {
|
||||
$this->_updateLocaleSupportState($request, $rowId, true);
|
||||
|
||||
$notificationManager = new NotificationManager();
|
||||
$user = $request->getUser();
|
||||
$notificationManager->createTrivialNotification(
|
||||
$user->getId(),
|
||||
PKPNotification::NOTIFICATION_TYPE_SUCCESS,
|
||||
['contents' => __('notification.localeEnabled')]
|
||||
);
|
||||
}
|
||||
|
||||
return \PKP\db\DAO::getDataChangedEvent($rowId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable an existing locale.
|
||||
*
|
||||
* @param array $args
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function disableLocale($args, $request)
|
||||
{
|
||||
$locale = $request->getUserVar('rowId');
|
||||
$gridData = $this->getGridDataElements($request);
|
||||
$notificationManager = new NotificationManager();
|
||||
$user = $request->getUser();
|
||||
|
||||
if ($request->checkCSRF() && array_key_exists($locale, $gridData)) {
|
||||
// Don't disable primary locales.
|
||||
if ($gridData[$locale]['primary']) {
|
||||
$notificationManager->createTrivialNotification(
|
||||
$user->getId(),
|
||||
PKPNotification::NOTIFICATION_TYPE_ERROR,
|
||||
['contents' => __('admin.languages.cantDisable')]
|
||||
);
|
||||
} else {
|
||||
$this->_updateLocaleSupportState($request, $locale, false);
|
||||
$notificationManager->createTrivialNotification(
|
||||
$user->getId(),
|
||||
PKPNotification::NOTIFICATION_TYPE_SUCCESS,
|
||||
['contents' => __('notification.localeDisabled')]
|
||||
);
|
||||
}
|
||||
return \PKP\db\DAO::getDataChangedEvent($locale);
|
||||
}
|
||||
|
||||
return new JSONMessage(false);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set primary locale.
|
||||
*
|
||||
* @param array $args
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function setPrimaryLocale($args, $request)
|
||||
{
|
||||
$rowId = $request->getUserVar('rowId');
|
||||
$gridData = $this->getGridDataElements($request);
|
||||
$localeData = $gridData[$rowId];
|
||||
$notificationManager = new NotificationManager();
|
||||
$user = $request->getUser();
|
||||
$site = $request->getSite();
|
||||
|
||||
if (array_key_exists($rowId, $gridData)) {
|
||||
if (Locale::isLocaleValid($rowId)) {
|
||||
$oldSitePrimaryLocale = $site->getPrimaryLocale();
|
||||
Repo::user()->dao->changeSitePrimaryLocale($oldSitePrimaryLocale, $rowId);
|
||||
$site->setPrimaryLocale($rowId);
|
||||
$siteDao = DAORegistry::getDAO('SiteDAO'); /** @var SiteDAO $siteDao */
|
||||
$siteDao->updateObject($site);
|
||||
|
||||
$notificationManager->createTrivialNotification(
|
||||
$user->getId(),
|
||||
PKPNotification::NOTIFICATION_TYPE_SUCCESS,
|
||||
['contents' => __('notification.primaryLocaleDefined', ['locale' => $localeData['name']])]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Need to refresh whole grid to remove the check in others
|
||||
// primary locale radio buttons.
|
||||
return \PKP\db\DAO::getDataChangedEvent();
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Helper methods.
|
||||
//
|
||||
/**
|
||||
* Update the locale support state (enabled or disabled).
|
||||
*
|
||||
* @param Request $request
|
||||
* @param string $rowId The locale row id.
|
||||
* @param bool $enable Enable locale flag.
|
||||
*/
|
||||
protected function _updateLocaleSupportState($request, $rowId, $enable)
|
||||
{
|
||||
$newSupportedLocales = [];
|
||||
$gridData = $this->getGridDataElements($request);
|
||||
|
||||
foreach ($gridData as $locale => $data) {
|
||||
if ($data['supported']) {
|
||||
array_push($newSupportedLocales, $locale);
|
||||
}
|
||||
}
|
||||
|
||||
if (Locale::isLocaleValid($rowId)) {
|
||||
if ($enable) {
|
||||
array_push($newSupportedLocales, $rowId);
|
||||
} else {
|
||||
$key = array_search($rowId, $newSupportedLocales);
|
||||
if ($key !== false) {
|
||||
unset($newSupportedLocales[$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$site = $request->getSite();
|
||||
$site->setSupportedLocales($newSupportedLocales);
|
||||
|
||||
$siteDao = DAORegistry::getDAO('SiteDAO'); /** @var SiteDAO $siteDao */
|
||||
$siteDao->updateObject($site);
|
||||
|
||||
$this->_updateContextLocaleSettings($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to update locale settings in all
|
||||
* installed contexts, based on site locale settings.
|
||||
*
|
||||
* @param object $request
|
||||
*/
|
||||
protected function _updateContextLocaleSettings($request)
|
||||
{
|
||||
$site = $request->getSite();
|
||||
$siteSupportedLocales = $site->getSupportedLocales();
|
||||
$contextService = Services::get('context');
|
||||
|
||||
$contextDao = Application::getContextDAO();
|
||||
$contexts = $contextDao->getAll();
|
||||
while ($context = $contexts->next()) {
|
||||
$params = [];
|
||||
$primaryLocale = $context->getPrimaryLocale();
|
||||
foreach (['supportedLocales', 'supportedFormLocales', 'supportedSubmissionLocales'] as $settingName) {
|
||||
$localeList = $context->getData($settingName);
|
||||
|
||||
if (is_array($localeList)) {
|
||||
$params[$settingName] = array_intersect($localeList, $siteSupportedLocales);
|
||||
}
|
||||
}
|
||||
if (!in_array($primaryLocale, $siteSupportedLocales)) {
|
||||
$params['primaryLocale'] = $site->getPrimaryLocale();
|
||||
$primaryLocale = $params['primaryLocale'];
|
||||
}
|
||||
$errors = $contextService->validate(EntityWriteInterface::VALIDATE_ACTION_EDIT, $params, $params['supportedLocales'], $primaryLocale);
|
||||
// If there are errors, it's too late to do anything about it
|
||||
assert(empty($errors));
|
||||
$contextService->edit($context, $params, $request);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This grid can also present management functions
|
||||
* if the conditions above are true.
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function _canManage($request)
|
||||
{
|
||||
$contextDao = Application::getContextDAO();
|
||||
$contexts = $contextDao->getAll();
|
||||
$userRoles = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_USER_ROLES);
|
||||
[$firstContext, $secondContext] = [$contexts->next(), $contexts->next()];
|
||||
return ($firstContext && !$secondContext && $request->getContext() && in_array(Role::ROLE_ID_MANAGER, $userRoles));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/admin/plugins/AdminPluginGridHandler.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 AdminPluginGridHandler
|
||||
*
|
||||
* @ingroup controllers_grid_admin_plugins
|
||||
*
|
||||
* @brief Handle site level plugins grid requests.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\admin\plugins;
|
||||
|
||||
use APP\core\Application;
|
||||
use PKP\controllers\grid\plugins\PluginGridHandler;
|
||||
use PKP\controllers\grid\plugins\PluginGridRow;
|
||||
use PKP\core\PKPRequest;
|
||||
use PKP\security\authorization\PluginAccessPolicy;
|
||||
use PKP\security\authorization\PolicySet;
|
||||
use PKP\security\authorization\RoleBasedHandlerOperationPolicy;
|
||||
use PKP\security\Role;
|
||||
|
||||
class AdminPluginGridHandler extends PluginGridHandler
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$roles = [Role::ROLE_ID_SITE_ADMIN];
|
||||
|
||||
$this->addRoleAssignment($roles, ['plugin']);
|
||||
|
||||
parent::__construct($roles);
|
||||
}
|
||||
|
||||
//
|
||||
// Overriden template methods.
|
||||
//
|
||||
/**
|
||||
* @see GridHandler::getRowInstance()
|
||||
*/
|
||||
public function getRowInstance()
|
||||
{
|
||||
return new PluginGridRow($this->getAuthorizedContextObject(Application::ASSOC_TYPE_USER_ROLES));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see GridHandler::authorize()
|
||||
*
|
||||
* @param PKPRequest $request
|
||||
* @param array $args
|
||||
* @param array $roleAssignments
|
||||
*/
|
||||
public function authorize($request, &$args, $roleAssignments)
|
||||
{
|
||||
$category = $request->getUserVar('category');
|
||||
$pluginName = $request->getUserVar('plugin');
|
||||
$verb = $request->getUserVar('verb');
|
||||
|
||||
if ($category && $pluginName) {
|
||||
if ($verb) {
|
||||
$accessMode = PluginAccessPolicy::ACCESS_MODE_MANAGE;
|
||||
} else {
|
||||
$accessMode = PluginAccessPolicy::ACCESS_MODE_ADMIN;
|
||||
}
|
||||
|
||||
$this->addPolicy(new PluginAccessPolicy($request, $args, $roleAssignments, $accessMode));
|
||||
} else {
|
||||
$rolePolicy = new PolicySet(PolicySet::COMBINING_PERMIT_OVERRIDES);
|
||||
|
||||
foreach ($roleAssignments as $role => $operations) {
|
||||
$rolePolicy->addPolicy(new RoleBasedHandlerOperationPolicy($request, $role, $operations));
|
||||
}
|
||||
$this->addPolicy($rolePolicy);
|
||||
}
|
||||
|
||||
return parent::authorize($request, $args, $roleAssignments);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/announcements/AnnouncementTypeGridCellProvider.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 AnnouncementTypeGridCellProvider
|
||||
*
|
||||
* @ingroup controllers_grid_announcements
|
||||
*
|
||||
* @brief Cell provider for title column of an announcement type grid.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\announcements;
|
||||
|
||||
use PKP\controllers\grid\GridCellProvider;
|
||||
use PKP\controllers\grid\GridColumn;
|
||||
use PKP\controllers\grid\GridHandler;
|
||||
use PKP\linkAction\LinkAction;
|
||||
use PKP\linkAction\request\AjaxModal;
|
||||
|
||||
class AnnouncementTypeGridCellProvider extends GridCellProvider
|
||||
{
|
||||
/**
|
||||
* @copydoc GridCellProvider::getCellActions()
|
||||
*/
|
||||
public function getCellActions($request, $row, $column, $position = GridHandler::GRID_ACTION_POSITION_DEFAULT)
|
||||
{
|
||||
switch ($column->getId()) {
|
||||
case 'name':
|
||||
$announcementType = $row->getData();
|
||||
$router = $request->getRouter();
|
||||
$actionArgs = ['announcementTypeId' => $row->getId()];
|
||||
|
||||
return [new LinkAction(
|
||||
'edit',
|
||||
new AjaxModal(
|
||||
$router->url($request, null, null, 'editAnnouncementType', null, $actionArgs),
|
||||
__('grid.action.edit'),
|
||||
null,
|
||||
true
|
||||
),
|
||||
htmlspecialchars($announcementType->getLocalizedTypeName())
|
||||
)];
|
||||
}
|
||||
return parent::getCellActions($request, $row, $column, $position);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts variables for a given column from a data element
|
||||
* so that they may be assigned to template before rendering.
|
||||
*
|
||||
* @param \PKP\controllers\grid\GridRow $row
|
||||
* @param GridColumn $column
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getTemplateVarsFromRowColumn($row, $column)
|
||||
{
|
||||
$announcementType = $row->getData();
|
||||
$columnId = $column->getId();
|
||||
assert($announcementType instanceof \PKP\announcement\AnnouncementType && !empty($columnId));
|
||||
|
||||
switch ($columnId) {
|
||||
case 'title':
|
||||
return ['label' => $announcementType->getLocalizedTypeName()];
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return parent::getTemplateVarsFromRowColumn($row, $column);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,246 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/announcements/AnnouncementTypeGridHandler.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 AnnouncementTypeGridHandler
|
||||
*
|
||||
* @ingroup controllers_grid_announcements
|
||||
*
|
||||
* @brief Handle announcement type grid requests.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\announcements;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\notification\NotificationManager;
|
||||
use PKP\announcement\AnnouncementTypeDAO;
|
||||
use PKP\controllers\grid\announcements\form\AnnouncementTypeForm;
|
||||
use PKP\controllers\grid\GridColumn;
|
||||
use PKP\controllers\grid\GridHandler;
|
||||
use PKP\core\JSONMessage;
|
||||
use PKP\core\PKPRequest;
|
||||
use PKP\db\DAORegistry;
|
||||
use PKP\linkAction\LinkAction;
|
||||
use PKP\linkAction\request\AjaxModal;
|
||||
use PKP\notification\PKPNotification;
|
||||
use PKP\security\authorization\ContextAccessPolicy;
|
||||
use PKP\security\authorization\PKPSiteAccessPolicy;
|
||||
use PKP\security\authorization\UserRolesRequiredPolicy;
|
||||
use PKP\security\Role;
|
||||
|
||||
class AnnouncementTypeGridHandler extends GridHandler
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->addRoleAssignment(
|
||||
[Role::ROLE_ID_MANAGER, Role::ROLE_ID_SITE_ADMIN],
|
||||
[
|
||||
'fetchGrid', 'fetchRow',
|
||||
'addAnnouncementType', 'editAnnouncementType',
|
||||
'updateAnnouncementType',
|
||||
'deleteAnnouncementType'
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// Overridden template methods
|
||||
//
|
||||
/**
|
||||
* @copydoc GridHandler::authorize()
|
||||
*/
|
||||
public function authorize($request, &$args, $roleAssignments)
|
||||
{
|
||||
$context = $request->getContext();
|
||||
|
||||
if ($context) {
|
||||
$this->addPolicy(new ContextAccessPolicy($request, $roleAssignments));
|
||||
} else {
|
||||
$this->addPolicy(new PKPSiteAccessPolicy($request, null, $roleAssignments));
|
||||
}
|
||||
|
||||
$announcementTypeId = $request->getUserVar('announcementTypeId');
|
||||
if ($announcementTypeId) {
|
||||
// Ensure announcement type is valid and for this context
|
||||
$announcementTypeDao = DAORegistry::getDAO('AnnouncementTypeDAO'); /** @var AnnouncementTypeDAO $announcementTypeDao */
|
||||
$announcementType = $announcementTypeDao->getById($announcementTypeId);
|
||||
if (!$announcementType || $announcementType->getContextId() != $context?->getId()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return parent::authorize($request, $args, $roleAssignments);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::initialize()
|
||||
*
|
||||
* @param null|mixed $args
|
||||
*/
|
||||
public function initialize($request, $args = null)
|
||||
{
|
||||
parent::initialize($request, $args);
|
||||
|
||||
// Basic grid configuration
|
||||
$this->setTitle('manager.announcementTypes');
|
||||
|
||||
// Set the no items row text
|
||||
$this->setEmptyRowText('manager.announcementTypes.noneCreated');
|
||||
|
||||
// Columns
|
||||
$announcementTypeCellProvider = new AnnouncementTypeGridCellProvider();
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'name',
|
||||
'common.name',
|
||||
null,
|
||||
null,
|
||||
$announcementTypeCellProvider,
|
||||
['width' => 60]
|
||||
)
|
||||
);
|
||||
|
||||
// Add grid action.
|
||||
$router = $request->getRouter();
|
||||
|
||||
$this->addAction(
|
||||
new LinkAction(
|
||||
'addAnnouncementType',
|
||||
new AjaxModal(
|
||||
$router->url($request, null, null, 'addAnnouncementType', null, null),
|
||||
__('grid.action.addAnnouncementType'),
|
||||
'modal_add_item',
|
||||
true
|
||||
),
|
||||
__('grid.action.addAnnouncementType'),
|
||||
'add_item'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::loadData()
|
||||
*/
|
||||
protected function loadData($request, $filter)
|
||||
{
|
||||
$announcementTypeDao = DAORegistry::getDAO('AnnouncementTypeDAO'); /** @var AnnouncementTypeDAO $announcementTypeDao */
|
||||
return $announcementTypeDao->getByContextId($request->getContext()?->getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::getRowInstance()
|
||||
*/
|
||||
protected function getRowInstance()
|
||||
{
|
||||
return new AnnouncementTypeGridRow();
|
||||
}
|
||||
|
||||
//
|
||||
// Public grid actions.
|
||||
//
|
||||
/**
|
||||
* Display form to add announcement type.
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return JSONMessage
|
||||
*/
|
||||
public function addAnnouncementType($args, $request)
|
||||
{
|
||||
return $this->editAnnouncementType($args, $request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display form to edit an announcement type.
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function editAnnouncementType($args, $request)
|
||||
{
|
||||
$announcementTypeId = (int)$request->getUserVar('announcementTypeId');
|
||||
$announcementTypeForm = new AnnouncementTypeForm($request->getContext()?->getId(), $announcementTypeId);
|
||||
$announcementTypeForm->initData();
|
||||
|
||||
return new JSONMessage(true, $announcementTypeForm->fetch($request));
|
||||
}
|
||||
|
||||
/**
|
||||
* Save an edited/inserted announcement type.
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function updateAnnouncementType($args, $request)
|
||||
{
|
||||
// Identify the announcement type id.
|
||||
$announcementTypeId = $request->getUserVar('announcementTypeId');
|
||||
|
||||
// Form handling.
|
||||
$announcementTypeForm = new AnnouncementTypeForm($request->getContext()?->getId(), $announcementTypeId);
|
||||
$announcementTypeForm->readInputData();
|
||||
|
||||
if ($announcementTypeForm->validate()) {
|
||||
$announcementTypeForm->execute();
|
||||
|
||||
if ($announcementTypeId) {
|
||||
// Successful edit of an existing announcement type.
|
||||
$notificationLocaleKey = 'notification.editedAnnouncementType';
|
||||
} else {
|
||||
// Successful added a new announcement type.
|
||||
$notificationLocaleKey = 'notification.addedAnnouncementType';
|
||||
}
|
||||
|
||||
// Record the notification to user.
|
||||
$notificationManager = new NotificationManager();
|
||||
$user = $request->getUser();
|
||||
$notificationManager->createTrivialNotification($user->getId(), PKPNotification::NOTIFICATION_TYPE_SUCCESS, ['contents' => __($notificationLocaleKey)]);
|
||||
|
||||
// Prepare the grid row data.
|
||||
return \PKP\db\DAO::getDataChangedEvent($announcementTypeId);
|
||||
} else {
|
||||
return new JSONMessage(false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete an announcement type.
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function deleteAnnouncementType($args, $request)
|
||||
{
|
||||
$announcementTypeId = (int) $request->getUserVar('announcementTypeId');
|
||||
|
||||
$announcementTypeDao = DAORegistry::getDAO('AnnouncementTypeDAO'); /** @var AnnouncementTypeDAO $announcementTypeDao */
|
||||
$announcementType = $announcementTypeDao->getById($announcementTypeId, $request->getContext()?->getId());
|
||||
if ($announcementType && $request->checkCSRF()) {
|
||||
$announcementTypeDao->deleteObject($announcementType);
|
||||
|
||||
// Create notification.
|
||||
$notificationManager = new NotificationManager();
|
||||
$user = $request->getUser();
|
||||
$notificationManager->createTrivialNotification($user->getId(), PKPNotification::NOTIFICATION_TYPE_SUCCESS, ['contents' => __('notification.removedAnnouncementType')]);
|
||||
|
||||
return \PKP\db\DAO::getDataChangedEvent();
|
||||
}
|
||||
|
||||
return new JSONMessage(false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/announcements/AnnouncementTypeGridRow.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 AnnouncementTypeGridRow
|
||||
*
|
||||
* @ingroup controllers_grid_content_announcements
|
||||
*
|
||||
* @brief Announcement type grid row definition
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\announcements;
|
||||
|
||||
use PKP\controllers\grid\GridRow;
|
||||
use PKP\linkAction\LinkAction;
|
||||
use PKP\linkAction\request\AjaxModal;
|
||||
use PKP\linkAction\request\RemoteActionConfirmationModal;
|
||||
|
||||
class AnnouncementTypeGridRow extends GridRow
|
||||
{
|
||||
//
|
||||
// Overridden methods from GridRow
|
||||
//
|
||||
/**
|
||||
* @copydoc GridRow::initialize()
|
||||
*
|
||||
* @param null|mixed $template
|
||||
*/
|
||||
public function initialize($request, $template = null)
|
||||
{
|
||||
parent::initialize($request, $template);
|
||||
|
||||
// Is this a new row or an existing row?
|
||||
$element = $this->getData();
|
||||
assert($element instanceof \PKP\announcement\AnnouncementType);
|
||||
|
||||
$rowId = $this->getId();
|
||||
|
||||
if (!empty($rowId) && is_numeric($rowId)) {
|
||||
// Only add row actions if this is an existing row
|
||||
$router = $request->getRouter();
|
||||
$actionArgs = [
|
||||
'announcementTypeId' => $rowId
|
||||
];
|
||||
$this->addAction(
|
||||
new LinkAction(
|
||||
'edit',
|
||||
new AjaxModal(
|
||||
$router->url($request, null, null, 'editAnnouncementType', null, $actionArgs),
|
||||
__('grid.action.edit'),
|
||||
'modal_edit',
|
||||
true
|
||||
),
|
||||
__('grid.action.edit'),
|
||||
'edit'
|
||||
)
|
||||
);
|
||||
$this->addAction(
|
||||
new LinkAction(
|
||||
'remove',
|
||||
new RemoteActionConfirmationModal(
|
||||
$request->getSession(),
|
||||
__('common.confirmDelete'),
|
||||
__('common.remove'),
|
||||
$router->url($request, null, null, 'deleteAnnouncementType', null, $actionArgs),
|
||||
'modal_delete'
|
||||
),
|
||||
__('grid.action.remove'),
|
||||
'delete'
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/announcements/form/AnnouncementTypeForm.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 AnnouncementTypeForm
|
||||
*
|
||||
* @ingroup controllers_grid_announcements_form
|
||||
*
|
||||
* @see AnnouncementType
|
||||
*
|
||||
* @brief Form for manager to create/edit announcement types.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\announcements\form;
|
||||
|
||||
use APP\template\TemplateManager;
|
||||
use PKP\announcement\AnnouncementTypeDAO;
|
||||
use PKP\db\DAORegistry;
|
||||
use PKP\form\Form;
|
||||
|
||||
class AnnouncementTypeForm extends Form
|
||||
{
|
||||
/** @var ?int Context ID or null for site announcement */
|
||||
public $contextId;
|
||||
|
||||
/** @var int The ID of the announcement type being edited */
|
||||
public $typeId;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param ?int $contextId Context ID or null for site announcement
|
||||
* @param int $typeId leave as default for new announcement type
|
||||
*/
|
||||
public function __construct($contextId, $typeId = null)
|
||||
{
|
||||
$this->typeId = isset($typeId) ? (int) $typeId : null;
|
||||
$this->contextId = $contextId;
|
||||
|
||||
parent::__construct('manager/announcement/announcementTypeForm.tpl');
|
||||
|
||||
// Type name is provided
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorLocale($this, 'name', 'required', 'manager.announcementTypes.form.typeNameRequired'));
|
||||
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorPost($this));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorCSRF($this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of localized field names for this form
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getLocaleFieldNames()
|
||||
{
|
||||
$announcementTypeDao = DAORegistry::getDAO('AnnouncementTypeDAO'); /** @var AnnouncementTypeDAO $announcementTypeDao */
|
||||
return $announcementTypeDao->getLocaleFieldNames();
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::fetch()
|
||||
*/
|
||||
public function fetch($request, $template = 'controllers/grid/announcements/form/announcementTypeForm.tpl', $display = false)
|
||||
{
|
||||
$templateMgr = TemplateManager::getManager($request);
|
||||
$templateMgr->assign('typeId', $this->typeId);
|
||||
return parent::fetch($request, $template, $display);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize form data from current announcement type.
|
||||
*/
|
||||
public function initData()
|
||||
{
|
||||
if (isset($this->typeId)) {
|
||||
$announcementTypeDao = DAORegistry::getDAO('AnnouncementTypeDAO'); /** @var AnnouncementTypeDAO $announcementTypeDao */
|
||||
$announcementType = $announcementTypeDao->getById($this->typeId);
|
||||
|
||||
if ($announcementType != null) {
|
||||
$this->_data = [
|
||||
'name' => $announcementType->getName(null) // Localized
|
||||
];
|
||||
} else {
|
||||
$this->typeId = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign form data to user-submitted data.
|
||||
*/
|
||||
public function readInputData()
|
||||
{
|
||||
$this->readUserVars(['name']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::execute()
|
||||
*/
|
||||
public function execute(...$functionArgs)
|
||||
{
|
||||
$announcementTypeDao = DAORegistry::getDAO('AnnouncementTypeDAO'); /** @var AnnouncementTypeDAO $announcementTypeDao */
|
||||
|
||||
if (isset($this->typeId)) {
|
||||
$announcementType = $announcementTypeDao->getById($this->typeId);
|
||||
}
|
||||
|
||||
if (!isset($announcementType)) {
|
||||
$announcementType = $announcementTypeDao->newDataObject();
|
||||
}
|
||||
|
||||
$announcementType->setContextId($this->contextId);
|
||||
$announcementType->setName($this->getData('name'), null); // Localized
|
||||
|
||||
// Update or insert announcement type
|
||||
if ($announcementType->getId() != null) {
|
||||
$announcementTypeDao->updateObject($announcementType);
|
||||
} else {
|
||||
$announcementTypeDao->insertObject($announcementType);
|
||||
}
|
||||
parent::execute(...$functionArgs);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/eventLog/EventLogGridCellProvider.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 EventLogGridCellProvider
|
||||
*
|
||||
* @ingroup controllers_grid_publicationEntry
|
||||
*
|
||||
* @brief Cell provider for event log entries.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\eventLog;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\facades\Repo;
|
||||
use PKP\controllers\grid\DataObjectGridCellProvider;
|
||||
use PKP\controllers\grid\GridColumn;
|
||||
use PKP\db\DAORegistry;
|
||||
use PKP\log\event\EventLogEntry;
|
||||
use PKP\log\event\PKPSubmissionEventLogEntry;
|
||||
use PKP\submission\reviewAssignment\ReviewAssignment;
|
||||
use PKP\submission\reviewAssignment\ReviewAssignmentDAO;
|
||||
use PKP\submissionFile\SubmissionFile;
|
||||
|
||||
class EventLogGridCellProvider extends DataObjectGridCellProvider
|
||||
{
|
||||
/** @var bool Is the current user assigned as an author to this submission */
|
||||
public $_isCurrentUserAssignedAuthor;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param bool $isCurrentUserAssignedAuthor Is the current user assigned
|
||||
* as an author to this submission?
|
||||
*/
|
||||
public function __construct($isCurrentUserAssignedAuthor)
|
||||
{
|
||||
parent::__construct();
|
||||
$this->_isCurrentUserAssignedAuthor = $isCurrentUserAssignedAuthor;
|
||||
}
|
||||
|
||||
//
|
||||
// Template methods from GridCellProvider
|
||||
//
|
||||
/**
|
||||
* Extracts variables for a given column from a data element
|
||||
* so that they may be assigned to template before rendering.
|
||||
*
|
||||
* @param \PKP\controllers\grid\GridRow $row
|
||||
* @param GridColumn $column
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getTemplateVarsFromRowColumn($row, $column)
|
||||
{
|
||||
$element = $row->getData();
|
||||
$columnId = $column->getId();
|
||||
assert($element instanceof \PKP\core\DataObject && !empty($columnId));
|
||||
/** @var EventLogEntry $element */
|
||||
switch ($columnId) {
|
||||
case 'date':
|
||||
return ['label' => $element instanceof EventLogEntry ? $element->getDateLogged() : $element->getDateSent()];
|
||||
case 'event':
|
||||
return ['label' => $element instanceof EventLogEntry ? $element->getTranslatedMessage(null, $this->_isCurrentUserAssignedAuthor) : $element->getPrefixedSubject()];
|
||||
case 'user':
|
||||
if ($element instanceof EventLogEntry) {
|
||||
$userName = $element->getUserFullName();
|
||||
|
||||
// Anonymize reviewer details where necessary
|
||||
if ($this->_isCurrentUserAssignedAuthor) {
|
||||
$reviewAssignmentDao = DAORegistry::getDAO('ReviewAssignmentDAO'); /** @var ReviewAssignmentDAO $reviewAssignmentDao */
|
||||
|
||||
// Maybe anonymize reviewer log entries
|
||||
$reviewerLogTypes = [
|
||||
PKPSubmissionEventLogEntry::SUBMISSION_LOG_REVIEW_ACCEPT,
|
||||
PKPSubmissionEventLogEntry::SUBMISSION_LOG_REVIEW_DECLINE,
|
||||
PKPSubmissionEventLogEntry::SUBMISSION_LOG_REVIEW_UNCONSIDERED,
|
||||
];
|
||||
if (in_array($element->getEventType(), $reviewerLogTypes)) {
|
||||
$userName = __('editor.review.anonymousReviewer');
|
||||
if ($reviewAssignmentId = $element->getData('reviewAssignmentId')) {
|
||||
$reviewAssignment = $reviewAssignmentDao->getById($reviewAssignmentId);
|
||||
if ($reviewAssignment && $reviewAssignment->getReviewMethod() === ReviewAssignment::SUBMISSION_REVIEW_METHOD_OPEN) {
|
||||
$userName = $element->getUserFullName();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Maybe anonymize files submitted by reviewers
|
||||
$fileStage = $element->getData('fileStage');
|
||||
if ($fileStage && $fileStage === SubmissionFile::SUBMISSION_FILE_REVIEW_ATTACHMENT) {
|
||||
$submissionFileId = $element->getData('submissionFileId');
|
||||
assert($element->getData('fileId') && $element->getData('submissionId') && $submissionFileId);
|
||||
$submissionFile = Repo::submissionFile()->get($submissionFileId);
|
||||
if ($submissionFile && $submissionFile->getData('assocType') === Application::ASSOC_TYPE_REVIEW_ASSIGNMENT) {
|
||||
$reviewAssignment = $reviewAssignmentDao->getById($submissionFile->getData('assocId'));
|
||||
if (!$reviewAssignment || in_array($reviewAssignment->getReviewMethod(), [ReviewAssignment::SUBMISSION_REVIEW_METHOD_ANONYMOUS, ReviewAssignment::SUBMISSION_REVIEW_METHOD_DOUBLEANONYMOUS])) {
|
||||
$userName = __('editor.review.anonymousReviewer');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$userName = $element->getSenderFullName();
|
||||
}
|
||||
return ['label' => $userName];
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/eventLog/EventLogGridRow.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 EventLogGridRow
|
||||
*
|
||||
* @ingroup controllers_grid_eventLog
|
||||
*
|
||||
* @brief EventLog grid row definition
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\eventLog;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\facades\Repo;
|
||||
use APP\submission\Submission;
|
||||
use PKP\controllers\api\file\linkAction\DownloadFileLinkAction;
|
||||
use PKP\controllers\grid\eventLog\linkAction\EmailLinkAction;
|
||||
use PKP\controllers\grid\GridRow;
|
||||
use PKP\db\DAORegistry;
|
||||
use PKP\log\EmailLogEntry;
|
||||
use PKP\log\event\EventLogEntry;
|
||||
use PKP\log\event\SubmissionFileEventLogEntry;
|
||||
use PKP\submission\reviewAssignment\ReviewAssignment;
|
||||
use PKP\submission\reviewAssignment\ReviewAssignmentDAO;
|
||||
use PKP\submissionFile\SubmissionFile;
|
||||
|
||||
class EventLogGridRow extends GridRow
|
||||
{
|
||||
/** @var Submission */
|
||||
public $_submission;
|
||||
|
||||
/** @var bool Is the current user assigned as an author to this submission */
|
||||
public $_isCurrentUserAssignedAuthor;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param Submission $submission
|
||||
* @param bool $isCurrentUserAssignedAuthor Is the current user assigned
|
||||
* as an author to this submission?
|
||||
*/
|
||||
public function __construct($submission, $isCurrentUserAssignedAuthor)
|
||||
{
|
||||
$this->_submission = $submission;
|
||||
$this->_isCurrentUserAssignedAuthor = $isCurrentUserAssignedAuthor;
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
//
|
||||
// Overridden methods from GridRow
|
||||
//
|
||||
/**
|
||||
* @copydoc GridRow::initialize()
|
||||
*
|
||||
* @param null|mixed $template
|
||||
*/
|
||||
public function initialize($request, $template = null)
|
||||
{
|
||||
parent::initialize($request, $template);
|
||||
|
||||
$logEntry = $this->getData(); // a Category object
|
||||
assert($logEntry != null && ($logEntry instanceof EventLogEntry || $logEntry instanceof EmailLogEntry));
|
||||
|
||||
if ($logEntry instanceof EventLogEntry) {
|
||||
|
||||
switch ($logEntry->getEventType()) {
|
||||
case SubmissionFileEventLogEntry::SUBMISSION_LOG_FILE_REVISION_UPLOAD:
|
||||
case SubmissionFileEventLogEntry::SUBMISSION_LOG_FILE_UPLOAD:
|
||||
$submissionFileId = $logEntry->getData('submissionFileId');
|
||||
$fileId = $logEntry->getData('fileId');
|
||||
$submissionFile = $submissionFileId ? Repo::submissionFile()->get($submissionFileId) : null;
|
||||
if (!$submissionFile) {
|
||||
break;
|
||||
}
|
||||
$filename = $logEntry->getLocalizedData('filename') ?? $submissionFile->getLocalizedData('name');
|
||||
if ($submissionFile) {
|
||||
$anonymousAuthor = false;
|
||||
$maybeAnonymousAuthor = $this->_isCurrentUserAssignedAuthor && $submissionFile->getData('fileStage') === SubmissionFile::SUBMISSION_FILE_REVIEW_ATTACHMENT;
|
||||
if ($maybeAnonymousAuthor && $submissionFile->getData('assocType') === Application::ASSOC_TYPE_REVIEW_ASSIGNMENT) {
|
||||
$reviewAssignmentDao = DAORegistry::getDAO('ReviewAssignmentDAO'); /** @var ReviewAssignmentDAO $reviewAssignmentDao */
|
||||
$reviewAssignment = $reviewAssignmentDao->getById($submissionFile->getData('assocId'));
|
||||
if ($reviewAssignment && in_array($reviewAssignment->getReviewMethod(), [ReviewAssignment::SUBMISSION_REVIEW_METHOD_ANONYMOUS, ReviewAssignment::SUBMISSION_REVIEW_METHOD_DOUBLEANONYMOUS])) {
|
||||
$anonymousAuthor = true;
|
||||
}
|
||||
}
|
||||
if (!$anonymousAuthor) {
|
||||
$workflowStageId = Repo::submissionFile()->getWorkflowStageId($submissionFile);
|
||||
// If a submission file is attached to a query that has been deleted, we cannot
|
||||
// determine its stage. Don't present a download link in this case.
|
||||
if ($workflowStageId || $submissionFile->getData('fileStage') != SubmissionFile::SUBMISSION_FILE_QUERY) {
|
||||
$this->addAction(new DownloadFileLinkAction($request, $submissionFile, $workflowStageId, __('common.download'), $fileId, $filename));
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
} elseif ($logEntry instanceof EmailLogEntry) {
|
||||
$this->addAction(
|
||||
new EmailLinkAction(
|
||||
$request,
|
||||
__('submission.event.viewEmail'),
|
||||
[
|
||||
'submissionId' => $logEntry->getAssocId(),
|
||||
'emailLogEntryId' => $logEntry->getId(),
|
||||
]
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,270 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/eventLog/SubmissionEventLogGridHandler.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 SubmissionEventLogGridHandler
|
||||
*
|
||||
* @ingroup controllers_grid_eventLog
|
||||
*
|
||||
* @brief Grid handler presenting the submission event log grid.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\eventLog;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\facades\Repo;
|
||||
use APP\submission\Submission;
|
||||
use PKP\controllers\grid\DateGridCellProvider;
|
||||
use PKP\controllers\grid\GridColumn;
|
||||
use PKP\controllers\grid\GridHandler;
|
||||
use PKP\core\JSONMessage;
|
||||
use PKP\core\PKPApplication;
|
||||
use PKP\core\PKPRequest;
|
||||
use PKP\core\PKPString;
|
||||
use PKP\db\DAORegistry;
|
||||
use PKP\log\EmailLogEntry;
|
||||
use PKP\log\SubmissionEmailLogDAO;
|
||||
use PKP\log\event\EventLogEntry;
|
||||
use PKP\security\authorization\internal\UserAccessibleWorkflowStageRequiredPolicy;
|
||||
use PKP\security\authorization\SubmissionAccessPolicy;
|
||||
use PKP\security\Role;
|
||||
|
||||
class SubmissionEventLogGridHandler extends GridHandler
|
||||
{
|
||||
/** @var Submission */
|
||||
public $_submission;
|
||||
|
||||
/** @var int The current workflow stage */
|
||||
public $_stageId;
|
||||
|
||||
/** @var bool Is the current user assigned as an author to this submission */
|
||||
public $_isCurrentUserAssignedAuthor;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->addRoleAssignment(
|
||||
[Role::ROLE_ID_MANAGER, Role::ROLE_ID_SITE_ADMIN, Role::ROLE_ID_SUB_EDITOR],
|
||||
['fetchGrid', 'fetchRow', 'viewEmail']
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Getters/Setters
|
||||
//
|
||||
/**
|
||||
* Get the submission associated with this grid.
|
||||
*
|
||||
* @return Submission
|
||||
*/
|
||||
public function getSubmission()
|
||||
{
|
||||
return $this->_submission;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Submission
|
||||
*
|
||||
* @param Submission $submission
|
||||
*/
|
||||
public function setSubmission($submission)
|
||||
{
|
||||
$this->_submission = $submission;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Overridden methods from PKPHandler
|
||||
//
|
||||
/**
|
||||
* @see PKPHandler::authorize()
|
||||
*
|
||||
* @param PKPRequest $request
|
||||
* @param array $args
|
||||
* @param array $roleAssignments
|
||||
*/
|
||||
public function authorize($request, &$args, $roleAssignments)
|
||||
{
|
||||
$this->addPolicy(new SubmissionAccessPolicy($request, $args, $roleAssignments));
|
||||
|
||||
$this->addPolicy(new UserAccessibleWorkflowStageRequiredPolicy($request, PKPApplication::WORKFLOW_TYPE_EDITORIAL));
|
||||
|
||||
$success = parent::authorize($request, $args, $roleAssignments);
|
||||
|
||||
// Prevent authors from accessing review details, even if they are also
|
||||
// assigned as an editor, sub-editor or assistant.
|
||||
$userAssignedRoles = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_ACCESSIBLE_WORKFLOW_STAGES);
|
||||
$this->_isCurrentUserAssignedAuthor = false;
|
||||
foreach ($userAssignedRoles as $stageId => $roles) {
|
||||
if (in_array(Role::ROLE_ID_AUTHOR, $roles)) {
|
||||
$this->_isCurrentUserAssignedAuthor = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $success;
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::initialize()
|
||||
*
|
||||
* @param null|mixed $args
|
||||
*/
|
||||
public function initialize($request, $args = null)
|
||||
{
|
||||
parent::initialize($request, $args);
|
||||
|
||||
// Retrieve the authorized monograph.
|
||||
$submission = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_SUBMISSION);
|
||||
$this->setSubmission($submission);
|
||||
|
||||
$this->_stageId = (int) ($args['stageId'] ?? null);
|
||||
|
||||
// Columns
|
||||
$cellProvider = new EventLogGridCellProvider($this->_isCurrentUserAssignedAuthor);
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'date',
|
||||
'common.date',
|
||||
null,
|
||||
null,
|
||||
new DateGridCellProvider(
|
||||
$cellProvider,
|
||||
Application::get()->getRequest()->getContext()->getLocalizedDateFormatShort()
|
||||
)
|
||||
)
|
||||
);
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'user',
|
||||
'common.user',
|
||||
null,
|
||||
null,
|
||||
$cellProvider
|
||||
)
|
||||
);
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'event',
|
||||
'common.event',
|
||||
null,
|
||||
null,
|
||||
$cellProvider,
|
||||
['width' => 60]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Overridden methods from GridHandler
|
||||
//
|
||||
/**
|
||||
* @see GridHandler::getRowInstance()
|
||||
*
|
||||
* @return EventLogGridRow
|
||||
*/
|
||||
protected function getRowInstance()
|
||||
{
|
||||
return new EventLogGridRow($this->getSubmission(), $this->_isCurrentUserAssignedAuthor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the arguments that will identify the data in the grid
|
||||
* In this case, the monograph.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getRequestArgs()
|
||||
{
|
||||
$submission = $this->getSubmission();
|
||||
|
||||
return [
|
||||
'submissionId' => $submission->getId(),
|
||||
'stageId' => $this->_stageId,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::loadData
|
||||
*
|
||||
* @param null|mixed $filter
|
||||
*/
|
||||
protected function loadData($request, $filter = null)
|
||||
{
|
||||
$submissionEmailLogDao = DAORegistry::getDAO('SubmissionEmailLogDAO'); /** @var SubmissionEmailLogDAO $submissionEmailLogDao */
|
||||
|
||||
$submission = $this->getSubmission();
|
||||
|
||||
$eventLogEntries = Repo::eventLog()->getCollector()
|
||||
->filterByAssoc(PKPApplication::ASSOC_TYPE_SUBMISSION, [$submission->getId()])
|
||||
->getMany();
|
||||
$emailLogEntries = $submissionEmailLogDao->getBySubmissionId($submission->getId());
|
||||
|
||||
$entries = array_merge($eventLogEntries->toArray(), $emailLogEntries->toArray());
|
||||
|
||||
// Sort the merged data by date, most recent first
|
||||
usort($entries, function ($a, $b) {
|
||||
$aDate = $a instanceof EventLogEntry ? $a->getDateLogged() : $a->getDateSent();
|
||||
$bDate = $b instanceof EventLogEntry ? $b->getDateLogged() : $b->getDateSent();
|
||||
|
||||
if ($aDate == $bDate) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return $aDate < $bDate ? 1 : -1;
|
||||
});
|
||||
|
||||
return $entries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the contents of the email
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function viewEmail($args, $request)
|
||||
{
|
||||
$submissionEmailLogDao = DAORegistry::getDAO('SubmissionEmailLogDAO'); /** @var SubmissionEmailLogDAO $submissionEmailLogDao */
|
||||
$emailLogEntry = $submissionEmailLogDao->getById((int) $args['emailLogEntryId']);
|
||||
return new JSONMessage(true, $this->_formatEmail($emailLogEntry));
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the contents of the email
|
||||
*
|
||||
*
|
||||
* @return string Formatted email
|
||||
*/
|
||||
public function _formatEmail(EmailLogEntry $emailLogEntry)
|
||||
{
|
||||
$text = [];
|
||||
$text[] = __('email.from') . ': ' . htmlspecialchars($emailLogEntry->getFrom());
|
||||
$text[] = __('email.to') . ': ' . htmlspecialchars($emailLogEntry->getRecipients());
|
||||
if ($emailLogEntry->getCcs()) {
|
||||
$text[] = __('email.cc') . ': ' . htmlspecialchars($emailLogEntry->getCcs());
|
||||
}
|
||||
if ($emailLogEntry->getBccs()) {
|
||||
$text[] = __('email.bcc') . ': ' . htmlspecialchars($emailLogEntry->getBccs());
|
||||
}
|
||||
$text[] = __('email.subject') . ': ' . htmlspecialchars($emailLogEntry->getSubject());
|
||||
|
||||
return
|
||||
'<div class="pkp_workflow_email_log_view">'
|
||||
. nl2br(join(PHP_EOL, $text)) . '<br><br>'
|
||||
. PKPString::stripUnsafeHtml($emailLogEntry->getBody())
|
||||
. '</div>';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/eventLog/SubmissionFileEventLogGridHandler.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 SubmissionFileEventLogGridHandler
|
||||
*
|
||||
* @ingroup controllers_grid_eventLog
|
||||
*
|
||||
* @brief Grid handler presenting the submission file event log grid.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\eventLog;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\facades\Repo;
|
||||
use PKP\core\PKPApplication;
|
||||
use PKP\core\PKPRequest;
|
||||
use PKP\security\authorization\SubmissionFileAccessPolicy;
|
||||
use PKP\security\Role;
|
||||
use PKP\submissionFile\SubmissionFile;
|
||||
|
||||
class SubmissionFileEventLogGridHandler extends SubmissionEventLogGridHandler
|
||||
{
|
||||
/** @var SubmissionFile SubmissionFile */
|
||||
public $_submissionFile;
|
||||
|
||||
//
|
||||
// Getters/Setters
|
||||
//
|
||||
/**
|
||||
* Get the submission file associated with this grid.
|
||||
*
|
||||
* @return SubmissionFile
|
||||
*/
|
||||
public function getSubmissionFile()
|
||||
{
|
||||
return $this->_submissionFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the submission file
|
||||
*
|
||||
* @param SubmissionFile $submissionFile
|
||||
*/
|
||||
public function setSubmissionFile($submissionFile)
|
||||
{
|
||||
$this->_submissionFile = $submissionFile;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Overridden methods from PKPHandler
|
||||
//
|
||||
/**
|
||||
* @see PKPHandler::authorize()
|
||||
*
|
||||
* @param PKPRequest $request
|
||||
* @param array $args
|
||||
* @param array $roleAssignments
|
||||
*/
|
||||
public function authorize($request, &$args, $roleAssignments)
|
||||
{
|
||||
$this->addPolicy(new SubmissionFileAccessPolicy($request, $args, $roleAssignments, SubmissionFileAccessPolicy::SUBMISSION_FILE_ACCESS_READ, (int) $args['submissionFileId']));
|
||||
return parent::authorize($request, $args, $roleAssignments);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the grid
|
||||
*
|
||||
* @see SubmissionEventLogGridHandler::initialize
|
||||
*
|
||||
* @param null|mixed $args
|
||||
*/
|
||||
public function initialize($request, $args = null)
|
||||
{
|
||||
parent::initialize($request, $args);
|
||||
|
||||
// Retrieve the authorized monograph.
|
||||
$submission = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_SUBMISSION);
|
||||
$submissionFile = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_SUBMISSION_FILE);
|
||||
$this->setSubmissionFile($submissionFile);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Overridden methods from GridHandler
|
||||
//
|
||||
/**
|
||||
* Get the arguments that will identify the data in the grid
|
||||
* In this case, the monograph.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getRequestArgs()
|
||||
{
|
||||
$submissionFile = $this->getSubmissionFile();
|
||||
|
||||
return [
|
||||
'submissionId' => $submissionFile->getData('submissionId'),
|
||||
'submissionFileId' => $submissionFile->getId(),
|
||||
'stageId' => $this->_stageId,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::loadData
|
||||
*
|
||||
* @param null|mixed $filter
|
||||
*/
|
||||
protected function loadData($request, $filter = null)
|
||||
{
|
||||
return Repo::eventLog()->getCollector()
|
||||
->filterByAssoc(PKPApplication::ASSOC_TYPE_SUBMISSION_FILE, [$this->getSubmissionFile()->getId()])
|
||||
->getMany()
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::getFilterForm()
|
||||
*
|
||||
* @return string Filter template.
|
||||
*/
|
||||
protected function getFilterForm()
|
||||
{
|
||||
// If the user only has an author role, do not permit access
|
||||
// to earlier stages.
|
||||
$userRoles = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_USER_ROLES);
|
||||
if (array_intersect([Role::ROLE_ID_MANAGER, Role::ROLE_ID_SITE_ADMIN, Role::ROLE_ID_SUB_EDITOR, Role::ROLE_ID_ASSISTANT], $userRoles)) {
|
||||
return 'controllers/grid/eventLog/eventLogGridFilter.tpl';
|
||||
}
|
||||
return parent::getFilterForm();
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::getFilterSelectionData()
|
||||
*/
|
||||
public function getFilterSelectionData($request)
|
||||
{
|
||||
return ['allEvents' => $request->getUserVar('allEvents') ? true : false];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/eventLog/linkAction/EmailLinkAction.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 EmailLinkAction
|
||||
*
|
||||
* @ingroup controllers_api_submission
|
||||
*
|
||||
* @brief An action to open up a modal to view an email sent to a user.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\eventLog\linkAction;
|
||||
|
||||
use APP\core\Request;
|
||||
use PKP\linkAction\LinkAction;
|
||||
use PKP\linkAction\request\AjaxModal;
|
||||
|
||||
class EmailLinkAction extends LinkAction
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param Request $request
|
||||
* @param string $modalTitle Title of the modal
|
||||
* @param array $actionArgs The action arguments.
|
||||
*/
|
||||
public function __construct($request, $modalTitle, $actionArgs)
|
||||
{
|
||||
$router = $request->getRouter();
|
||||
|
||||
// Instantiate the view email modal.
|
||||
$ajaxModal = new AjaxModal(
|
||||
$router->url($request, null, null, 'viewEmail', null, $actionArgs),
|
||||
$modalTitle,
|
||||
'modal_email'
|
||||
);
|
||||
|
||||
// Configure the link action.
|
||||
parent::__construct(
|
||||
'viewEmail',
|
||||
$ajaxModal,
|
||||
$modalTitle,
|
||||
'notify'
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/files/FileDateGridColumn.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.
|
||||
* Borrowed from FileDateGridColumn.php
|
||||
*
|
||||
* @class FileDateGridColumn
|
||||
*
|
||||
* @ingroup controllers_grid_files
|
||||
*
|
||||
* @brief Implements a file name column.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\files;
|
||||
|
||||
use APP\core\Application;
|
||||
use PKP\controllers\grid\ColumnBasedGridCellProvider;
|
||||
use PKP\controllers\grid\GridColumn;
|
||||
use PKP\core\PKPString;
|
||||
|
||||
class FileDateGridColumn extends GridColumn
|
||||
{
|
||||
/** @var ?int */
|
||||
public $_stageId;
|
||||
|
||||
/** @var bool */
|
||||
public $_includeNotes;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param bool $includeNotes
|
||||
* without the history tab.
|
||||
*/
|
||||
public function __construct($includeNotes = true)
|
||||
{
|
||||
$this->_includeNotes = $includeNotes;
|
||||
|
||||
$cellProvider = new ColumnBasedGridCellProvider();
|
||||
|
||||
parent::__construct(
|
||||
'date',
|
||||
'common.date',
|
||||
null,
|
||||
null,
|
||||
$cellProvider,
|
||||
['width' => 10, 'alignment' => GridColumn::COLUMN_ALIGNMENT_LEFT, 'anyhtml' => true]
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Public methods
|
||||
//
|
||||
/**
|
||||
* Method expected by ColumnBasedGridCellProvider
|
||||
* to render a cell in this column.
|
||||
*
|
||||
* @copydoc ColumnBasedGridCellProvider::getTemplateVarsFromRowColumn()
|
||||
*/
|
||||
public function getTemplateVarsFromRow($row)
|
||||
{
|
||||
$submissionFileData = $row->getData();
|
||||
$submissionFile = $submissionFileData['submissionFile'];
|
||||
assert($submissionFile instanceof \PKP\submissionFile\SubmissionFile);
|
||||
$mtimestamp = strtotime($submissionFile->getData('updatedAt'));
|
||||
$dateFormatLong = PKPString::convertStrftimeFormat(Application::get()->getRequest()->getContext()->getLocalizedDateFormatLong());
|
||||
$date = date($dateFormatLong, $mtimestamp);
|
||||
// File age
|
||||
$age = (int)floor((date('U') - $mtimestamp) / 86400);
|
||||
switch (true) {
|
||||
case $age <= 7:
|
||||
$cls = ' pkp_helpers_text_warn';
|
||||
break;
|
||||
case $age <= 28:
|
||||
$cls = ' pkp_helpers_text_primary';
|
||||
break;
|
||||
default:
|
||||
$cls = '';
|
||||
break;
|
||||
}
|
||||
return ['label' => sprintf(
|
||||
"<span class='label%s'>%s</span>",
|
||||
$cls,
|
||||
htmlspecialchars($date)
|
||||
)];
|
||||
}
|
||||
|
||||
//
|
||||
// Private methods
|
||||
//
|
||||
/**
|
||||
* Determine whether or not submission note status should be included.
|
||||
*/
|
||||
public function _getIncludeNotes()
|
||||
{
|
||||
return $this->_includeNotes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get stage id, if any.
|
||||
*
|
||||
* @return mixed int or null
|
||||
*/
|
||||
public function _getStageId()
|
||||
{
|
||||
return $this->_stageId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/files/FileNameGridColumn.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 FileNameGridColumn
|
||||
*
|
||||
* @ingroup controllers_grid_files
|
||||
*
|
||||
* @brief Implements a file name column.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\files;
|
||||
|
||||
use PKP\controllers\api\file\linkAction\DownloadFileLinkAction;
|
||||
use PKP\controllers\grid\ColumnBasedGridCellProvider;
|
||||
use PKP\controllers\grid\GridColumn;
|
||||
use PKP\controllers\grid\GridHandler;
|
||||
use PKP\submissionFile\SubmissionFile;
|
||||
|
||||
class FileNameGridColumn extends GridColumn
|
||||
{
|
||||
/** @var bool */
|
||||
public $_includeNotes;
|
||||
|
||||
/** @var int */
|
||||
public $_stageId;
|
||||
|
||||
/** @var bool */
|
||||
public $_removeHistoryTab;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param bool $includeNotes
|
||||
* @param int $stageId (optional)
|
||||
* @param bool $removeHistoryTab (optional) Open the information center
|
||||
* without the history tab.
|
||||
*/
|
||||
public function __construct($includeNotes = true, $stageId = null, $removeHistoryTab = false)
|
||||
{
|
||||
$this->_includeNotes = $includeNotes;
|
||||
$this->_stageId = $stageId;
|
||||
$this->_removeHistoryTab = $removeHistoryTab;
|
||||
|
||||
$cellProvider = new ColumnBasedGridCellProvider();
|
||||
|
||||
parent::__construct(
|
||||
'name',
|
||||
'common.name',
|
||||
null,
|
||||
null,
|
||||
$cellProvider,
|
||||
['width' => 70, 'alignment' => GridColumn::COLUMN_ALIGNMENT_LEFT, 'anyhtml' => true]
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Public methods
|
||||
//
|
||||
/**
|
||||
* Method expected by ColumnBasedGridCellProvider
|
||||
* to render a cell in this column.
|
||||
*
|
||||
* @copydoc ColumnBasedGridCellProvider::getTemplateVarsFromRowColumn()
|
||||
*/
|
||||
public function getTemplateVarsFromRow($row)
|
||||
{
|
||||
$submissionFileData = $row->getData();
|
||||
$submissionFile = $submissionFileData['submissionFile'];
|
||||
assert($submissionFile instanceof SubmissionFile);
|
||||
$fileExtension = pathinfo($submissionFile->getData('path'), PATHINFO_EXTENSION);
|
||||
return ['label' => '<span class="file_extension ' . $fileExtension . '">' . $submissionFile->getId() . '</span>'];
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Override methods from GridColumn
|
||||
//
|
||||
/**
|
||||
* @copydoc GridColumn::getCellActions()
|
||||
*/
|
||||
public function getCellActions($request, $row, $position = GridHandler::GRID_ACTION_POSITION_DEFAULT)
|
||||
{
|
||||
$cellActions = parent::getCellActions($request, $row, $position);
|
||||
|
||||
// Retrieve the submission file.
|
||||
$submissionFileData = & $row->getData();
|
||||
assert(isset($submissionFileData['submissionFile']));
|
||||
$submissionFile = $submissionFileData['submissionFile']; /** @var SubmissionFile $submissionFile */
|
||||
|
||||
// Create the cell action to download a file.
|
||||
$cellActions[] = new DownloadFileLinkAction($request, $submissionFile, $this->_getStageId());
|
||||
|
||||
return $cellActions;
|
||||
}
|
||||
|
||||
//
|
||||
// Private methods
|
||||
//
|
||||
/**
|
||||
* Determine whether or not submission note status should be included.
|
||||
*/
|
||||
public function _getIncludeNotes()
|
||||
{
|
||||
return $this->_includeNotes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get stage id, if any.
|
||||
*
|
||||
* @return mixed int or null
|
||||
*/
|
||||
public function _getStageId()
|
||||
{
|
||||
return $this->_stageId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/files/FilesGridDataProvider.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 FilesGridDataProvider
|
||||
*
|
||||
* @ingroup controllers_grid_files
|
||||
*
|
||||
* @brief Basic files grid data provider.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\files;
|
||||
|
||||
use APP\core\Application;
|
||||
use PKP\controllers\grid\GridDataProvider;
|
||||
|
||||
class FilesGridDataProvider extends GridDataProvider
|
||||
{
|
||||
/** @var int */
|
||||
public $_uploaderRoles;
|
||||
|
||||
/** @var bool */
|
||||
public $_viewableOnly = false;
|
||||
|
||||
|
||||
//
|
||||
// Getters and Setters
|
||||
//
|
||||
/**
|
||||
* Set the uploader roles.
|
||||
*
|
||||
* @param array $roleAssignments The grid's
|
||||
* role assignment from which the uploader roles
|
||||
* will be extracted.
|
||||
*/
|
||||
public function setUploaderRoles($roleAssignments)
|
||||
{
|
||||
$this->_uploaderRoles = array_keys($roleAssignments);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the uploader roles.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getUploaderRoles()
|
||||
{
|
||||
assert(is_array($this->_uploaderRoles) && !empty($this->_uploaderRoles));
|
||||
return $this->_uploaderRoles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load only viewable files flag.
|
||||
*
|
||||
* @param bool $viewableOnly
|
||||
*/
|
||||
public function setViewableOnly($viewableOnly)
|
||||
{
|
||||
$this->_viewableOnly = $viewableOnly;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Public helper methods
|
||||
//
|
||||
/**
|
||||
* Configures and returns the action to add a file.
|
||||
*
|
||||
* NB: Must be overridden by subclasses (if implemented).
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return AddFileLinkAction
|
||||
*/
|
||||
public function getAddFileAction($request)
|
||||
{
|
||||
assert(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures and returns the select files action.
|
||||
*
|
||||
* NB: Must be overridden by subclasses (if implemented).
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return SelectFilesLinkAction
|
||||
*/
|
||||
public function getSelectAction($request)
|
||||
{
|
||||
assert(false);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Protected helper methods
|
||||
//
|
||||
/**
|
||||
* Get the authorized submission.
|
||||
*
|
||||
* @return Submission
|
||||
*/
|
||||
protected function getSubmission()
|
||||
{
|
||||
return $this->getAuthorizedContextObject(Application::ASSOC_TYPE_SUBMISSION);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/files/LibraryFileGridCategoryRow.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 LibraryFileGridCategoryRow
|
||||
*
|
||||
* @ingroup controllers_grid_settings_library
|
||||
*
|
||||
* @brief Library file grid category row definition
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\files;
|
||||
|
||||
use APP\file\LibraryFileManager;
|
||||
use PKP\context\Context;
|
||||
use PKP\controllers\grid\GridCategoryRow;
|
||||
|
||||
class LibraryFileGridCategoryRow extends GridCategoryRow
|
||||
{
|
||||
/** @var Context the context for our Library file manager */
|
||||
public $_context;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct($context)
|
||||
{
|
||||
$this->_context = & $context;
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
//
|
||||
// Overridden methods from GridCategoryRow
|
||||
//
|
||||
/**
|
||||
* Category rows only have one cell and one label. This is it.
|
||||
* return string
|
||||
*/
|
||||
public function getCategoryLabel()
|
||||
{
|
||||
$context = $this->getContext();
|
||||
$libraryFileManager = new LibraryFileManager($context->getId());
|
||||
return __($libraryFileManager->getTitleKeyFromType($this->getData()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the context
|
||||
*
|
||||
* @return object context
|
||||
*/
|
||||
public function getContext()
|
||||
{
|
||||
return $this->_context;
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridCategoryRow::initialize()
|
||||
*
|
||||
* @param null|mixed $template
|
||||
*/
|
||||
public function initialize($request, $template = null)
|
||||
{
|
||||
parent::initialize($request, $template);
|
||||
$this->setId($this->getData());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/files/LibraryFileGridCellProvider.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 LibraryFileGridCellProvider
|
||||
*
|
||||
* @ingroup controllers_grid_settings_library
|
||||
*
|
||||
* @brief Subclass for a LibraryFile grid column's cell provider
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\files;
|
||||
|
||||
use PKP\controllers\api\file\linkAction\DownloadLibraryFileLinkAction;
|
||||
use PKP\controllers\grid\GridCellProvider;
|
||||
use PKP\controllers\grid\GridColumn;
|
||||
use PKP\controllers\grid\GridHandler;
|
||||
|
||||
class LibraryFileGridCellProvider extends GridCellProvider
|
||||
{
|
||||
/**
|
||||
* Extracts variables for a given column from a data element
|
||||
* so that they may be assigned to template before rendering.
|
||||
*
|
||||
* @param \PKP\controllers\grid\GridRow $row
|
||||
* @param GridColumn $column
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getTemplateVarsFromRowColumn($row, $column)
|
||||
{
|
||||
$element = & $row->getData();
|
||||
$columnId = $column->getId();
|
||||
assert($element instanceof \PKP\core\DataObject && !empty($columnId));
|
||||
switch ($columnId) {
|
||||
case 'files':
|
||||
// handled by our link action.
|
||||
return ['label' => ''];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cell actions associated with this row/column combination
|
||||
*
|
||||
* @param \PKP\controllers\grid\GridRow $row
|
||||
* @param GridColumn $column
|
||||
*
|
||||
* @return array an array of LinkAction instances
|
||||
*/
|
||||
public function getCellActions($request, $row, $column, $position = GridHandler::GRID_ACTION_POSITION_DEFAULT)
|
||||
{
|
||||
switch ($column->getId()) {
|
||||
case 'files':
|
||||
$element = $row->getData();
|
||||
assert($element instanceof \PKP\context\LibraryFile);
|
||||
// Create the cell action to download a file.
|
||||
return [new DownloadLibraryFileLinkAction($request, $element)];
|
||||
}
|
||||
return parent::getCellActions($request, $row, $column, $position);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,374 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/files/LibraryFileGridHandler.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 LibraryFileGridHandler
|
||||
*
|
||||
* @ingroup controllers_grid_files
|
||||
*
|
||||
* @brief Base class for handling library file grid requests.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\files;
|
||||
|
||||
use APP\file\LibraryFileManager;
|
||||
use PKP\context\Context;
|
||||
use PKP\controllers\grid\CategoryGridHandler;
|
||||
use PKP\controllers\grid\files\form\LibraryFileForm;
|
||||
use PKP\controllers\grid\GridColumn;
|
||||
use PKP\core\JSONMessage;
|
||||
use PKP\core\PKPRequest;
|
||||
use PKP\file\TemporaryFileManager;
|
||||
use PKP\form\Form;
|
||||
use PKP\linkAction\LinkAction;
|
||||
use PKP\linkAction\request\AjaxModal;
|
||||
use PKP\security\Role;
|
||||
|
||||
class LibraryFileGridHandler extends CategoryGridHandler
|
||||
{
|
||||
/** @var Context The context for this grid */
|
||||
public $_context;
|
||||
|
||||
/** @var bool Whether or not the grid is editable */
|
||||
public $_canEdit;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct($dataProvider)
|
||||
{
|
||||
parent::__construct($dataProvider);
|
||||
$this->addRoleAssignment(
|
||||
[Role::ROLE_ID_MANAGER, Role::ROLE_ID_SITE_ADMIN, Role::ROLE_ID_SUB_EDITOR, Role::ROLE_ID_ASSISTANT, Role::ROLE_ID_AUTHOR],
|
||||
[
|
||||
'fetchGrid', 'fetchCategory', 'fetchRow', // Parent grid-level actions
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Getters/Setters
|
||||
//
|
||||
/**
|
||||
* Get the context
|
||||
*
|
||||
* @return object context
|
||||
*/
|
||||
public function getContext()
|
||||
{
|
||||
return $this->_context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can the user edit/add files in this grid?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function canEdit()
|
||||
{
|
||||
return $this->_canEdit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether or not the user can edit or add files.
|
||||
*
|
||||
* @param bool $canEdit
|
||||
*/
|
||||
public function setCanEdit($canEdit)
|
||||
{
|
||||
$this->_canEdit = $canEdit;
|
||||
}
|
||||
|
||||
//
|
||||
// Overridden template methods
|
||||
//
|
||||
|
||||
/**
|
||||
* Configure the grid
|
||||
*
|
||||
* @see CategoryGridHandler::initialize
|
||||
*
|
||||
* @param null|mixed $args
|
||||
*/
|
||||
public function initialize($request, $args = null)
|
||||
{
|
||||
parent::initialize($request, $args);
|
||||
|
||||
$router = $request->getRouter();
|
||||
$this->_context = $router->getContext($request);
|
||||
|
||||
// Set name
|
||||
$this->setTitle('manager.publication.library');
|
||||
|
||||
// Columns
|
||||
// Basic grid row configuration
|
||||
$this->addColumn($this->getFileNameColumn());
|
||||
|
||||
$router = $request->getRouter();
|
||||
|
||||
// Add grid-level actions
|
||||
if ($this->canEdit()) {
|
||||
$this->addAction(
|
||||
new LinkAction(
|
||||
'addFile',
|
||||
new AjaxModal(
|
||||
$router->url($request, null, null, 'addFile', null, $this->getActionArgs()),
|
||||
__('grid.action.addFile'),
|
||||
'modal_add_file'
|
||||
),
|
||||
__('grid.action.addFile'),
|
||||
'add'
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Implement template methods from CategoryGridHandler
|
||||
//
|
||||
/**
|
||||
* @copydoc CategoryGridHandler::getCategoryRowInstance()
|
||||
*/
|
||||
protected function getCategoryRowInstance()
|
||||
{
|
||||
return new LibraryFileGridCategoryRow($this->getContext());
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::loadData()
|
||||
*/
|
||||
protected function loadData($request, $filter)
|
||||
{
|
||||
$context = $this->getContext();
|
||||
$libraryFileManager = new LibraryFileManager($context->getId());
|
||||
$fileTypeKeys = $libraryFileManager->getTypeSuffixMap();
|
||||
foreach (array_keys($fileTypeKeys) as $key) {
|
||||
$data[$key] = $key;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
//
|
||||
// Overridden methods from GridHandler
|
||||
//
|
||||
/**
|
||||
* Get the row handler - override the default row handler
|
||||
*
|
||||
* @return LibraryFileGridRow
|
||||
*/
|
||||
protected function getRowInstance()
|
||||
{
|
||||
return new LibraryFileGridRow($this->canEdit());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an instance of the cell provider for this grid.
|
||||
*
|
||||
* @return GridColumn
|
||||
*/
|
||||
public function getFileNameColumn()
|
||||
{
|
||||
return new GridColumn(
|
||||
'files',
|
||||
'grid.libraryFiles.column.files',
|
||||
null,
|
||||
null,
|
||||
new LibraryFileGridCellProvider()
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// Public File Grid Actions
|
||||
//
|
||||
/**
|
||||
* An action to add a new file
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function addFile($args, $request)
|
||||
{
|
||||
$this->initialize($request);
|
||||
$router = $request->getRouter();
|
||||
$context = $request->getContext();
|
||||
|
||||
$fileForm = $this->_getNewFileForm($context);
|
||||
$fileForm->initData();
|
||||
|
||||
return new JSONMessage(true, $fileForm->fetch($request));
|
||||
}
|
||||
|
||||
/**
|
||||
* Save a new library file.
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function saveFile($args, $request)
|
||||
{
|
||||
$router = $request->getRouter();
|
||||
$context = $request->getContext();
|
||||
|
||||
$fileForm = $this->_getNewFileForm($context);
|
||||
$fileForm->readInputData();
|
||||
|
||||
if ($fileForm->validate()) {
|
||||
$fileId = $fileForm->execute();
|
||||
|
||||
// Let the calling grid reload itself
|
||||
return \PKP\db\DAO::getDataChangedEvent();
|
||||
}
|
||||
|
||||
return new JSONMessage(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* An action to add a new file
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function editFile($args, $request)
|
||||
{
|
||||
$this->initialize($request);
|
||||
assert(isset($args['fileId']));
|
||||
$fileId = (int) $args['fileId'];
|
||||
|
||||
$router = $request->getRouter();
|
||||
$context = $request->getContext();
|
||||
|
||||
$fileForm = $this->_getEditFileForm($context, $fileId);
|
||||
$fileForm->initData();
|
||||
|
||||
return new JSONMessage(true, $fileForm->fetch($request));
|
||||
}
|
||||
|
||||
/**
|
||||
* Save changes to an existing library file.
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function updateFile($args, $request)
|
||||
{
|
||||
assert(isset($args['fileId']));
|
||||
$fileId = (int) $args['fileId'];
|
||||
|
||||
$router = $request->getRouter();
|
||||
$context = $request->getContext();
|
||||
|
||||
$fileForm = $this->_getEditFileForm($context, $fileId);
|
||||
$fileForm->readInputData();
|
||||
|
||||
if ($fileForm->validate()) {
|
||||
$fileForm->execute();
|
||||
|
||||
// Let the calling grid reload itself
|
||||
return \PKP\db\DAO::getDataChangedEvent();
|
||||
}
|
||||
|
||||
return new JSONMessage(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a file
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function deleteFile($args, $request)
|
||||
{
|
||||
$fileId = $args['fileId'] ?? null;
|
||||
$router = $request->getRouter();
|
||||
$context = $router->getContext($request);
|
||||
|
||||
if ($request->checkCSRF() && $fileId) {
|
||||
$libraryFileManager = new LibraryFileManager($context->getId());
|
||||
$libraryFileManager->deleteById($fileId);
|
||||
|
||||
return \PKP\db\DAO::getDataChangedEvent();
|
||||
}
|
||||
|
||||
return new JSONMessage(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload a new library file.
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function uploadFile($args, $request)
|
||||
{
|
||||
$router = $request->getRouter();
|
||||
$context = $request->getContext();
|
||||
$user = $request->getUser();
|
||||
|
||||
$temporaryFileManager = new TemporaryFileManager();
|
||||
$temporaryFile = $temporaryFileManager->handleUpload('uploadedFile', $user->getId());
|
||||
if ($temporaryFile) {
|
||||
$json = new JSONMessage(true);
|
||||
$json->setAdditionalAttributes([
|
||||
'temporaryFileId' => $temporaryFile->getId()
|
||||
]);
|
||||
return $json;
|
||||
} else {
|
||||
return new JSONMessage(false, __('common.uploadFailed'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a specific instance of the new form for this grid.
|
||||
* Must be implemented by subclasses.
|
||||
*
|
||||
* @param Context $context
|
||||
*
|
||||
* @return Form
|
||||
*/
|
||||
public function _getNewFileForm($context)
|
||||
{
|
||||
assert(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a specific instance of the edit form for this grid.
|
||||
* Must be implemented by subclasses.
|
||||
*
|
||||
* @param Context $context
|
||||
* @param int $fileId
|
||||
*
|
||||
* @return LibraryFileForm
|
||||
*/
|
||||
public function _getEditFileForm($context, $fileId)
|
||||
{
|
||||
assert(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the arguments for the 'add file' action.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getActionArgs()
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/files/LibraryFileGridRow.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 LibraryFileGridRow
|
||||
*
|
||||
* @ingroup controllers_grid_files
|
||||
*
|
||||
* @brief Handle library file grid row requests.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\files;
|
||||
|
||||
use APP\submission\Submission;
|
||||
use PKP\controllers\grid\GridRow;
|
||||
use PKP\linkAction\LinkAction;
|
||||
use PKP\linkAction\request\AjaxModal;
|
||||
use PKP\linkAction\request\RemoteActionConfirmationModal;
|
||||
|
||||
class LibraryFileGridRow extends GridRow
|
||||
{
|
||||
/** @var int LIBRARY_FILE_TYPE_... */
|
||||
public $_fileType;
|
||||
|
||||
/** @var bool is the grid row read only */
|
||||
public $_canEdit;
|
||||
|
||||
/** @var Submission the submission associated with submission library files */
|
||||
public $_submission;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param null|mixed $submission
|
||||
*/
|
||||
public function __construct($canEdit = false, $submission = null)
|
||||
{
|
||||
$this->_canEdit = $canEdit;
|
||||
$this->_submission = $submission;
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
//
|
||||
// Getters / setters
|
||||
//
|
||||
/**
|
||||
* Get the file type for this row
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFileType()
|
||||
{
|
||||
return $this->_fileType;
|
||||
}
|
||||
|
||||
public function setFileType($fileType)
|
||||
{
|
||||
$this->_fileType = $fileType;
|
||||
}
|
||||
|
||||
//
|
||||
// Overridden template methods
|
||||
//
|
||||
/**
|
||||
* @copydoc GridRow::initialize()
|
||||
*
|
||||
* @param null|mixed $template
|
||||
*/
|
||||
public function initialize($request, $template = null)
|
||||
{
|
||||
parent::initialize($request, $template);
|
||||
|
||||
$this->setFileType($request->getUserVar('fileType'));
|
||||
|
||||
// Is this a new row or an existing row?
|
||||
$fileId = $this->getId();
|
||||
|
||||
if (!empty($fileId) && $this->_canEdit) {
|
||||
// Actions
|
||||
$router = $request->getRouter();
|
||||
$actionArgs = [
|
||||
'fileId' => $fileId,
|
||||
];
|
||||
|
||||
if ($this->_submission) {
|
||||
$actionArgs['submissionId'] = $this->_submission->getId();
|
||||
}
|
||||
|
||||
$this->addAction(
|
||||
new LinkAction(
|
||||
'editFile',
|
||||
new AjaxModal(
|
||||
$router->url($request, null, null, 'editFile', null, $actionArgs),
|
||||
__('grid.action.edit'),
|
||||
'modal_edit'
|
||||
),
|
||||
__('grid.action.edit'),
|
||||
'edit'
|
||||
)
|
||||
);
|
||||
$this->addAction(
|
||||
new LinkAction(
|
||||
'deleteFile',
|
||||
new RemoteActionConfirmationModal(
|
||||
$request->getSession(),
|
||||
__('common.confirmDelete'),
|
||||
__('common.delete'),
|
||||
$router->url($request, null, null, 'deleteFile', null, $actionArgs),
|
||||
'modal_delete'
|
||||
),
|
||||
__('grid.action.delete'),
|
||||
'delete'
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/files/SelectableLibraryFileGridHandler.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 SelectableLibraryFileGridHandler
|
||||
*
|
||||
* @ingroup controllers_grid_files
|
||||
*
|
||||
* @brief Handle selectable library file list category grid requests.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\files;
|
||||
|
||||
use PKP\controllers\grid\feature\selectableItems\SelectableItemsFeature;
|
||||
use PKP\controllers\grid\settings\library\LibraryFileAdminGridDataProvider;
|
||||
|
||||
class SelectableLibraryFileGridHandler extends LibraryFileGridHandler
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(new LibraryFileAdminGridDataProvider(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::initFeatures()
|
||||
*/
|
||||
public function initFeatures($request, $args)
|
||||
{
|
||||
return [new SelectableItemsFeature()];
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::isDataElementInCategorySelected()
|
||||
*/
|
||||
public function isDataElementInCategorySelected($categoryDataId, &$gridDataElement)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the selection name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSelectName()
|
||||
{
|
||||
return 'selectedLibraryFiles';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,296 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/files/SelectableSubmissionFileListCategoryGridHandler.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 SelectableSubmissionFileListCategoryGridHandler
|
||||
*
|
||||
* @ingroup controllers_grid_files
|
||||
*
|
||||
* @brief Handle selectable submission file list category grid requests.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\files;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\core\Request;
|
||||
use APP\submission\Submission;
|
||||
use PKP\controllers\grid\CategoryGridHandler;
|
||||
use PKP\controllers\grid\feature\selectableItems\SelectableItemsFeature;
|
||||
use PKP\controllers\grid\files\fileList\FileGenreGridColumn;
|
||||
use PKP\controllers\grid\GridDataProvider;
|
||||
use PKP\controllers\grid\GridHandler;
|
||||
|
||||
class SelectableSubmissionFileListCategoryGridHandler extends CategoryGridHandler
|
||||
{
|
||||
/** @var FilesGridCapabilities */
|
||||
public $_capabilities;
|
||||
|
||||
/** @var ?int */
|
||||
public $_stageId;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param GridDataProvider $dataProvider
|
||||
* @param ?int $stageId One of the WORKFLOW_STAGE_ID_* constants.
|
||||
* @param int $capabilities A bit map with zero or more
|
||||
* FILE_GRID_* capabilities set.
|
||||
*/
|
||||
public function __construct($dataProvider, $stageId, $capabilities = 0)
|
||||
{
|
||||
// the StageId can be set later if necessary.
|
||||
if ($stageId) {
|
||||
$this->_stageId = (int)$stageId;
|
||||
}
|
||||
|
||||
$this->_capabilities = new FilesGridCapabilities($capabilities);
|
||||
|
||||
parent::__construct($dataProvider);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Getters and Setters
|
||||
//
|
||||
/**
|
||||
* Get grid capabilities object.
|
||||
*
|
||||
* @return FilesGridCapabilities
|
||||
*/
|
||||
public function getCapabilities()
|
||||
{
|
||||
return $this->_capabilities;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the workflow stage id.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getStageId()
|
||||
{
|
||||
return $this->_stageId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the authorized submission.
|
||||
*
|
||||
* @return Submission
|
||||
*/
|
||||
public function getSubmission()
|
||||
{
|
||||
// We assume proper authentication by the data provider.
|
||||
$submission = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_SUBMISSION);
|
||||
assert($submission instanceof Submission);
|
||||
return $submission;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Overridden methods from GridHandler
|
||||
//
|
||||
/**
|
||||
* @copydoc GridHandler::loadData()
|
||||
*/
|
||||
protected function loadData($request, $filter)
|
||||
{
|
||||
// Let parent class get data from data provider.
|
||||
$workflowStages = parent::loadData($request, $filter);
|
||||
|
||||
// Filter the data.
|
||||
if ($filter['allStages']) {
|
||||
return array_combine($workflowStages, $workflowStages);
|
||||
} else {
|
||||
return [$this->getStageId() => $this->getStageId()];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::getFilterForm()
|
||||
*/
|
||||
protected function getFilterForm()
|
||||
{
|
||||
return 'controllers/grid/files/selectableSubmissionFileListCategoryGridFilter.tpl';
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::isFilterFormCollapsible()
|
||||
*/
|
||||
protected function isFilterFormCollapsible()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::getFilterSelectionData()
|
||||
*/
|
||||
public function getFilterSelectionData($request)
|
||||
{
|
||||
return ['allStages' => $request->getUserVar('allStages') ? true : false];
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Overridden methods from CategoryGridHandler
|
||||
//
|
||||
/**
|
||||
* @copydoc CategoryGridHandler::getCategoryRowInstance()
|
||||
*/
|
||||
protected function getCategoryRowInstance()
|
||||
{
|
||||
return new SelectableSubmissionFileListCategoryGridRow();
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Implement template methods from PKPHandler
|
||||
//
|
||||
/**
|
||||
* @copydoc PKPHandler::authorize()
|
||||
*/
|
||||
public function authorize($request, &$args, $roleAssignments)
|
||||
{
|
||||
// Set the stage id from the request parameter if not set previously.
|
||||
if (!$this->getStageId()) {
|
||||
$stageId = (int) $request->getUserVar('stageId');
|
||||
// This will be validated with the authorization policy added by
|
||||
// the grid data provider.
|
||||
$this->_stageId = $stageId;
|
||||
}
|
||||
|
||||
$dataProvider = $this->getDataProvider();
|
||||
$dataProvider->setStageId($this->getStageId());
|
||||
|
||||
return parent::authorize($request, $args, $roleAssignments);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc CategoryGridHandler::initialize()
|
||||
*
|
||||
* @param null|mixed $args
|
||||
*/
|
||||
public function initialize($request, $args = null)
|
||||
{
|
||||
parent::initialize($request, $args);
|
||||
|
||||
// Add grid actions
|
||||
$capabilities = $this->getCapabilities();
|
||||
$dataProvider = $this->getDataProvider();
|
||||
|
||||
if ($capabilities->canManage()) {
|
||||
$this->addAction($dataProvider->getSelectAction($request));
|
||||
}
|
||||
|
||||
if ($capabilities->canAdd()) {
|
||||
assert(isset($dataProvider));
|
||||
$this->addAction($dataProvider->getAddFileAction($request));
|
||||
}
|
||||
|
||||
// Test whether an archive tool is available for the export to work, if so, add 'download all' grid action
|
||||
if ($capabilities->canDownloadAll() && $this->hasGridDataElements($request)) {
|
||||
$submission = $this->getSubmission();
|
||||
$stageId = $this->getStageId();
|
||||
$linkParams = [
|
||||
'nameLocaleKey' => $this->getTitle(),
|
||||
'submissionId' => $submission->getId(),
|
||||
'stageId' => $stageId,
|
||||
];
|
||||
$files = $this->getFilesToDownload($request);
|
||||
|
||||
$this->addAction($capabilities->getDownloadAllAction($request, $files, $linkParams), GridHandler::GRID_ACTION_POSITION_BELOW);
|
||||
}
|
||||
|
||||
// The file name column is common to all file grid types.
|
||||
$this->addColumn(new FileNameGridColumn($capabilities->canViewNotes(), $this->getStageId()));
|
||||
|
||||
// The file list grid layout has an additional file genre column.
|
||||
$this->addColumn(new FileGenreGridColumn());
|
||||
|
||||
// Set the no items row text
|
||||
$this->setEmptyRowText('grid.noFiles');
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::initFeatures()
|
||||
*/
|
||||
public function initFeatures($request, $args)
|
||||
{
|
||||
return [new SelectableItemsFeature()];
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Overridden methods from GridHandler
|
||||
//
|
||||
/**
|
||||
* @copydoc GridHandler::getRowInstance()
|
||||
*/
|
||||
protected function getRowInstance()
|
||||
{
|
||||
return new SubmissionFilesGridRow($this->getCapabilities(), $this->getStageId());
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Protected methods
|
||||
//
|
||||
/**
|
||||
* Get all files of this grid to download.
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getFilesToDownload($request)
|
||||
{
|
||||
$dataProvider = $this->getDataProvider();
|
||||
$workflowStages = $this->getGridDataElements($request);
|
||||
|
||||
// Get the submission files to be downloaded.
|
||||
$submissionFiles = [];
|
||||
foreach ($workflowStages as $stageId) {
|
||||
$submissionFiles = array_merge(
|
||||
$submissionFiles,
|
||||
$this->getGridCategoryDataElements($request, $stageId)
|
||||
);
|
||||
}
|
||||
return $submissionFiles;
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::isDataElementInCategorySelected()
|
||||
*/
|
||||
public function isDataElementInCategorySelected($categoryDataId, &$gridDataElement)
|
||||
{
|
||||
$currentStageId = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_WORKFLOW_STAGE);
|
||||
$submissionFile = $gridDataElement['submissionFile'];
|
||||
|
||||
// Check for special cases when the file needs to be unselected.
|
||||
$dataProvider = $this->getDataProvider();
|
||||
if ($dataProvider->getFileStage() != $submissionFile->getFileStage()) {
|
||||
return false;
|
||||
} elseif ($currentStageId == WORKFLOW_STAGE_ID_INTERNAL_REVIEW || $currentStageId == WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
|
||||
if ($currentStageId != $categoryDataId) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Passed the checks above. If viewable then select it.
|
||||
return $submissionFile->getViewable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the selection name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSelectName()
|
||||
{
|
||||
return 'selectedFiles';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
/**
|
||||
* @file controllers/grid/files/SelectableSubmissionFileListCategoryGridRow.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 SelectableSubmissionFileListCategoryGridRow
|
||||
*
|
||||
* @ingroup controllers_grid_files
|
||||
*
|
||||
* @brief Selectable submission file list category grid row definition.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\files;
|
||||
|
||||
use PKP\controllers\grid\GridCategoryRow;
|
||||
use PKP\workflow\WorkflowStageDAO;
|
||||
|
||||
class SelectableSubmissionFileListCategoryGridRow extends GridCategoryRow
|
||||
{
|
||||
//
|
||||
// Overridden methods from GridCategoryRow
|
||||
//
|
||||
/**
|
||||
* @copydoc GridCategoryRow::getCategoryLabel()
|
||||
*/
|
||||
public function getCategoryLabel()
|
||||
{
|
||||
$stageId = $this->getData();
|
||||
$stageTranslationKey = WorkflowStageDAO::getTranslationKeyFromId($stageId);
|
||||
|
||||
return __($stageTranslationKey);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,246 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/files/SubmissionFilesCategoryGridDataProvider.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 SubmissionFilesCategoryGridDataProvider
|
||||
*
|
||||
* @ingroup controllers_grid_files_review
|
||||
*
|
||||
* @brief Provide access to submission files data for category grids.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\files;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\facades\Repo;
|
||||
use PKP\controllers\grid\CategoryGridDataProvider;
|
||||
use PKP\db\DAORegistry;
|
||||
use PKP\note\NoteDAO;
|
||||
use PKP\query\QueryDAO;
|
||||
use PKP\submission\reviewRound\ReviewRoundDAO;
|
||||
use PKP\submissionFile\SubmissionFile;
|
||||
|
||||
class SubmissionFilesCategoryGridDataProvider extends CategoryGridDataProvider
|
||||
{
|
||||
/** @var array */
|
||||
public $_submissionFiles;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param int $fileStage The current file stage that the grid is handling
|
||||
* (others file stages could be shown activating the grid filter, but this
|
||||
* is the file stage that will be used to bring files from other stages, upload
|
||||
* new file, etc).
|
||||
* @param array $dataProviderInitParams Other parameters to initiate the grid
|
||||
* data provider that this category grid data provider will use to implement
|
||||
* common behaviours and data.
|
||||
*/
|
||||
public function __construct($fileStage, $dataProviderInitParams = null)
|
||||
{
|
||||
parent::__construct();
|
||||
$this->setDataProvider($this->initGridDataProvider($fileStage, $dataProviderInitParams));
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Extended method from CategoryGridDataProvider.
|
||||
//
|
||||
/**
|
||||
* @copydoc CategoryGridDataProvider::setDataProvider()
|
||||
*/
|
||||
public function setDataProvider($gridDataProvider)
|
||||
{
|
||||
assert($gridDataProvider instanceof SubmissionFilesGridDataProvider);
|
||||
parent::setDataProvider($gridDataProvider);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Implement template methods from GridDataProvider
|
||||
//
|
||||
/**
|
||||
* @copydoc GridDataProvider::getAuthorizationPolicy()
|
||||
*/
|
||||
public function getAuthorizationPolicy($request, $args, $roleAssignments)
|
||||
{
|
||||
// Get the submission files grid data provider authorization policy.
|
||||
$dataProvider = $this->getDataProvider();
|
||||
return $dataProvider->getAuthorizationPolicy($request, $args, $roleAssignments);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridDataProvider::getRequestArgs()
|
||||
*/
|
||||
public function getRequestArgs()
|
||||
{
|
||||
$dataProvider = $this->getDataProvider();
|
||||
return $dataProvider->getRequestArgs();
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridDataProvider::loadData()
|
||||
*/
|
||||
public function loadData($filter = [])
|
||||
{
|
||||
// Return only the user accessible workflow stages.
|
||||
return array_keys($this->getAuthorizedContextObject(Application::ASSOC_TYPE_ACCESSIBLE_WORKFLOW_STAGES));
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Implement template methods from CategoryGridDataProvider
|
||||
//
|
||||
/**
|
||||
* @copydoc CategoryGridDataProvider::loadCategoryData()
|
||||
*
|
||||
* @param null|mixed $filter
|
||||
* @param null|mixed $reviewRound
|
||||
*/
|
||||
public function loadCategoryData($request, $categoryDataElement, $filter = null, $reviewRound = null)
|
||||
{
|
||||
/** @var SubmissionFilesGridDataProvider */
|
||||
$dataProvider = $this->getDataProvider();
|
||||
$submission = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_SUBMISSION);
|
||||
$stageId = $categoryDataElement;
|
||||
$fileStages = $this->_getFileStagesByStageId($stageId);
|
||||
$stageSubmissionFiles = null;
|
||||
|
||||
// For review stages, get the revisions of the review round that user is currently accessing.
|
||||
if ($stageId == WORKFLOW_STAGE_ID_INTERNAL_REVIEW || $stageId == WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
|
||||
if (is_null($reviewRound) || $reviewRound->getStageId() != $stageId) {
|
||||
$reviewRoundDao = DAORegistry::getDAO('ReviewRoundDAO'); /** @var ReviewRoundDAO $reviewRoundDao */
|
||||
$reviewRound = $reviewRoundDao->getLastReviewRoundBySubmissionId($submission->getId(), $stageId);
|
||||
}
|
||||
if ($reviewRound) {
|
||||
$stageSubmissionFiles = Repo::submissionFile()
|
||||
->getCollector()
|
||||
->filterBySubmissionIds([$submission->getId()])
|
||||
->filterByReviewRoundIds([$reviewRound->getId()])
|
||||
->filterByFileStages($fileStages)
|
||||
->getMany()
|
||||
->toArray();
|
||||
} else {
|
||||
$stageSubmissionFiles = [];
|
||||
}
|
||||
} else {
|
||||
// Filter the passed workflow stage files.
|
||||
if (!$this->_submissionFiles) {
|
||||
$this->_submissionFiles = Repo::submissionFile()
|
||||
->getCollector()
|
||||
->filterBySubmissionIds([$submission->getId()])
|
||||
->getMany()
|
||||
->toArray();
|
||||
}
|
||||
$submissionFiles = $this->_submissionFiles;
|
||||
$stageSubmissionFiles = [];
|
||||
foreach ($submissionFiles as $key => $submissionFile) {
|
||||
if (in_array($submissionFile->getData('fileStage'), $fileStages)) {
|
||||
$stageSubmissionFiles[$key] = $submissionFile;
|
||||
} elseif ($submissionFile->getData('fileStage') == SubmissionFile::SUBMISSION_FILE_QUERY) {
|
||||
// Determine the stage from the query.
|
||||
if ($submissionFile->getData('assocType') != Application::ASSOC_TYPE_NOTE) {
|
||||
break;
|
||||
}
|
||||
$noteDao = DAORegistry::getDAO('NoteDAO'); /** @var NoteDAO $noteDao */
|
||||
$note = $noteDao->getById($submissionFile->getData('assocId'));
|
||||
$queryDao = DAORegistry::getDAO('QueryDAO'); /** @var QueryDAO $queryDao */
|
||||
if ($note && $note->getAssocType() == Application::ASSOC_TYPE_QUERY) {
|
||||
$query = $queryDao->getById($note->getAssocId());
|
||||
}
|
||||
if ($query && $query->getStageId() == $stageId) {
|
||||
$stageSubmissionFiles[$key] = $submissionFile;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $dataProvider->prepareSubmissionFileData($stageSubmissionFiles, false, $filter);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Public methods
|
||||
//
|
||||
/**
|
||||
* @copydoc SubmissionFilesGridDataProvider::getAddFileAction()
|
||||
*/
|
||||
public function getAddFileAction($request)
|
||||
{
|
||||
/** @var SubmissionFilesGridDataProvider */
|
||||
$dataProvider = $this->getDataProvider();
|
||||
return $dataProvider->getAddFileAction($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc SubmissionFilesGridDataProvider::getFileStage()
|
||||
*/
|
||||
public function setStageId($stageId)
|
||||
{
|
||||
/** @var SubmissionFilesGridDataProvider */
|
||||
$dataProvider = $this->getDataProvider();
|
||||
$dataProvider->setStageId($stageId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc SubmissionFilesGridDataProvider::getFileStage()
|
||||
*/
|
||||
public function getFileStage()
|
||||
{
|
||||
/** @var SubmissionFilesGridDataProvider */
|
||||
$dataProvider = $this->getDataProvider();
|
||||
return $dataProvider->getFileStage();
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Protected methods.
|
||||
//
|
||||
/**
|
||||
* Init the grid data provider that this category grid data provider
|
||||
* will use and return it. Override this to initiate another grid data provider.
|
||||
*
|
||||
* @param int $fileStage
|
||||
* @param array $initParams (optional) The parameters to initiate the grid data provider.
|
||||
*
|
||||
* @return SubmissionFilesGridDataProvider
|
||||
*/
|
||||
public function initGridDataProvider($fileStage, $initParams = null)
|
||||
{
|
||||
// By default, this category grid data provider use the
|
||||
// SubmissionFilesGridDataProvider.
|
||||
return new SubmissionFilesGridDataProvider($fileStage);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Private helper methods.
|
||||
//
|
||||
/**
|
||||
* Get the file stage using the passed stage id. This will define
|
||||
* which file stage will be present on each workflow stage category
|
||||
* of the grid.
|
||||
*/
|
||||
public function _getFileStagesByStageId(int $stageId): array
|
||||
{
|
||||
switch ($stageId) {
|
||||
case WORKFLOW_STAGE_ID_SUBMISSION:
|
||||
return [SubmissionFile::SUBMISSION_FILE_SUBMISSION];
|
||||
case WORKFLOW_STAGE_ID_INTERNAL_REVIEW:
|
||||
return [SubmissionFile::SUBMISSION_FILE_INTERNAL_REVIEW_FILE, SubmissionFile::SUBMISSION_FILE_INTERNAL_REVIEW_REVISION];
|
||||
case WORKFLOW_STAGE_ID_EXTERNAL_REVIEW:
|
||||
return [SubmissionFile::SUBMISSION_FILE_REVIEW_FILE, SubmissionFile::SUBMISSION_FILE_REVIEW_REVISION];
|
||||
case WORKFLOW_STAGE_ID_EDITING:
|
||||
return [SubmissionFile::SUBMISSION_FILE_FINAL, SubmissionFile::SUBMISSION_FILE_COPYEDIT];
|
||||
case WORKFLOW_STAGE_ID_PRODUCTION:
|
||||
return [SubmissionFile::SUBMISSION_FILE_PRODUCTION_READY];
|
||||
default:
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,199 @@
|
||||
<?php
|
||||
/**
|
||||
* @file controllers/grid/files/SubmissionFilesGridDataProvider.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 SubmissionFilesGridDataProvider
|
||||
*
|
||||
* @ingroup controllers_grid_files
|
||||
*
|
||||
* @brief Provide access to submission file data for grids.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\files;
|
||||
|
||||
use APP\facades\Repo;
|
||||
use PKP\controllers\api\file\linkAction\AddFileLinkAction;
|
||||
use PKP\facades\Locale;
|
||||
use PKP\security\authorization\WorkflowStageAccessPolicy;
|
||||
|
||||
class SubmissionFilesGridDataProvider extends FilesGridDataProvider
|
||||
{
|
||||
/** @var int */
|
||||
public $_stageId;
|
||||
|
||||
/** @var int */
|
||||
public $_fileStage;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param int $fileStage One of the SubmissionFile::SUBMISSION_FILE_* constants.
|
||||
* @param bool $viewableOnly True iff only viewable files should be included.
|
||||
*/
|
||||
public function __construct($fileStage, $viewableOnly = false)
|
||||
{
|
||||
assert(is_numeric($fileStage) && $fileStage > 0);
|
||||
$this->_fileStage = (int)$fileStage;
|
||||
parent::__construct();
|
||||
|
||||
$this->setViewableOnly($viewableOnly);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Getters and setters.
|
||||
//
|
||||
/**
|
||||
* Set the workflow stage.
|
||||
*
|
||||
* @param int $stageId WORKFLOW_STAGE_ID_...
|
||||
*/
|
||||
public function setStageId($stageId)
|
||||
{
|
||||
$this->_stageId = $stageId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the workflow stage.
|
||||
*
|
||||
* @return int WORKFLOW_STAGE_ID_...
|
||||
*/
|
||||
public function getStageId()
|
||||
{
|
||||
return $this->_stageId;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Implement template methods from GridDataProvider
|
||||
//
|
||||
/**
|
||||
* @copydoc GridDataProvider::getRequestArgs()
|
||||
*/
|
||||
public function getRequestArgs()
|
||||
{
|
||||
$submission = $this->getSubmission();
|
||||
return [
|
||||
'submissionId' => $submission->getId(),
|
||||
'stageId' => $this->getStageId(),
|
||||
'fileStage' => $this->getFileStage(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the file stage.
|
||||
*
|
||||
* @return int SubmissionFile::SUBMISSION_FILE_...
|
||||
*/
|
||||
public function getFileStage()
|
||||
{
|
||||
return $this->_fileStage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridDataProvider::loadData()
|
||||
*/
|
||||
public function loadData($filter = [])
|
||||
{
|
||||
$submissionFiles = Repo::submissionFile()
|
||||
->getCollector()
|
||||
->filterBySubmissionIds([$this->getSubmission()->getId()])
|
||||
->filterByFileStages([$this->getFileStage()])
|
||||
->getMany()
|
||||
->toArray();
|
||||
return $this->prepareSubmissionFileData($submissionFiles, $this->_viewableOnly, $filter);
|
||||
}
|
||||
|
||||
//
|
||||
// Implement template methods from GridDataProvider
|
||||
//
|
||||
/**
|
||||
* @copydoc GridDataProvider::getAuthorizationPolicy()
|
||||
*/
|
||||
public function getAuthorizationPolicy($request, $args, $roleAssignments)
|
||||
{
|
||||
$this->setUploaderRoles($roleAssignments);
|
||||
|
||||
return new WorkflowStageAccessPolicy($request, $args, $roleAssignments, 'submissionId', $this->getStageId());
|
||||
}
|
||||
|
||||
//
|
||||
// Overridden public methods from FilesGridDataProvider
|
||||
//
|
||||
/**
|
||||
* @copydoc FilesGridDataProvider::getAddFileAction()
|
||||
*/
|
||||
public function getAddFileAction($request)
|
||||
{
|
||||
$submission = $this->getSubmission();
|
||||
return new AddFileLinkAction(
|
||||
$request,
|
||||
$submission->getId(),
|
||||
$this->getStageId(),
|
||||
$this->getUploaderRoles(),
|
||||
$this->getFileStage()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Protected functions
|
||||
//
|
||||
/**
|
||||
* Apply the filter to the list of revisions, returning only matching elements.
|
||||
*
|
||||
* @param array $revisions List of potential submission files to include.
|
||||
* @param array $filter Associative array of filter data
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function applyFilter($revisions, $filter)
|
||||
{
|
||||
if (!empty($filter['search'])) {
|
||||
switch ($filter['column']) {
|
||||
case 'name':
|
||||
foreach ($revisions as $key => $submissionFile) {
|
||||
if (!stristr($submissionFile->getData('name', Locale::getLocale()), $filter['search'])) {
|
||||
unset($revisions[$key]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $revisions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rearrange file revisions by file id and return the file
|
||||
* data wrapped into an array so that grid implementations
|
||||
* can add further data.
|
||||
*
|
||||
* @param array $revisions List of SubmissionFiles
|
||||
* @param bool $viewableOnly optional True iff only viewable files should be listed
|
||||
* @param array $filter optional Associative array of filter conditions
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function prepareSubmissionFileData($revisions, $viewableOnly = false, $filter = [])
|
||||
{
|
||||
$revisions = $this->applyFilter($revisions, $filter);
|
||||
|
||||
// Rearrange the files as required by submission file grids.
|
||||
$submissionFileData = [];
|
||||
foreach ($revisions as $revision) {
|
||||
if ($viewableOnly && !$revision->getViewable()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$submissionFileData[$revision->getId()] = [
|
||||
'submissionFile' => $revision
|
||||
];
|
||||
}
|
||||
return $submissionFileData;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,229 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/files/SubmissionFilesGridHandler.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 SubmissionFilesGridHandler
|
||||
*
|
||||
* @ingroup controllers_grid_files
|
||||
*
|
||||
* @brief Handle submission file grid requests.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\files;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\submission\Submission;
|
||||
use PKP\controllers\grid\GridDataProvider;
|
||||
use PKP\controllers\grid\GridHandler;
|
||||
|
||||
class SubmissionFilesGridHandler extends GridHandler
|
||||
{
|
||||
/** @var FilesGridCapabilities */
|
||||
public $_capabilities;
|
||||
|
||||
/** @var ?int */
|
||||
public $_stageId;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param GridDataProvider $dataProvider
|
||||
* @param ?int $stageId One of the WORKFLOW_STAGE_ID_* constants.
|
||||
* @param int $capabilities A bit map with zero or more
|
||||
* FILE_GRID_* capabilities set.
|
||||
*/
|
||||
public function __construct($dataProvider, $stageId, $capabilities = 0)
|
||||
{
|
||||
parent::__construct($dataProvider);
|
||||
|
||||
if ($stageId) {
|
||||
$this->_stageId = (int)$stageId;
|
||||
}
|
||||
$this->_capabilities = new FilesGridCapabilities($capabilities);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Getters and Setters
|
||||
//
|
||||
/**
|
||||
* Get grid capabilities object.
|
||||
*
|
||||
* @return FilesGridCapabilities
|
||||
*/
|
||||
public function getCapabilities()
|
||||
{
|
||||
return $this->_capabilities;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set grid capabilities object.
|
||||
*
|
||||
* @param FilesGridCapabilities $capabilities
|
||||
*/
|
||||
public function setCapabilities($capabilities)
|
||||
{
|
||||
$this->_capabilities = $capabilities;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the workflow stage id.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getStageId()
|
||||
{
|
||||
return $this->_stageId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the authorized submission.
|
||||
*
|
||||
* @return Submission
|
||||
*/
|
||||
public function getSubmission()
|
||||
{
|
||||
// We assume proper authentication by the data provider.
|
||||
$submission = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_SUBMISSION);
|
||||
assert($submission instanceof Submission);
|
||||
return $submission;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Implement template methods from PKPHandler
|
||||
//
|
||||
/**
|
||||
* @copydoc PKPHandler::authorize()
|
||||
*/
|
||||
public function authorize($request, &$args, $roleAssignments)
|
||||
{
|
||||
// Set the stage id from the request parameter if not set previously.
|
||||
if (!$this->getStageId()) {
|
||||
$stageId = (int) $request->getUserVar('stageId');
|
||||
// This will be validated with the authorization policy added by
|
||||
// the grid data provider.
|
||||
$this->_stageId = $stageId;
|
||||
}
|
||||
|
||||
$dataProvider = $this->getDataProvider();
|
||||
$dataProvider->setStageId($this->getStageId());
|
||||
|
||||
return parent::authorize($request, $args, $roleAssignments);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::initialize()
|
||||
*
|
||||
* @param null|mixed $args
|
||||
*/
|
||||
public function initialize($request, $args = null)
|
||||
{
|
||||
parent::initialize($request, $args);
|
||||
|
||||
// Add grid actions
|
||||
$capabilities = $this->getCapabilities();
|
||||
$dataProvider = $this->getDataProvider();
|
||||
|
||||
$submission = $this->getSubmission();
|
||||
|
||||
if ($capabilities->canAdd()) {
|
||||
assert(isset($dataProvider));
|
||||
$this->addAction($dataProvider->getAddFileAction($request));
|
||||
}
|
||||
|
||||
// Test whether an archive tool is available for the export to work, if so, add 'download all' grid action
|
||||
if ($capabilities->canDownloadAll() && $this->hasGridDataElements($request)) {
|
||||
$stageId = $this->getStageId();
|
||||
$linkParams = [
|
||||
'nameLocaleKey' => $this->getTitle(),
|
||||
'fileStage' => $this->getDataProvider()->getFileStage(),
|
||||
'submissionId' => $submission->getId(),
|
||||
'stageId' => $stageId,
|
||||
];
|
||||
$files = $this->getFilesToDownload($request);
|
||||
|
||||
$this->addAction($capabilities->getDownloadAllAction($request, $files, $linkParams), GridHandler::GRID_ACTION_POSITION_BELOW);
|
||||
}
|
||||
|
||||
// The file name column is common to all file grid types.
|
||||
$this->addColumn(new FileNameGridColumn($capabilities->canViewNotes(), $this->getStageId()));
|
||||
|
||||
// Additional column with file upload date/creation date
|
||||
$this->addColumn(new FileDateGridColumn($capabilities->canViewNotes()));
|
||||
|
||||
// Set the no items row text
|
||||
$this->setEmptyRowText('grid.noFiles');
|
||||
}
|
||||
|
||||
/**
|
||||
* @copyDoc GridHandler::getFilterForm()
|
||||
*/
|
||||
protected function getFilterForm()
|
||||
{
|
||||
return 'controllers/grid/files/filesGridFilter.tpl';
|
||||
}
|
||||
|
||||
/**
|
||||
* @copyDoc GridHandler::renderFilter()
|
||||
*/
|
||||
public function renderFilter($request, $filterData = [])
|
||||
{
|
||||
return parent::renderFilter(
|
||||
$request,
|
||||
[
|
||||
'columns' => $this->getFilterColumns(),
|
||||
'gridId' => $this->getId()
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copyDoc GridHandler::getFilterSelectionData()
|
||||
*/
|
||||
public function getFilterSelectionData($request)
|
||||
{
|
||||
return [
|
||||
'search' => (string) $request->getUserVar('search'),
|
||||
'column' => (string) $request->getUserVar('column'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get which columns can be used by users to filter data.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getFilterColumns()
|
||||
{
|
||||
return [
|
||||
'name' => __('common.name'),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Overridden methods from GridHandler
|
||||
//
|
||||
/**
|
||||
* @copydoc GridHandler::getRowInstance()
|
||||
*/
|
||||
protected function getRowInstance()
|
||||
{
|
||||
return new SubmissionFilesGridRow($this->getCapabilities(), $this->getStageId());
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Protected methods.
|
||||
//
|
||||
public function getFilesToDownload($request)
|
||||
{
|
||||
return $this->getGridDataElements($request);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/files/SubmissionFilesGridRow.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 SubmissionFilesGridRow
|
||||
*
|
||||
* @ingroup controllers_grid_files
|
||||
*
|
||||
* @brief Handle submission file grid row requests.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\files;
|
||||
|
||||
use PKP\controllers\api\file\linkAction\DeleteFileLinkAction;
|
||||
use PKP\controllers\api\file\linkAction\EditFileLinkAction;
|
||||
use PKP\controllers\grid\GridRow;
|
||||
use PKP\controllers\informationCenter\linkAction\FileInfoCenterLinkAction;
|
||||
use PKP\submissionFile\SubmissionFile;
|
||||
|
||||
class SubmissionFilesGridRow extends GridRow
|
||||
{
|
||||
/** @var FilesGridCapabilities */
|
||||
public $_capabilities;
|
||||
|
||||
/** @var int */
|
||||
public $_stageId;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param FilesGridCapabilities $capabilities
|
||||
* @param int $stageId Stage ID (optional)
|
||||
*/
|
||||
public function __construct($capabilities = null, $stageId = null)
|
||||
{
|
||||
$this->_capabilities = $capabilities;
|
||||
$this->_stageId = $stageId;
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Getters and Setters
|
||||
//
|
||||
/**
|
||||
* Can the user delete files from this grid?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function canDelete()
|
||||
{
|
||||
return $this->_capabilities->canDelete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Can the user view file notes on this grid?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function canViewNotes()
|
||||
{
|
||||
return $this->_capabilities->canViewNotes();
|
||||
}
|
||||
|
||||
/**
|
||||
* Can the user manage files in this grid?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function canEdit()
|
||||
{
|
||||
return $this->_capabilities->canEdit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the stage id, if any.
|
||||
*
|
||||
* @return int Stage ID
|
||||
*/
|
||||
public function getStageId()
|
||||
{
|
||||
return $this->_stageId;
|
||||
}
|
||||
|
||||
//
|
||||
// Overridden template methods from GridRow
|
||||
//
|
||||
/**
|
||||
* @copydoc GridRow::initialize()
|
||||
*/
|
||||
public function initialize($request, $template = 'controllers/grid/gridRow.tpl')
|
||||
{
|
||||
parent::initialize($request, $template);
|
||||
|
||||
// Retrieve the submission file.
|
||||
$submissionFileData = & $this->getData();
|
||||
assert(isset($submissionFileData['submissionFile']));
|
||||
$submissionFile = & $submissionFileData['submissionFile']; /** @var SubmissionFile $submissionFile */
|
||||
assert(is_a($submissionFile, 'SubmissionFile'));
|
||||
|
||||
// File grid row actions:
|
||||
// 1) Information center action.
|
||||
if ($this->canViewNotes()) {
|
||||
$this->addAction(new FileInfoCenterLinkAction($request, $submissionFile, $this->getStageId()));
|
||||
}
|
||||
|
||||
// 2) Edit metadata action.
|
||||
if ($this->canEdit()) {
|
||||
$this->addAction(new EditFileLinkAction($request, $submissionFile, $this->getStageId()));
|
||||
}
|
||||
|
||||
// 3) Delete file action.
|
||||
if ($this->canDelete()) {
|
||||
$this->addAction(new DeleteFileLinkAction($request, $submissionFile, $this->getStageId()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/files/attachment/AuthorOpenReviewAttachmentsGridHandler.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 AuthorOpenReviewAttachmentsGridHandler
|
||||
*
|
||||
* @ingroup controllers_grid_files_attachment
|
||||
*
|
||||
* @brief Handle review attachment grid requests in open reviews (author's perspective)
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\files\attachment;
|
||||
|
||||
use PKP\controllers\grid\files\fileList\FileListGridHandler;
|
||||
use PKP\security\Role;
|
||||
|
||||
class AuthorOpenReviewAttachmentsGridHandler extends FileListGridHandler
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
// Pass in null stageId to be set in initialize from request var.
|
||||
// Show also files that are not viewable by default
|
||||
parent::__construct(
|
||||
new ReviewerReviewAttachmentGridDataProvider(),
|
||||
null
|
||||
);
|
||||
|
||||
$this->addRoleAssignment(
|
||||
[Role::ROLE_ID_MANAGER, Role::ROLE_ID_SITE_ADMIN, Role::ROLE_ID_SUB_EDITOR, Role::ROLE_ID_ASSISTANT, Role::ROLE_ID_AUTHOR],
|
||||
['fetchGrid', 'fetchRow']
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/files/attachment/AuthorReviewAttachmentsGridHandler.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 AuthorReviewAttachmentsGridHandler
|
||||
*
|
||||
* @ingroup controllers_grid_files_attachment
|
||||
*
|
||||
* @brief Handle review attachment grid requests (author's perspective)
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\files\attachment;
|
||||
|
||||
use PKP\controllers\grid\files\fileList\FileListGridHandler;
|
||||
use PKP\controllers\grid\files\review\ReviewGridDataProvider;
|
||||
use PKP\security\Role;
|
||||
use PKP\submissionFile\SubmissionFile;
|
||||
|
||||
class AuthorReviewAttachmentsGridHandler extends FileListGridHandler
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
// Pass in null stageId to be set in initialize from request var.
|
||||
parent::__construct(
|
||||
new ReviewGridDataProvider(SubmissionFile::SUBMISSION_FILE_REVIEW_ATTACHMENT, true),
|
||||
null
|
||||
);
|
||||
|
||||
$this->addRoleAssignment(
|
||||
[Role::ROLE_ID_MANAGER, Role::ROLE_ID_SITE_ADMIN, Role::ROLE_ID_SUB_EDITOR, Role::ROLE_ID_ASSISTANT, Role::ROLE_ID_AUTHOR],
|
||||
['fetchGrid', 'fetchRow']
|
||||
);
|
||||
|
||||
// Set the grid title.
|
||||
$this->setTitle('grid.reviewAttachments.title');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/files/attachment/EditorReviewAttachmentsGridHandler.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 EditorReviewAttachmentsGridHandler
|
||||
*
|
||||
* @ingroup controllers_grid_files_attachment
|
||||
*
|
||||
* @brief Editor's view of the Review Attachments Grid.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\files\attachment;
|
||||
|
||||
use PKP\controllers\grid\files\fileList\FileListGridHandler;
|
||||
use PKP\controllers\grid\files\FilesGridCapabilities;
|
||||
use PKP\security\Role;
|
||||
use PKP\submissionFile\SubmissionFile;
|
||||
|
||||
class EditorReviewAttachmentsGridHandler extends FileListGridHandler
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
// Pass in null stageId to be set in initialize from request var.
|
||||
parent::__construct(
|
||||
new ReviewerReviewAttachmentGridDataProvider(),
|
||||
null,
|
||||
FilesGridCapabilities::FILE_GRID_DELETE | FilesGridCapabilities::FILE_GRID_ADD | FilesGridCapabilities::FILE_GRID_VIEW_NOTES | FilesGridCapabilities::FILE_GRID_EDIT
|
||||
);
|
||||
|
||||
$this->addRoleAssignment(
|
||||
[Role::ROLE_ID_MANAGER, Role::ROLE_ID_SITE_ADMIN, Role::ROLE_ID_SUB_EDITOR, Role::ROLE_ID_ASSISTANT],
|
||||
[
|
||||
'fetchGrid', 'fetchRow'
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
+142
@@ -0,0 +1,142 @@
|
||||
<?php
|
||||
/**
|
||||
* @file controllers/grid/files/attachment/ReviewerReviewAttachmentGridDataProvider.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 ReviewerReviewAttachmentGridDataProvider
|
||||
*
|
||||
* @ingroup controllers_grid_files_attachment
|
||||
*
|
||||
* @brief Provide the reviewers access to their own review attachments data for grids.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\files\attachment;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\facades\Repo;
|
||||
use PKP\controllers\api\file\linkAction\AddFileLinkAction;
|
||||
use PKP\controllers\grid\files\SubmissionFilesGridDataProvider;
|
||||
use PKP\db\DAORegistry;
|
||||
use PKP\security\authorization\internal\ReviewAssignmentRequiredPolicy;
|
||||
use PKP\security\authorization\ReviewStageAccessPolicy;
|
||||
use PKP\submission\reviewAssignment\ReviewAssignmentDAO;
|
||||
use PKP\submissionFile\SubmissionFile;
|
||||
|
||||
class ReviewerReviewAttachmentGridDataProvider extends SubmissionFilesGridDataProvider
|
||||
{
|
||||
/** @var int */
|
||||
public $_reviewId;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(SubmissionFile::SUBMISSION_FILE_REVIEW_ATTACHMENT);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Implement template methods from GridDataProvider
|
||||
//
|
||||
/**
|
||||
* @copydoc GridDataProvider::getAuthorizationPolicy()
|
||||
*/
|
||||
public function getAuthorizationPolicy($request, $args, $roleAssignments)
|
||||
{
|
||||
// Need to use the reviewId because this grid can either be
|
||||
// viewed by the reviewer (in which case, we could do a
|
||||
// $request->getUser()->getId() or by the editor when reading
|
||||
// the review. The following covers both cases...
|
||||
$assocType = (int) $request->getUserVar('assocType');
|
||||
$assocId = (int) $request->getUserVar('assocId');
|
||||
if ($assocType && $assocId) {
|
||||
// Viewing from a Reviewer perspective.
|
||||
assert($assocType == Application::ASSOC_TYPE_REVIEW_ASSIGNMENT);
|
||||
|
||||
$this->setUploaderRoles($roleAssignments);
|
||||
|
||||
$authorizationPolicy = new ReviewStageAccessPolicy($request, $args, $roleAssignments, 'submissionId', $request->getUserVar('stageId'));
|
||||
$paramName = 'assocId';
|
||||
} else {
|
||||
// Viewing from a context role perspective.
|
||||
$authorizationPolicy = parent::getAuthorizationPolicy($request, $args, $roleAssignments);
|
||||
$paramName = 'reviewId';
|
||||
}
|
||||
|
||||
$authorizationPolicy->addPolicy(new ReviewAssignmentRequiredPolicy($request, $args, $paramName));
|
||||
|
||||
return $authorizationPolicy;
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridDataProvider::getRequestArgs()
|
||||
*/
|
||||
public function getRequestArgs()
|
||||
{
|
||||
return array_merge(
|
||||
parent::getRequestArgs(),
|
||||
[
|
||||
'assocType' => Application::ASSOC_TYPE_REVIEW_ASSIGNMENT,
|
||||
'assocId' => $this->_getReviewId()
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridDataProvider::loadData()
|
||||
*/
|
||||
public function loadData($filter = [])
|
||||
{
|
||||
$submissionFiles = Repo::submissionFile()
|
||||
->getCollector()
|
||||
->filterByAssoc(
|
||||
Application::ASSOC_TYPE_REVIEW_ASSIGNMENT,
|
||||
[$this->_getReviewId()]
|
||||
)->filterBySubmissionIds([$this->getSubmission()->getId()])
|
||||
->getMany()
|
||||
->toArray();
|
||||
return $this->prepareSubmissionFileData($submissionFiles, false, $filter);
|
||||
}
|
||||
|
||||
//
|
||||
// Overridden public methods from FilesGridDataProvider
|
||||
//
|
||||
/**
|
||||
* @copydoc FilesGridDataProvider::getAddFileAction()
|
||||
*/
|
||||
public function getAddFileAction($request)
|
||||
{
|
||||
$submission = $this->getSubmission();
|
||||
|
||||
$reviewAssignmentDao = DAORegistry::getDAO('ReviewAssignmentDAO'); /** @var ReviewAssignmentDAO $reviewAssignmentDao */
|
||||
$reviewAssignment = $reviewAssignmentDao->getById($this->_getReviewId());
|
||||
|
||||
return new AddFileLinkAction(
|
||||
$request,
|
||||
$submission->getId(),
|
||||
$this->getStageId(),
|
||||
$this->getUploaderRoles(),
|
||||
$this->getFileStage(),
|
||||
Application::ASSOC_TYPE_REVIEW_ASSIGNMENT,
|
||||
$this->_getReviewId(),
|
||||
$reviewAssignment->getReviewRoundId()
|
||||
);
|
||||
}
|
||||
//
|
||||
// Private helper methods
|
||||
//
|
||||
/**
|
||||
* Get the review id.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function _getReviewId()
|
||||
{
|
||||
$reviewAssignment = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_REVIEW_ASSIGNMENT);
|
||||
return $reviewAssignment->getId();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
/**
|
||||
* @file controllers/grid/files/attachment/ReviewerReviewAttachmentsGridHandler.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 ReviewerReviewAttachmentsGridHandler
|
||||
*
|
||||
* @ingroup controllers_grid_files_attachment
|
||||
*
|
||||
* @brief Handle file grid requests.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\files\attachment;
|
||||
|
||||
use PKP\controllers\grid\files\fileList\FileListGridHandler;
|
||||
use PKP\controllers\grid\files\FilesGridCapabilities;
|
||||
use PKP\security\Role;
|
||||
use PKP\submissionFile\SubmissionFile;
|
||||
|
||||
class ReviewerReviewAttachmentsGridHandler extends FileListGridHandler
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
// Pass in null stageId to be set in initialize from request var.
|
||||
parent::__construct(
|
||||
new ReviewerReviewAttachmentGridDataProvider(),
|
||||
null,
|
||||
FilesGridCapabilities::FILE_GRID_ADD | FilesGridCapabilities::FILE_GRID_DELETE | FilesGridCapabilities::FILE_GRID_EDIT
|
||||
);
|
||||
|
||||
$this->addRoleAssignment(
|
||||
[Role::ROLE_ID_MANAGER, Role::ROLE_ID_SITE_ADMIN, Role::ROLE_ID_SUB_EDITOR, Role::ROLE_ID_REVIEWER],
|
||||
[
|
||||
'fetchGrid', 'fetchRow'
|
||||
]
|
||||
);
|
||||
|
||||
// Set the grid title.
|
||||
$this->setTitle('reviewer.submission.reviewerFiles');
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc FileListGridHandler::initialize()
|
||||
*
|
||||
* @param null|mixed $args
|
||||
*/
|
||||
public function initialize($request, $args = null)
|
||||
{
|
||||
// Watch for flag from including template to warn about the
|
||||
// review already being complete. If so, remove some capabilities.
|
||||
$capabilities = $this->getCapabilities();
|
||||
if ($request->getUserVar('reviewIsClosed')) {
|
||||
$capabilities->setCanAdd(false);
|
||||
$capabilities->setCanDelete(false);
|
||||
}
|
||||
|
||||
parent::initialize($request, $args);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/files/copyedit/CopyeditFilesGridDataProvider.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 CopyeditFilesGridDataProvider
|
||||
*
|
||||
* @ingroup controllers_grid_files_copyedit
|
||||
*
|
||||
* @brief Provide access to copyedited files management.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\files\copyedit;
|
||||
|
||||
use PKP\controllers\grid\files\fileList\linkAction\SelectFilesLinkAction;
|
||||
use PKP\controllers\grid\files\SubmissionFilesGridDataProvider;
|
||||
use PKP\submissionFile\SubmissionFile;
|
||||
|
||||
class CopyeditFilesGridDataProvider extends SubmissionFilesGridDataProvider
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(SubmissionFile::SUBMISSION_FILE_COPYEDIT);
|
||||
}
|
||||
|
||||
//
|
||||
// Overridden public methods from FilesGridDataProvider
|
||||
//
|
||||
/**
|
||||
* @copydoc FilesGridDataProvider::getSelectAction()
|
||||
*/
|
||||
public function getSelectAction($request)
|
||||
{
|
||||
return new SelectFilesLinkAction(
|
||||
$request,
|
||||
[
|
||||
'submissionId' => $this->getSubmission()->getId(),
|
||||
'stageId' => $this->getStageId()
|
||||
],
|
||||
__('editor.submission.uploadSelectFiles')
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/files/copyedit/CopyeditFilesGridHandler.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 CopyeditFilesGridHandler
|
||||
*
|
||||
* @ingroup controllers_grid_files_copyedit
|
||||
*
|
||||
* @brief Handle the copyedited files grid
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\files\copyedit;
|
||||
|
||||
use APP\core\Application;
|
||||
use PKP\controllers\grid\files\copyedit\form\ManageCopyeditFilesForm;
|
||||
use PKP\controllers\grid\files\fileList\FileListGridHandler;
|
||||
use PKP\controllers\grid\files\FilesGridCapabilities;
|
||||
use PKP\core\JSONMessage;
|
||||
use PKP\core\PKPRequest;
|
||||
use PKP\security\Role;
|
||||
|
||||
class CopyeditFilesGridHandler extends FileListGridHandler
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
* FILE_GRID_* capabilities set.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(
|
||||
new CopyeditFilesGridDataProvider(),
|
||||
null
|
||||
);
|
||||
$this->addRoleAssignment(
|
||||
[
|
||||
Role::ROLE_ID_SUB_EDITOR,
|
||||
Role::ROLE_ID_MANAGER,
|
||||
Role::ROLE_ID_SITE_ADMIN,
|
||||
Role::ROLE_ID_ASSISTANT,
|
||||
Role::ROLE_ID_AUTHOR,
|
||||
],
|
||||
[
|
||||
'fetchGrid', 'fetchRow',
|
||||
]
|
||||
);
|
||||
$this->addRoleAssignment(
|
||||
[
|
||||
Role::ROLE_ID_SUB_EDITOR,
|
||||
Role::ROLE_ID_MANAGER,
|
||||
Role::ROLE_ID_SITE_ADMIN,
|
||||
Role::ROLE_ID_ASSISTANT
|
||||
],
|
||||
[
|
||||
'selectFiles'
|
||||
]
|
||||
);
|
||||
|
||||
|
||||
$this->setTitle('submission.copyedited');
|
||||
}
|
||||
|
||||
//
|
||||
// Public handler methods
|
||||
//
|
||||
/**
|
||||
* @copydoc GridHandler::initialize()
|
||||
*
|
||||
* @param null|mixed $args
|
||||
*/
|
||||
public function initialize($request, $args = null)
|
||||
{
|
||||
if (0 != count(array_intersect(
|
||||
$this->getAuthorizedContextObject(Application::ASSOC_TYPE_USER_ROLES),
|
||||
[Role::ROLE_ID_MANAGER, Role::ROLE_ID_SITE_ADMIN, Role::ROLE_ID_ASSISTANT, Role::ROLE_ID_SUB_EDITOR]
|
||||
// Authors may also view this grid, and shouldn't be able to do anything (just view).
|
||||
))) {
|
||||
$this->setCapabilities(new FilesGridCapabilities(FilesGridCapabilities::FILE_GRID_EDIT | FilesGridCapabilities::FILE_GRID_MANAGE | FilesGridCapabilities::FILE_GRID_VIEW_NOTES | FilesGridCapabilities::FILE_GRID_DELETE));
|
||||
}
|
||||
parent::initialize($request, $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form to allow the user to select files from previous stages
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function selectFiles($args, $request)
|
||||
{
|
||||
$manageCopyeditFilesForm = new ManageCopyeditFilesForm($this->getSubmission()->getId());
|
||||
$manageCopyeditFilesForm->initData();
|
||||
return new JSONMessage(true, $manageCopyeditFilesForm->fetch($request));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/files/copyedit/ManageCopyeditFilesGridHandler.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 ManageCopyeditFilesGridHandler
|
||||
*
|
||||
* @ingroup controllers_grid_files_copyedit
|
||||
*
|
||||
* @brief Handle the copyedited file selection grid
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\files\copyedit;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\notification\NotificationManager;
|
||||
use PKP\controllers\grid\files\copyedit\form\ManageCopyeditFilesForm;
|
||||
use PKP\controllers\grid\files\FilesGridCapabilities;
|
||||
use PKP\controllers\grid\files\SelectableSubmissionFileListCategoryGridHandler;
|
||||
use PKP\controllers\grid\files\SubmissionFilesCategoryGridDataProvider;
|
||||
use PKP\core\JSONMessage;
|
||||
use PKP\core\PKPRequest;
|
||||
use PKP\notification\PKPNotification;
|
||||
use PKP\security\Role;
|
||||
use PKP\submissionFile\SubmissionFile;
|
||||
|
||||
class ManageCopyeditFilesGridHandler extends SelectableSubmissionFileListCategoryGridHandler
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(
|
||||
new SubmissionFilesCategoryGridDataProvider(SubmissionFile::SUBMISSION_FILE_COPYEDIT),
|
||||
WORKFLOW_STAGE_ID_EDITING,
|
||||
FilesGridCapabilities::FILE_GRID_ADD | FilesGridCapabilities::FILE_GRID_DELETE | FilesGridCapabilities::FILE_GRID_VIEW_NOTES | FilesGridCapabilities::FILE_GRID_EDIT
|
||||
);
|
||||
|
||||
$this->addRoleAssignment(
|
||||
[
|
||||
Role::ROLE_ID_SUB_EDITOR,
|
||||
Role::ROLE_ID_MANAGER,
|
||||
Role::ROLE_ID_SITE_ADMIN,
|
||||
Role::ROLE_ID_ASSISTANT
|
||||
],
|
||||
[
|
||||
'fetchGrid', 'fetchCategory', 'fetchRow',
|
||||
'addFile',
|
||||
'downloadFile',
|
||||
'deleteFile',
|
||||
'updateCopyeditFiles'
|
||||
]
|
||||
);
|
||||
|
||||
// Set the grid title.
|
||||
$this->setTitle('submission.copyedited');
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Public handler methods
|
||||
//
|
||||
/**
|
||||
* Save 'manage copyedited files' form
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function updateCopyeditFiles($args, $request)
|
||||
{
|
||||
$submission = $this->getSubmission();
|
||||
|
||||
$manageCopyeditFilesForm = new ManageCopyeditFilesForm($submission->getId());
|
||||
$manageCopyeditFilesForm->readInputData();
|
||||
|
||||
if ($manageCopyeditFilesForm->validate()) {
|
||||
$manageCopyeditFilesForm->execute(
|
||||
$this->getGridCategoryDataElements($request, $this->getStageId())
|
||||
);
|
||||
|
||||
if ($submission->getStageId() == WORKFLOW_STAGE_ID_EDITING ||
|
||||
$submission->getStageId() == WORKFLOW_STAGE_ID_PRODUCTION) {
|
||||
$notificationMgr = new NotificationManager();
|
||||
$notificationMgr->updateNotification(
|
||||
$request,
|
||||
[
|
||||
PKPNotification::NOTIFICATION_TYPE_ASSIGN_COPYEDITOR,
|
||||
PKPNotification::NOTIFICATION_TYPE_AWAITING_COPYEDITS,
|
||||
],
|
||||
null,
|
||||
Application::ASSOC_TYPE_SUBMISSION,
|
||||
$submission->getId()
|
||||
);
|
||||
}
|
||||
|
||||
// Let the calling grid reload itself
|
||||
return \PKP\db\DAO::getDataChangedEvent();
|
||||
} else {
|
||||
return new JSONMessage(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/files/copyedit/form/ManageCopyeditFilesForm.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 ManageCopyeditFilesForm
|
||||
*
|
||||
* @ingroup controllers_grid_files_copyedit
|
||||
*
|
||||
* @brief Form to add files to the copyedited files grid
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\files\copyedit\form;
|
||||
|
||||
use PKP\controllers\grid\files\form\ManageSubmissionFilesForm;
|
||||
use PKP\submissionFile\SubmissionFile;
|
||||
|
||||
class ManageCopyeditFilesForm extends ManageSubmissionFilesForm
|
||||
{
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param int $submissionId Submission ID.
|
||||
*/
|
||||
public function __construct($submissionId)
|
||||
{
|
||||
parent::__construct($submissionId, 'controllers/grid/files/copyedit/manageCopyeditFiles.tpl');
|
||||
}
|
||||
|
||||
/**
|
||||
* Save selection of copyedited files
|
||||
*
|
||||
* @param array $stageSubmissionFiles List of submission files in this stage.
|
||||
* @param int $fileStage SubmissionFile::SUBMISSION_FILE_...
|
||||
*/
|
||||
public function execute($stageSubmissionFiles = null, $fileStage = null, ...$functionArgs)
|
||||
{
|
||||
parent::execute($stageSubmissionFiles, SubmissionFile::SUBMISSION_FILE_COPYEDIT);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/files/dependent/DependentFilesGridDataProvider.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 DependentFilesGridDataProvider
|
||||
*
|
||||
* @ingroup controllers_grid_files_dependent
|
||||
*
|
||||
* @brief Provide access to dependent file data for grids.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\files\dependent;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\facades\Repo;
|
||||
use PKP\controllers\api\file\linkAction\AddFileLinkAction;
|
||||
use PKP\controllers\grid\files\SubmissionFilesGridDataProvider;
|
||||
use PKP\submissionFile\SubmissionFile;
|
||||
|
||||
class DependentFilesGridDataProvider extends SubmissionFilesGridDataProvider
|
||||
{
|
||||
/**
|
||||
* The submission file id for the parent file.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $_assocId;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param int $assocId Association ID
|
||||
*/
|
||||
public function __construct($assocId)
|
||||
{
|
||||
assert(is_numeric($assocId));
|
||||
$this->_assocId = (int) $assocId;
|
||||
parent::__construct(SubmissionFile::SUBMISSION_FILE_DEPENDENT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridDataProvider::loadData()
|
||||
*/
|
||||
public function loadData($filter = [])
|
||||
{
|
||||
// Retrieve all dependent files for the given file stage and original submission file id (i.e. the main galley/production file)
|
||||
$submissionFiles = Repo::submissionFile()
|
||||
->getCollector()
|
||||
->filterByAssoc(
|
||||
Application::ASSOC_TYPE_SUBMISSION_FILE,
|
||||
[$this->getAssocId()]
|
||||
)->filterBySubmissionIds([$this->getSubmission()->getId()])
|
||||
->filterByFileStages([$this->getFileStage()])
|
||||
->includeDependentFiles()
|
||||
->getMany()
|
||||
->toArray();
|
||||
return $this->prepareSubmissionFileData($submissionFiles, $this->_viewableOnly, $filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Overridden from SubmissionFilesGridDataProvider - we need to also include the assocType and assocId
|
||||
*
|
||||
* @copydoc FilesGridDataProvider::getAddFileAction()
|
||||
*/
|
||||
public function getAddFileAction($request)
|
||||
{
|
||||
$submission = $this->getSubmission();
|
||||
return new AddFileLinkAction(
|
||||
$request,
|
||||
$submission->getId(),
|
||||
$this->getStageId(),
|
||||
$this->getUploaderRoles(),
|
||||
$this->getFileStage(),
|
||||
Application::ASSOC_TYPE_SUBMISSION_FILE,
|
||||
$this->getAssocId(),
|
||||
null,
|
||||
null,
|
||||
$this->isDependent()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the id of the parent submission file for these dependent files.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getAssocId()
|
||||
{
|
||||
return $this->_assocId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience function to make the argument to the AddFileLinkAction more obvious.
|
||||
*
|
||||
* @return true
|
||||
*/
|
||||
public function isDependent()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/files/dependent/DependentFilesGridHandler.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 DependentFilesGridHandler
|
||||
*
|
||||
* @ingroup controllers_grid_files_dependent
|
||||
*
|
||||
* @brief Handle dependent files that are associated with a submissions's display
|
||||
* (galleys or production formats, for example).
|
||||
* The submission author and all context/editor roles have access to this grid.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\files\dependent;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\submission\Submission;
|
||||
use PKP\controllers\grid\files\fileList\FileListGridHandler;
|
||||
use PKP\controllers\grid\files\FilesGridCapabilities;
|
||||
use PKP\security\authorization\PublicationAccessPolicy;
|
||||
use PKP\security\authorization\SubmissionFileAccessPolicy;
|
||||
use PKP\security\Role;
|
||||
|
||||
class DependentFilesGridHandler extends FileListGridHandler
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
// import app-specific grid data provider for access policies.
|
||||
$request = Application::get()->getRequest();
|
||||
$submissionFileId = $request->getUserVar('submissionFileId'); // authorized in authorize() method.
|
||||
|
||||
parent::__construct(
|
||||
new DependentFilesGridDataProvider($submissionFileId),
|
||||
$request->getUserVar('stageId')
|
||||
);
|
||||
|
||||
$this->addRoleAssignment(
|
||||
[Role::ROLE_ID_MANAGER, Role::ROLE_ID_SITE_ADMIN, Role::ROLE_ID_SUB_EDITOR, Role::ROLE_ID_ASSISTANT, Role::ROLE_ID_AUTHOR],
|
||||
['fetchGrid', 'fetchRow']
|
||||
);
|
||||
|
||||
$this->setTitle('submission.submit.dependentFiles');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the authorized publication.
|
||||
*
|
||||
* @return \Publication
|
||||
*/
|
||||
public function getPublication()
|
||||
{
|
||||
return $this->getAuthorizedContextObject(Application::ASSOC_TYPE_PUBLICATION);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @copydoc SubmissionFilesGridHandler::authorize()
|
||||
*/
|
||||
public function authorize($request, &$args, $roleAssignments)
|
||||
{
|
||||
$this->addPolicy(new SubmissionFileAccessPolicy($request, $args, $roleAssignments, SubmissionFileAccessPolicy::SUBMISSION_FILE_ACCESS_MODIFY, (int) $args['submissionFileId']));
|
||||
|
||||
$publicationId = $request->getUserVar('publicationId'); // authorized in authorize() method.
|
||||
if ($publicationId) {
|
||||
$this->addPolicy(new PublicationAccessPolicy($request, $args, $roleAssignments));
|
||||
}
|
||||
|
||||
return parent::authorize($request, $args, $roleAssignments);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::getRequestArgs()
|
||||
*/
|
||||
public function getRequestArgs()
|
||||
{
|
||||
$submissionFile = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_SUBMISSION_FILE);
|
||||
return array_merge(
|
||||
parent::getRequestArgs(),
|
||||
['submissionFileId' => $submissionFile->getId()]
|
||||
);
|
||||
}
|
||||
|
||||
public function initialize($request, $args = null)
|
||||
{
|
||||
$capabilities = FilesGridCapabilities::FILE_GRID_ADD | FilesGridCapabilities::FILE_GRID_DELETE | FilesGridCapabilities::FILE_GRID_VIEW_NOTES | FilesGridCapabilities::FILE_GRID_EDIT;
|
||||
|
||||
$publication = $this->getPublication();
|
||||
|
||||
if ($publication) {
|
||||
if ($publication->getData('status') == Submission::STATUS_PUBLISHED) {
|
||||
$capabilities = FilesGridCapabilities::FILE_GRID_VIEW_NOTES;
|
||||
}
|
||||
}
|
||||
|
||||
$this->setCapabilities(new FilesGridCapabilities($capabilities));
|
||||
|
||||
parent::initialize($request, $args);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
/**
|
||||
* @file controllers/grid/files/fileList/FileGenreGridColumn.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 FileGenreGridColumn
|
||||
*
|
||||
* @ingroup controllers_grid_files_fileList
|
||||
*
|
||||
* @brief Implements a file name column.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\files\fileList;
|
||||
|
||||
use PKP\controllers\grid\ColumnBasedGridCellProvider;
|
||||
use PKP\controllers\grid\GridColumn;
|
||||
use PKP\db\DAORegistry;
|
||||
use PKP\submission\GenreDAO;
|
||||
use PKP\submissionFile\SubmissionFile;
|
||||
|
||||
class FileGenreGridColumn extends GridColumn
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$cellProvider = new ColumnBasedGridCellProvider();
|
||||
parent::__construct('type', 'common.component', null, null, $cellProvider);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Public methods
|
||||
//
|
||||
/**
|
||||
* Method expected by ColumnBasedGridCellProvider
|
||||
* to render a cell in this column.
|
||||
*
|
||||
* @see ColumnBasedGridCellProvider::getTemplateVarsFromRowColumn()
|
||||
*/
|
||||
public function getTemplateVarsFromRow($row)
|
||||
{
|
||||
// Retrieve the submission file.
|
||||
$submissionFileData = & $row->getData();
|
||||
assert(isset($submissionFileData['submissionFile']));
|
||||
$submissionFile = & $submissionFileData['submissionFile']; /** @var SubmissionFile $submissionFile */
|
||||
assert(is_a($submissionFile, 'SubmissionFile'));
|
||||
|
||||
// Retrieve the genre label for the submission file.
|
||||
$genreDao = DAORegistry::getDAO('GenreDAO'); /** @var GenreDAO $genreDao */
|
||||
$genre = $genreDao->getById($submissionFile->getGenreId());
|
||||
|
||||
// If no label exists (e.g. for review attachments)
|
||||
if (!$genre) {
|
||||
return ['label' => null];
|
||||
}
|
||||
|
||||
// Otherwise, the label exists.
|
||||
return ['label' => $genre->getLocalizedName()];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
/**
|
||||
* @defgroup controllers_grid_files_fileList File List Grid
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file controllers/grid/files/fileList/FileListGridHandler.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 FileListGridHandler
|
||||
*
|
||||
* @ingroup controllers_grid_files_fileList
|
||||
*
|
||||
* @brief Base grid for simple file lists. This grid shows the file type in
|
||||
* addition to the file name.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\files\fileList;
|
||||
|
||||
use PKP\controllers\grid\files\SubmissionFilesGridHandler;
|
||||
|
||||
class FileListGridHandler extends SubmissionFilesGridHandler
|
||||
{
|
||||
//
|
||||
// Extended methods from SubmissionFilesGridHandler.
|
||||
//
|
||||
/**
|
||||
* @copydoc SubmissionFilesGridHandler::initialize()
|
||||
*
|
||||
* @param null|mixed $args
|
||||
*/
|
||||
public function initialize($request, $args = null)
|
||||
{
|
||||
parent::initialize($request, $args);
|
||||
|
||||
// Add the "manage files" action if required.
|
||||
$capabilities = $this->getCapabilities();
|
||||
if ($capabilities->canManage()) {
|
||||
$dataProvider = $this->getDataProvider();
|
||||
$this->addAction($dataProvider->getSelectAction($request));
|
||||
}
|
||||
|
||||
// The file list grid layout has an additional file genre column.
|
||||
$this->addColumn(new FileGenreGridColumn());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
/**
|
||||
* @file controllers/grid/files/fileList/SelectableFileListGridHandler.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 SelectableFileListGridHandler
|
||||
*
|
||||
* @ingroup controllers_grid_files_fileList
|
||||
*
|
||||
* @brief Base grid for selectable file lists. The grid use the SelectableItemFeature
|
||||
* to show a check box for each row so that the user can make a selection
|
||||
* among grid entries.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\files\fileList;
|
||||
|
||||
use PKP\controllers\grid\feature\selectableItems\SelectableItemsFeature;
|
||||
|
||||
class SelectableFileListGridHandler extends FileListGridHandler
|
||||
{
|
||||
//
|
||||
// Overriden methods from GridHandler.
|
||||
//
|
||||
/**
|
||||
* @copydoc GridHandler::initFeatures()
|
||||
*/
|
||||
public function initFeatures($request, $args)
|
||||
{
|
||||
return [new SelectableItemsFeature()];
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Implemented methods from GridHandler.
|
||||
//
|
||||
/**
|
||||
* @copydoc GridHandler::isDataElementSelected()
|
||||
*/
|
||||
public function isDataElementSelected($gridDataElement)
|
||||
{
|
||||
$file = $gridDataElement['submissionFile'];
|
||||
return $file->getViewable();
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::getSelectName()
|
||||
*/
|
||||
public function getSelectName()
|
||||
{
|
||||
return 'selectedFiles';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
/**
|
||||
* @defgroup controllers_grid_files_fileList_linkAction File List Link Actions
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file controllers/grid/files/fileList/linkAction/DownloadAllLinkAction.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 DownloadAllLinkAction
|
||||
*
|
||||
* @ingroup controllers_grid_files_fileList_linkAction
|
||||
*
|
||||
* @brief An action to download all files in a submission file grid.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\files\fileList\linkAction;
|
||||
|
||||
use APP\core\Request;
|
||||
use PKP\linkAction\LinkAction;
|
||||
use PKP\linkAction\request\PostAndRedirectAction;
|
||||
|
||||
class DownloadAllLinkAction extends LinkAction
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param Request $request
|
||||
* @param array $actionArgs
|
||||
*/
|
||||
public function __construct($request, $actionArgs)
|
||||
{
|
||||
// Instantiate the redirect action request.
|
||||
$router = $request->getRouter();
|
||||
$redirectRequest = new PostAndRedirectAction(
|
||||
$router->url($request, null, 'api.file.FileApiHandler', 'recordDownload', null, $actionArgs),
|
||||
$router->url($request, null, 'api.file.FileApiHandler', 'downloadAllFiles', null, $actionArgs)
|
||||
);
|
||||
|
||||
// Configure the link action.
|
||||
parent::__construct('downloadAll', $redirectRequest, __('submission.files.downloadAll'), 'getPackage');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
/**
|
||||
* @file controllers/grid/files/fileList/linkAction/SelectFilesLinkAction.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 SelectFilesLinkAction
|
||||
*
|
||||
* @ingroup controllers_grid_files_fileList_linkAction
|
||||
*
|
||||
* @brief An abstract base action for actions to open up a modal that allows users to
|
||||
* select files from a file list grid.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\files\fileList\linkAction;
|
||||
|
||||
use APP\core\Request;
|
||||
use PKP\linkAction\LinkAction;
|
||||
use PKP\linkAction\request\AjaxModal;
|
||||
|
||||
class SelectFilesLinkAction extends LinkAction
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param Request $request
|
||||
* @param array $actionArgs The parameters required by the
|
||||
* link action target to identify a list of files.
|
||||
* @param string $actionLabel The localized label of the link action.
|
||||
* @param string $modalTitle the (optional) title to be used for the modal.
|
||||
*/
|
||||
public function __construct($request, $actionArgs, $actionLabel, $modalTitle = null)
|
||||
{
|
||||
// Create an ajax action request that'll contain
|
||||
// the file selection grid.
|
||||
$modalTitle ??= $actionLabel;
|
||||
$router = $request->getRouter();
|
||||
$ajaxModal = new AjaxModal(
|
||||
$router->url($request, null, null, 'selectFiles', null, $actionArgs),
|
||||
$modalTitle,
|
||||
'modal_add_file'
|
||||
);
|
||||
|
||||
// Configure the link action.
|
||||
parent::__construct('selectFiles', $ajaxModal, $actionLabel, 'add');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
/**
|
||||
* @file controllers/grid/files/fileList/linkAction/SelectReviewFilesLinkAction.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 SelectReviewFilesLinkAction
|
||||
*
|
||||
* @ingroup controllers_grid_files_fileList_linkAction
|
||||
*
|
||||
* @brief An action to open up the modal that allows users to select review files
|
||||
* from a file list grid.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\files\fileList\linkAction;
|
||||
|
||||
use APP\core\Request;
|
||||
use PKP\submission\reviewRound\ReviewRound;
|
||||
|
||||
class SelectReviewFilesLinkAction extends SelectFilesLinkAction
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param Request $request
|
||||
* @param ReviewRound $reviewRound The review round from which to
|
||||
* select review files.
|
||||
* @param string $actionLabel The localized label of the link action.
|
||||
* @param string $modalTitle the (optional) title to be used for the modal.
|
||||
*/
|
||||
public function __construct($request, $reviewRound, $actionLabel, $modalTitle = null)
|
||||
{
|
||||
$actionArgs = ['submissionId' => $reviewRound->getSubmissionId(),
|
||||
'stageId' => $reviewRound->getStageId(), 'reviewRoundId' => $reviewRound->getId()];
|
||||
|
||||
parent::__construct($request, $actionArgs, $actionLabel, $modalTitle);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/files/final/FinalDraftFilesGridDataProvider.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 FinalDraftFilesGridDataProvider
|
||||
*
|
||||
* @ingroup controllers_grid_files_final
|
||||
*
|
||||
* @brief Provide access to final draft files management.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\files\final;
|
||||
|
||||
use PKP\controllers\grid\files\fileList\linkAction\SelectFilesLinkAction;
|
||||
use PKP\controllers\grid\files\SubmissionFilesGridDataProvider;
|
||||
use PKP\submissionFile\SubmissionFile;
|
||||
|
||||
class FinalDraftFilesGridDataProvider extends SubmissionFilesGridDataProvider
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(SubmissionFile::SUBMISSION_FILE_FINAL);
|
||||
}
|
||||
|
||||
//
|
||||
// Overridden public methods from FilesGridDataProvider
|
||||
//
|
||||
/**
|
||||
* @copydoc FilesGridDataProvider::getSelectAction()
|
||||
*/
|
||||
public function getSelectAction($request)
|
||||
{
|
||||
return new SelectFilesLinkAction(
|
||||
$request,
|
||||
[
|
||||
'submissionId' => $this->getSubmission()->getId(),
|
||||
'stageId' => $this->getStageId()
|
||||
],
|
||||
__('editor.submission.uploadSelectFiles')
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/files/final/FinalDraftFilesGridHandler.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 FinalDraftFilesGridHandler
|
||||
*
|
||||
* @ingroup controllers_grid_files_final
|
||||
*
|
||||
* @brief Handle the final draft files grid (displays files sent to copyediting from the review stage)
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\files\final;
|
||||
|
||||
use PKP\controllers\grid\files\fileList\FileListGridHandler;
|
||||
use PKP\controllers\grid\files\FilesGridCapabilities;
|
||||
use PKP\controllers\grid\files\final\form\ManageFinalDraftFilesForm;
|
||||
use PKP\core\JSONMessage;
|
||||
use PKP\core\PKPRequest;
|
||||
use PKP\security\Role;
|
||||
|
||||
class FinalDraftFilesGridHandler extends FileListGridHandler
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
* FILE_GRID_* capabilities set.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(
|
||||
new FinalDraftFilesGridDataProvider(),
|
||||
null,
|
||||
FilesGridCapabilities::FILE_GRID_DELETE | FilesGridCapabilities::FILE_GRID_EDIT | FilesGridCapabilities::FILE_GRID_MANAGE | FilesGridCapabilities::FILE_GRID_VIEW_NOTES
|
||||
);
|
||||
$this->addRoleAssignment(
|
||||
[
|
||||
Role::ROLE_ID_SUB_EDITOR,
|
||||
Role::ROLE_ID_MANAGER,
|
||||
Role::ROLE_ID_SITE_ADMIN,
|
||||
Role::ROLE_ID_ASSISTANT
|
||||
],
|
||||
[
|
||||
'fetchGrid', 'fetchRow', 'selectFiles'
|
||||
]
|
||||
);
|
||||
|
||||
$this->setTitle('submission.finalDraft');
|
||||
}
|
||||
|
||||
//
|
||||
// Public handler methods
|
||||
//
|
||||
/**
|
||||
* Show the form to allow the user to select files from previous stages
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function selectFiles($args, $request)
|
||||
{
|
||||
$manageFinalDraftFilesForm = new ManageFinalDraftFilesForm($this->getSubmission()->getId());
|
||||
$manageFinalDraftFilesForm->initData();
|
||||
return new JSONMessage(true, $manageFinalDraftFilesForm->fetch($request));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/files/final/ManageFinalDraftFilesGridHandler.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 ManageFinalDraftFilesGridHandler
|
||||
*
|
||||
* @ingroup controllers_grid_files_final
|
||||
*
|
||||
* @brief Handle the editor review file selection grid (selects which files to send to review or to next review round)
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\files\final;
|
||||
|
||||
use PKP\controllers\grid\files\FilesGridCapabilities;
|
||||
use PKP\controllers\grid\files\final\form\ManageFinalDraftFilesForm;
|
||||
use PKP\controllers\grid\files\SelectableSubmissionFileListCategoryGridHandler;
|
||||
use PKP\controllers\grid\files\SubmissionFilesCategoryGridDataProvider;
|
||||
use PKP\core\JSONMessage;
|
||||
use PKP\core\PKPRequest;
|
||||
use PKP\security\Role;
|
||||
use PKP\submissionFile\SubmissionFile;
|
||||
|
||||
class ManageFinalDraftFilesGridHandler extends SelectableSubmissionFileListCategoryGridHandler
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(
|
||||
new SubmissionFilesCategoryGridDataProvider(SubmissionFile::SUBMISSION_FILE_FINAL),
|
||||
WORKFLOW_STAGE_ID_EDITING,
|
||||
FilesGridCapabilities::FILE_GRID_ADD | FilesGridCapabilities::FILE_GRID_DELETE | FilesGridCapabilities::FILE_GRID_VIEW_NOTES | FilesGridCapabilities::FILE_GRID_EDIT
|
||||
);
|
||||
|
||||
$this->addRoleAssignment(
|
||||
[
|
||||
Role::ROLE_ID_SUB_EDITOR,
|
||||
Role::ROLE_ID_MANAGER,
|
||||
Role::ROLE_ID_SITE_ADMIN,
|
||||
Role::ROLE_ID_ASSISTANT
|
||||
],
|
||||
[
|
||||
'fetchGrid', 'fetchCategory', 'fetchRow',
|
||||
'addFile',
|
||||
'downloadFile',
|
||||
'deleteFile',
|
||||
'updateFinalDraftFiles'
|
||||
]
|
||||
);
|
||||
|
||||
// Set the grid title.
|
||||
$this->setTitle('submission.finalDraft');
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Public handler methods
|
||||
//
|
||||
/**
|
||||
* Save 'manage final draft files' form
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function updateFinalDraftFiles($args, $request)
|
||||
{
|
||||
$submission = $this->getSubmission();
|
||||
|
||||
$manageFinalDraftFilesForm = new ManageFinalDraftFilesForm($submission->getId());
|
||||
$manageFinalDraftFilesForm->readInputData();
|
||||
|
||||
if ($manageFinalDraftFilesForm->validate()) {
|
||||
$manageFinalDraftFilesForm->execute(
|
||||
$this->getGridCategoryDataElements($request, $this->getStageId())
|
||||
);
|
||||
|
||||
// Let the calling grid reload itself
|
||||
return \PKP\db\DAO::getDataChangedEvent();
|
||||
} else {
|
||||
return new JSONMessage(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/files/final/form/ManageFinalDraftFilesForm.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 ManageFinalDraftFilesForm
|
||||
*
|
||||
* @ingroup controllers_grid_files_finalDraftFiles
|
||||
*
|
||||
* @brief Form to add files to the final draft files grid
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\files\final\form;
|
||||
|
||||
use PKP\controllers\grid\files\form\ManageSubmissionFilesForm;
|
||||
use PKP\submissionFile\SubmissionFile;
|
||||
|
||||
class ManageFinalDraftFilesForm extends ManageSubmissionFilesForm
|
||||
{
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param int $submissionId Submission ID.
|
||||
*/
|
||||
public function __construct($submissionId)
|
||||
{
|
||||
parent::__construct($submissionId, 'controllers/grid/files/final/manageFinalDraftFiles.tpl');
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Overridden template methods
|
||||
//
|
||||
/**
|
||||
* Save Selection of Final Draft files
|
||||
*
|
||||
* @param array $stageSubmissionFiles The files that belongs to a file stage
|
||||
* that is currently being used by a grid inside this form.
|
||||
* @param int $fileStage SubmissionFile::SUBMISSION_FILE_...
|
||||
*/
|
||||
public function execute($stageSubmissionFiles = null, $fileStage = null, ...$functionArgs)
|
||||
{
|
||||
parent::execute($stageSubmissionFiles, SubmissionFile::SUBMISSION_FILE_FINAL);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/files/form/LibraryFileForm.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 LibraryFileForm
|
||||
*
|
||||
* @ingroup controllers_grid_file_form
|
||||
*
|
||||
* @brief Form for adding/editing a file
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\files\form;
|
||||
|
||||
use APP\file\LibraryFileManager;
|
||||
use APP\template\TemplateManager;
|
||||
use PKP\form\Form;
|
||||
|
||||
class LibraryFileForm extends Form
|
||||
{
|
||||
/** @var int the id of the context this library file is attached to */
|
||||
public $contextId;
|
||||
|
||||
/** @var LibraryFileManager the library file manager instantiated in this form. */
|
||||
public $libraryFileManager;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $template
|
||||
* @param int $contextId
|
||||
*/
|
||||
public function __construct($template, $contextId)
|
||||
{
|
||||
$this->contextId = $contextId;
|
||||
|
||||
parent::__construct($template);
|
||||
$this->libraryFileManager = $libraryFileManager = new LibraryFileManager($contextId);
|
||||
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorLocale($this, 'libraryFileName', 'required', 'settings.libraryFiles.nameRequired'));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorCustom(
|
||||
$this,
|
||||
'fileType',
|
||||
'required',
|
||||
'settings.libraryFiles.typeRequired',
|
||||
function ($type) use ($libraryFileManager) {
|
||||
return is_numeric($type) && $libraryFileManager->getNameFromType($type);
|
||||
}
|
||||
));
|
||||
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorPost($this));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorCSRF($this));
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::fetch()
|
||||
*
|
||||
* @param null|mixed $template
|
||||
*/
|
||||
public function fetch($request, $template = null, $display = false)
|
||||
{
|
||||
// load the file types for the selector on the form.
|
||||
$templateMgr = TemplateManager::getManager($request);
|
||||
$fileTypeKeys = $this->libraryFileManager->getTypeTitleKeyMap();
|
||||
$templateMgr->assign('fileTypes', $fileTypeKeys);
|
||||
|
||||
return parent::fetch($request, $template, $display);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign form data to user-submitted data.
|
||||
*
|
||||
* @see Form::readInputData()
|
||||
*/
|
||||
public function readInputData()
|
||||
{
|
||||
$this->readUserVars(['libraryFileName', 'fileType', 'publicAccess']);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/files/form/ManageSubmissionFilesForm.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 ManageSubmissionFilesForm
|
||||
*
|
||||
* @ingroup controllers_grid_files_form
|
||||
*
|
||||
* @brief Form for add or removing files from a review
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\files\form;
|
||||
|
||||
use APP\facades\Repo;
|
||||
use PKP\form\Form;
|
||||
use PKP\submissionFile\SubmissionFile;
|
||||
|
||||
class ManageSubmissionFilesForm extends Form
|
||||
{
|
||||
/** @var int */
|
||||
public $_submissionId;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param int $submissionId Submission ID
|
||||
* @param string $template Template filename
|
||||
*/
|
||||
public function __construct($submissionId, $template)
|
||||
{
|
||||
parent::__construct($template);
|
||||
$this->_submissionId = (int)$submissionId;
|
||||
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorPost($this));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorCSRF($this));
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Getters / Setters
|
||||
//
|
||||
/**
|
||||
* Get the submission id
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getSubmissionId()
|
||||
{
|
||||
return $this->_submissionId;
|
||||
}
|
||||
|
||||
//
|
||||
// Overridden template methods
|
||||
//
|
||||
/**
|
||||
* @copydoc Form::initData
|
||||
*/
|
||||
public function initData()
|
||||
{
|
||||
$this->setData('submissionId', $this->_submissionId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign form data to user-submitted data.
|
||||
*
|
||||
* @see Form::readInputData()
|
||||
*/
|
||||
public function readInputData()
|
||||
{
|
||||
$this->readUserVars(['selectedFiles']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save selection of submission files
|
||||
*
|
||||
* @param array $stageSubmissionFiles The files that belongs to a file stage
|
||||
* that is currently being used by a grid inside this form.
|
||||
* @param int $fileStage SubmissionFile::SUBMISSION_FILE_...
|
||||
*/
|
||||
public function execute($stageSubmissionFiles = null, $fileStage = null, ...$functionArgs)
|
||||
{
|
||||
$selectedFiles = (array)$this->getData('selectedFiles');
|
||||
$submissionFiles = Repo::submissionFile()
|
||||
->getCollector()
|
||||
->filterBySubmissionIds([$this->getSubmissionId()])
|
||||
->getMany();
|
||||
|
||||
foreach ($submissionFiles as $submissionFile) {
|
||||
// Get the viewable flag value.
|
||||
$isViewable = in_array(
|
||||
$submissionFile->getId(),
|
||||
$selectedFiles
|
||||
);
|
||||
|
||||
// If this is a submission file that's already in this listing...
|
||||
if ($this->fileExistsInStage($submissionFile, $stageSubmissionFiles, $fileStage)) {
|
||||
// ...update the "viewable" flag accordingly.
|
||||
if ($isViewable != $submissionFile->getData('viewable')) {
|
||||
Repo::submissionFile()
|
||||
->edit(
|
||||
$submissionFile,
|
||||
['viewable' => $isViewable]
|
||||
);
|
||||
$submissionFile = Repo::submissionFile()->get($submissionFile->getId());
|
||||
}
|
||||
} elseif ($isViewable) {
|
||||
// Import a file from a different workflow area
|
||||
$submissionFile = $this->importFile($submissionFile, $fileStage);
|
||||
}
|
||||
}
|
||||
|
||||
parent::execute($stageSubmissionFiles = null, $fileStage = null, ...$functionArgs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if a file with the same file stage is already present in the workflow stage.
|
||||
*
|
||||
* @param SubmissionFile $submissionFile The submission file
|
||||
* @param array $stageSubmissionFiles The list of submission files in the stage.
|
||||
* @param int $fileStage FILE_STAGE_...
|
||||
*/
|
||||
protected function fileExistsInStage($submissionFile, $stageSubmissionFiles, $fileStage)
|
||||
{
|
||||
if (!isset($stageSubmissionFiles[$submissionFile->getId()])) {
|
||||
return false;
|
||||
}
|
||||
foreach ($stageSubmissionFiles[$submissionFile->getId()] as $stageFile) {
|
||||
if ($stageFile->getFileStage() == $submissionFile->getFileStage() && $stageFile->getFileStage() == $fileStage) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a copy of the file to the specified file stage.
|
||||
*
|
||||
* @param SubmissionFile $submissionFile
|
||||
* @param int $fileStage SubmissionFile::SUBMISSION_FILE_...
|
||||
*
|
||||
* @return SubmissionFile Resultant new submission file
|
||||
*/
|
||||
protected function importFile($submissionFile, $fileStage)
|
||||
{
|
||||
$newSubmissionFile = clone $submissionFile;
|
||||
$newSubmissionFile->setData('fileStage', $fileStage);
|
||||
$newSubmissionFile->setData('sourceSubmissionFileId', $submissionFile->getId());
|
||||
$newSubmissionFileId = Repo::submissionFile()->add($newSubmissionFile);
|
||||
|
||||
return Repo::submissionFile()->get($newSubmissionFileId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/files/productionReady/ProductionReadyFilesGridHandler.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 ProductionReadyFilesGridHandler
|
||||
*
|
||||
* @ingroup controllers_grid_files_productionready
|
||||
*
|
||||
* @brief Handle the fair copy files grid (displays copyedited files ready to move to proofreading)
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\files\productionReady;
|
||||
|
||||
use PKP\controllers\grid\files\fileList\FileListGridHandler;
|
||||
use PKP\controllers\grid\files\FilesGridCapabilities;
|
||||
use PKP\controllers\grid\files\SubmissionFilesGridDataProvider;
|
||||
use PKP\security\Role;
|
||||
use PKP\submissionFile\SubmissionFile;
|
||||
|
||||
class ProductionReadyFilesGridHandler extends FileListGridHandler
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(
|
||||
new SubmissionFilesGridDataProvider(SubmissionFile::SUBMISSION_FILE_PRODUCTION_READY),
|
||||
WORKFLOW_STAGE_ID_PRODUCTION,
|
||||
FilesGridCapabilities::FILE_GRID_ADD | FilesGridCapabilities::FILE_GRID_DELETE | FilesGridCapabilities::FILE_GRID_VIEW_NOTES | FilesGridCapabilities::FILE_GRID_EDIT | FilesGridCapabilities::FILE_GRID_DOWNLOAD_ALL
|
||||
);
|
||||
|
||||
$this->addRoleAssignment(
|
||||
[
|
||||
Role::ROLE_ID_SUB_EDITOR,
|
||||
Role::ROLE_ID_MANAGER,
|
||||
Role::ROLE_ID_SITE_ADMIN,
|
||||
Role::ROLE_ID_ASSISTANT
|
||||
],
|
||||
[
|
||||
'fetchGrid', 'fetchRow',
|
||||
'addFile',
|
||||
'downloadFile',
|
||||
'deleteFile',
|
||||
]
|
||||
);
|
||||
|
||||
$this->setTitle('editor.submission.production.productionReadyFiles');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/files/proof/ManageProofFilesGridHandler.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 ManageProofFilesGridHandler
|
||||
*
|
||||
* @ingroup controllers_grid_files_proof
|
||||
*
|
||||
* @brief Handle the editor's proof files selection grid (selects which files to include)
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\files\proof;
|
||||
|
||||
use APP\core\Application;
|
||||
use PKP\controllers\grid\files\proof\form\ManageProofFilesForm;
|
||||
use PKP\controllers\grid\files\SelectableSubmissionFileListCategoryGridHandler;
|
||||
use PKP\controllers\grid\files\SubmissionFilesCategoryGridDataProvider;
|
||||
use PKP\core\JSONMessage;
|
||||
use PKP\core\PKPRequest;
|
||||
use PKP\security\authorization\internal\RepresentationRequiredPolicy;
|
||||
use PKP\security\authorization\PublicationAccessPolicy;
|
||||
use PKP\security\authorization\SubmissionAccessPolicy;
|
||||
use PKP\security\Role;
|
||||
use PKP\submissionFile\SubmissionFile;
|
||||
|
||||
class ManageProofFilesGridHandler extends SelectableSubmissionFileListCategoryGridHandler
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(
|
||||
new SubmissionFilesCategoryGridDataProvider(SubmissionFile::SUBMISSION_FILE_PROOF),
|
||||
WORKFLOW_STAGE_ID_PRODUCTION
|
||||
);
|
||||
|
||||
$this->addRoleAssignment(
|
||||
[Role::ROLE_ID_SUB_EDITOR, Role::ROLE_ID_MANAGER, Role::ROLE_ID_SITE_ADMIN],
|
||||
[
|
||||
'fetchGrid', 'fetchCategory', 'fetchRow',
|
||||
'addFile', 'downloadFile', 'deleteFile',
|
||||
'updateProofFiles',
|
||||
]
|
||||
);
|
||||
|
||||
// Set the grid title.
|
||||
$this->setTitle('submission.pageProofs');
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc PKPHandler::authorize()
|
||||
*/
|
||||
public function authorize($request, &$args, $roleAssignments)
|
||||
{
|
||||
$this->addPolicy(new SubmissionAccessPolicy($request, $args, $roleAssignments));
|
||||
|
||||
$this->addPolicy(new PublicationAccessPolicy($request, $args, $roleAssignments));
|
||||
$this->addPolicy(new RepresentationRequiredPolicy($request, $args));
|
||||
return parent::authorize($request, $args, $roleAssignments);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the grid request parameters.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getRequestArgs()
|
||||
{
|
||||
$publication = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_PUBLICATION);
|
||||
$representation = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_REPRESENTATION);
|
||||
return array_merge(
|
||||
parent::getRequestArgs(),
|
||||
[
|
||||
'publicationId' => $publication->getId(),
|
||||
'representationId' => $representation->getId()
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// Public handler methods
|
||||
//
|
||||
/**
|
||||
* Save 'manage proof files' form
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function updateProofFiles($args, $request)
|
||||
{
|
||||
$submission = $this->getSubmission();
|
||||
$publication = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_PUBLICATION);
|
||||
$representation = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_REPRESENTATION);
|
||||
|
||||
$manageProofFilesForm = new ManageProofFilesForm($submission->getId(), $publication->getId(), $representation->getId());
|
||||
$manageProofFilesForm->readInputData();
|
||||
|
||||
if ($manageProofFilesForm->validate()) {
|
||||
$manageProofFilesForm->execute(
|
||||
$this->getGridCategoryDataElements($request, $this->getStageId()),
|
||||
SubmissionFile::SUBMISSION_FILE_PROOF
|
||||
);
|
||||
|
||||
// Let the calling grid reload itself
|
||||
return \PKP\db\DAO::getDataChangedEvent();
|
||||
} else {
|
||||
return new JSONMessage(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/files/proof/form/ManageProofFilesForm.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 ManageProofFilesForm
|
||||
*
|
||||
* @ingroup controllers_grid_files_proof
|
||||
*
|
||||
* @brief Form to add files to the proof files grid
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\files\proof\form;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\template\TemplateManager;
|
||||
use PKP\controllers\grid\files\form\ManageSubmissionFilesForm;
|
||||
use PKP\submissionFile\SubmissionFile;
|
||||
|
||||
class ManageProofFilesForm extends ManageSubmissionFilesForm
|
||||
{
|
||||
/** @var int PublicationId ID. */
|
||||
public $_publicationId;
|
||||
|
||||
/** @var int Representation ID. */
|
||||
public $_representationId;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param int $submissionId Submission ID.
|
||||
* @param int $publicationId Publication ID
|
||||
* @param int $representationId Representation ID.
|
||||
*/
|
||||
public function __construct($submissionId, $publicationId, $representationId)
|
||||
{
|
||||
parent::__construct($submissionId, 'controllers/grid/files/proof/manageProofFiles.tpl');
|
||||
$this->_publicationId = $publicationId;
|
||||
$this->_representationId = $representationId;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Overridden template methods
|
||||
//
|
||||
/**
|
||||
* @copydoc ManageSubmissionFilesForm::fetch
|
||||
*
|
||||
* @param null|mixed $template
|
||||
*/
|
||||
public function fetch($request, $template = null, $display = false)
|
||||
{
|
||||
$templateMgr = TemplateManager::getManager($request);
|
||||
$templateMgr->assign('publicationId', $this->_publicationId);
|
||||
$templateMgr->assign('representationId', $this->_representationId);
|
||||
return parent::fetch($request, $template, $display);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc ManageSubmissionFilesForm::fileExistsInStage
|
||||
*/
|
||||
protected function fileExistsInStage($submissionFile, $stageSubmissionFiles, $fileStage)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @copydoc ManageSubmissionFilesForm::importFile()
|
||||
*/
|
||||
protected function importFile($submissionFile, $fileStage)
|
||||
{
|
||||
$newSubmissionFile = clone $submissionFile;
|
||||
$newSubmissionFile->setData('assocType', Application::ASSOC_TYPE_REPRESENTATION);
|
||||
$newSubmissionFile->setData('assocId', $this->_representationId);
|
||||
$newSubmissionFile->setData('viewable', false); // Not approved by default
|
||||
|
||||
return parent::importFile($newSubmissionFile, SubmissionFile::SUBMISSION_FILE_PROOF);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/files/query/ManageQueryNoteFilesGridHandler.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 ManageQueryNoteFilesGridHandler
|
||||
*
|
||||
* @ingroup controllers_grid_files_query
|
||||
*
|
||||
* @brief Handle the query file selection grid
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\files\query;
|
||||
|
||||
use APP\core\Application;
|
||||
use PKP\controllers\grid\files\FilesGridCapabilities;
|
||||
use PKP\controllers\grid\files\query\form\ManageQueryNoteFilesForm;
|
||||
use PKP\controllers\grid\files\SelectableSubmissionFileListCategoryGridHandler;
|
||||
use PKP\core\JSONMessage;
|
||||
use PKP\core\PKPRequest;
|
||||
use PKP\security\Role;
|
||||
|
||||
class ManageQueryNoteFilesGridHandler extends SelectableSubmissionFileListCategoryGridHandler
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$request = Application::get()->getRequest();
|
||||
$stageId = $request->getUservar('stageId'); // authorized by data provider.
|
||||
parent::__construct(
|
||||
new QueryNoteFilesCategoryGridDataProvider(),
|
||||
$stageId,
|
||||
FilesGridCapabilities::FILE_GRID_DELETE | FilesGridCapabilities::FILE_GRID_VIEW_NOTES | FilesGridCapabilities::FILE_GRID_EDIT
|
||||
);
|
||||
|
||||
$this->addRoleAssignment(
|
||||
[
|
||||
Role::ROLE_ID_SUB_EDITOR,
|
||||
Role::ROLE_ID_MANAGER,
|
||||
Role::ROLE_ID_SITE_ADMIN,
|
||||
Role::ROLE_ID_ASSISTANT
|
||||
],
|
||||
[
|
||||
'fetchGrid', 'fetchCategory', 'fetchRow',
|
||||
'addFile',
|
||||
'downloadFile',
|
||||
'deleteFile',
|
||||
'updateQueryNoteFiles'
|
||||
]
|
||||
);
|
||||
|
||||
// Set the grid title.
|
||||
$this->setTitle('submission.queryNoteFiles');
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Override methods from SelectableSubmissionFileListCategoryGridHandler
|
||||
//
|
||||
/**
|
||||
* @copydoc GridHandler::isDataElementInCategorySelected()
|
||||
*/
|
||||
public function isDataElementInCategorySelected($categoryDataId, &$gridDataElement)
|
||||
{
|
||||
$submissionFile = $gridDataElement['submissionFile'];
|
||||
|
||||
// Check for special cases when the file needs to be unselected.
|
||||
$dataProvider = $this->getDataProvider();
|
||||
if ($dataProvider->getFileStage() != $submissionFile->getFileStage()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Passed the checks above. If it's part of the current query, mark selected.
|
||||
$query = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_QUERY);
|
||||
$headNote = $query->getHeadNote();
|
||||
return ($submissionFile->getData('assocType') == Application::ASSOC_TYPE_NOTE && $submissionFile->getData('assocId') == $headNote->getId());
|
||||
}
|
||||
|
||||
//
|
||||
// Public handler methods
|
||||
//
|
||||
/**
|
||||
* Save 'manage query files' form
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function updateQueryNoteFiles($args, $request)
|
||||
{
|
||||
$submission = $this->getSubmission();
|
||||
$query = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_QUERY);
|
||||
|
||||
$manageQueryNoteFilesForm = new ManageQueryNoteFilesForm($submission->getId(), $query->getId(), $request->getUserVar('noteId'));
|
||||
$manageQueryNoteFilesForm->readInputData();
|
||||
|
||||
if ($manageQueryNoteFilesForm->validate()) {
|
||||
$manageQueryNoteFilesForm->execute(
|
||||
$this->getGridCategoryDataElements($request, $this->getStageId())
|
||||
);
|
||||
|
||||
// Let the calling grid reload itself
|
||||
return \PKP\db\DAO::getDataChangedEvent();
|
||||
} else {
|
||||
return new JSONMessage(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
/**
|
||||
* @file controllers/grid/files/query/QueryNoteFilesCategoryGridDataProvider.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 QueryNoteFilesCategoryGridDataProvider
|
||||
*
|
||||
* @ingroup controllers_grid_files_query
|
||||
*
|
||||
* @brief Provide access to query file data for category grids.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\files\query;
|
||||
|
||||
use APP\core\Application;
|
||||
use PKP\controllers\grid\files\SubmissionFilesCategoryGridDataProvider;
|
||||
use PKP\submissionFile\SubmissionFile;
|
||||
|
||||
class QueryNoteFilesCategoryGridDataProvider extends SubmissionFilesCategoryGridDataProvider
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(SubmissionFile::SUBMISSION_FILE_QUERY);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Overriden public methods from SubmissionFilesCategoryGridDataProvider
|
||||
//
|
||||
/**
|
||||
* @copydoc SubmissionFilesCategoryGridDataProvider::initGridDataProvider()
|
||||
*
|
||||
* @param null|mixed $initParams
|
||||
*/
|
||||
public function initGridDataProvider($fileStage, $initParams = null)
|
||||
{
|
||||
$request = Application::get()->getRequest();
|
||||
return new QueryNoteFilesGridDataProvider($request->getUserVar('noteId'));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/files/query/QueryNoteFilesGridDataProvider.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 QueryNoteFilesGridDataProvider
|
||||
*
|
||||
* @ingroup controllers_grid_files_query
|
||||
*
|
||||
* @brief Provide access to query files management.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\files\query;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\facades\Repo;
|
||||
use Exception;
|
||||
use PKP\controllers\api\file\linkAction\AddFileLinkAction;
|
||||
use PKP\controllers\grid\files\fileList\linkAction\SelectFilesLinkAction;
|
||||
use PKP\controllers\grid\files\SubmissionFilesGridDataProvider;
|
||||
use PKP\db\DAORegistry;
|
||||
use PKP\note\NoteDAO;
|
||||
use PKP\security\authorization\QueryAccessPolicy;
|
||||
use PKP\submissionFile\SubmissionFile;
|
||||
|
||||
class QueryNoteFilesGridDataProvider extends SubmissionFilesGridDataProvider
|
||||
{
|
||||
/** @var int Note ID */
|
||||
public $_noteId;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param int $noteId Note ID
|
||||
*/
|
||||
public function __construct($noteId)
|
||||
{
|
||||
parent::__construct(SubmissionFile::SUBMISSION_FILE_QUERY);
|
||||
$this->_noteId = $noteId;
|
||||
}
|
||||
|
||||
//
|
||||
// Overridden public methods from FilesGridDataProvider
|
||||
//
|
||||
/**
|
||||
* @copydoc GridDataProvider::getAuthorizationPolicy()
|
||||
*/
|
||||
public function getAuthorizationPolicy($request, $args, $roleAssignments)
|
||||
{
|
||||
$this->setUploaderRoles($roleAssignments);
|
||||
|
||||
return new QueryAccessPolicy($request, $args, $roleAssignments, $this->getStageId());
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc FilesGridDataProvider::getSelectAction()
|
||||
*/
|
||||
public function getSelectAction($request)
|
||||
{
|
||||
$query = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_QUERY);
|
||||
return new SelectFilesLinkAction(
|
||||
$request,
|
||||
$this->getRequestArgs(),
|
||||
__('editor.submission.selectFiles')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridDataProvider::loadData()
|
||||
*/
|
||||
public function loadData($filter = [])
|
||||
{
|
||||
// Retrieve all submission files for the given file query.
|
||||
$submission = $this->getSubmission();
|
||||
$query = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_QUERY);
|
||||
|
||||
$noteDao = DAORegistry::getDAO('NoteDAO'); /** @var NoteDAO $noteDao */
|
||||
$note = $noteDao->getById($this->_noteId);
|
||||
if ($note->getAssocType() != Application::ASSOC_TYPE_QUERY || $note->getAssocId() != $query->getId()) {
|
||||
throw new Exception('Invalid note ID specified!');
|
||||
}
|
||||
|
||||
$submissionFiles = Repo::submissionFile()
|
||||
->getCollector()
|
||||
->filterByAssoc(
|
||||
Application::ASSOC_TYPE_NOTE,
|
||||
[$this->_noteId]
|
||||
)->filterBySubmissionIds([$submission->getId()])
|
||||
->filterByFileStages([(int) $this->getFileStage()])
|
||||
->getMany()
|
||||
->toArray();
|
||||
return $this->prepareSubmissionFileData($submissionFiles, $this->_viewableOnly, $filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridDataProvider::getRequestArgs()
|
||||
*/
|
||||
public function getRequestArgs()
|
||||
{
|
||||
$query = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_QUERY);
|
||||
$representation = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_REPRESENTATION);
|
||||
return array_merge(
|
||||
parent::getRequestArgs(),
|
||||
[
|
||||
'assocType' => Application::ASSOC_TYPE_NOTE,
|
||||
'assocId' => $this->_noteId,
|
||||
'queryId' => $query->getId(),
|
||||
'noteId' => $this->_noteId,
|
||||
'representationId' => $representation ? $representation->getId() : null,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc FilesGridDataProvider::getAddFileAction()
|
||||
*/
|
||||
public function getAddFileAction($request)
|
||||
{
|
||||
$submission = $this->getSubmission();
|
||||
$query = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_QUERY);
|
||||
return new AddFileLinkAction(
|
||||
$request,
|
||||
$submission->getId(),
|
||||
$this->getStageId(),
|
||||
$this->getUploaderRoles(),
|
||||
$this->getFileStage(),
|
||||
Application::ASSOC_TYPE_NOTE,
|
||||
$this->_noteId,
|
||||
null,
|
||||
null,
|
||||
false,
|
||||
$query->getId()
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/files/query/QueryNoteFilesGridHandler.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 QueryNoteFilesGridHandler
|
||||
*
|
||||
* @ingroup controllers_grid_files_query
|
||||
*
|
||||
* @brief Handle query files that are associated with a query
|
||||
* The participants of a query have access to the files in this grid.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\files\query;
|
||||
|
||||
use APP\core\Application;
|
||||
use PKP\controllers\grid\files\fileList\FileListGridHandler;
|
||||
use PKP\controllers\grid\files\FilesGridCapabilities;
|
||||
use PKP\controllers\grid\files\query\form\ManageQueryNoteFilesForm;
|
||||
use PKP\core\JSONMessage;
|
||||
use PKP\core\PKPRequest;
|
||||
use PKP\security\authorization\QueryAccessPolicy;
|
||||
use PKP\security\Role;
|
||||
|
||||
class QueryNoteFilesGridHandler extends FileListGridHandler
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
// import app-specific grid data provider for access policies.
|
||||
$request = Application::get()->getRequest();
|
||||
$stageId = $request->getUservar('stageId'); // authorized in authorize() method.
|
||||
parent::__construct(
|
||||
new QueryNoteFilesGridDataProvider($request->getUserVar('noteId')),
|
||||
$stageId,
|
||||
FilesGridCapabilities::FILE_GRID_ADD | FilesGridCapabilities::FILE_GRID_DELETE | FilesGridCapabilities::FILE_GRID_VIEW_NOTES | FilesGridCapabilities::FILE_GRID_EDIT
|
||||
);
|
||||
|
||||
$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],
|
||||
['fetchGrid', 'fetchRow', 'selectFiles']
|
||||
);
|
||||
|
||||
// Set grid title.
|
||||
$this->setTitle('submission.queries.attachedFiles');
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc SubmissionFilesGridHandler::authorize()
|
||||
*/
|
||||
public function authorize($request, &$args, $roleAssignments)
|
||||
{
|
||||
$stageId = $request->getUserVar('stageId'); // This is being validated in WorkflowStageAccessPolicy
|
||||
$this->_stageId = (int)$stageId;
|
||||
|
||||
// Get the stage access policy
|
||||
$queryAccessPolicy = new QueryAccessPolicy($request, $args, $roleAssignments, $stageId);
|
||||
$this->addPolicy($queryAccessPolicy);
|
||||
$result = parent::authorize($request, $args, $roleAssignments);
|
||||
|
||||
if (0 != count(array_intersect(
|
||||
$this->getAuthorizedContextObject(Application::ASSOC_TYPE_USER_ROLES),
|
||||
[Role::ROLE_ID_MANAGER, Role::ROLE_ID_SITE_ADMIN, Role::ROLE_ID_SUB_EDITOR, Role::ROLE_ID_ASSISTANT]
|
||||
))) {
|
||||
$this->getCapabilities()->setCanManage(true);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Public handler methods
|
||||
//
|
||||
/**
|
||||
* Show the form to allow the user to select files from previous stages
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function selectFiles($args, $request)
|
||||
{
|
||||
$submission = $this->getSubmission();
|
||||
$query = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_QUERY);
|
||||
|
||||
$manageQueryNoteFilesForm = new ManageQueryNoteFilesForm($submission->getId(), $query->getId(), $request->getUserVar('noteId'), $this->getRequestArgs());
|
||||
$manageQueryNoteFilesForm->initData();
|
||||
return new JSONMessage(true, $manageQueryNoteFilesForm->fetch($request));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/files/query/form/ManageQueryNoteFilesForm.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 ManageQueryNoteFilesForm
|
||||
*
|
||||
* @ingroup controllers_grid_files_query
|
||||
*
|
||||
* @brief Form to add files to the query files grid
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\files\query\form;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\template\TemplateManager;
|
||||
use PKP\controllers\grid\files\form\ManageSubmissionFilesForm;
|
||||
use PKP\submissionFile\SubmissionFile;
|
||||
|
||||
class ManageQueryNoteFilesForm extends ManageSubmissionFilesForm
|
||||
{
|
||||
/** @var int Query ID */
|
||||
public $_queryId;
|
||||
|
||||
/** @var int Note ID */
|
||||
public $_noteId;
|
||||
|
||||
/** @var array Extra parameters to actions. */
|
||||
public $_actionArgs;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param int $submissionId Submission ID.
|
||||
* @param int $queryId Query ID.
|
||||
* @param int $noteId Note ID.
|
||||
* @param array $actionArgs Optional list of extra request parameters.
|
||||
*/
|
||||
public function __construct($submissionId, $queryId, $noteId, $actionArgs = [])
|
||||
{
|
||||
parent::__construct($submissionId, 'controllers/grid/files/query/manageQueryNoteFiles.tpl');
|
||||
$this->_queryId = $queryId;
|
||||
$this->_noteId = $noteId;
|
||||
$this->_actionArgs = $actionArgs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::fetch()
|
||||
*
|
||||
* @param null|mixed $template
|
||||
*/
|
||||
public function fetch($request, $template = null, $display = false)
|
||||
{
|
||||
$templateMgr = TemplateManager::getManager($request);
|
||||
$templateMgr->assign([
|
||||
'queryId' => $this->_queryId,
|
||||
'noteId' => $this->_noteId,
|
||||
'actionArgs' => $this->_actionArgs,
|
||||
]);
|
||||
return parent::fetch($request, $template, $display);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save selection of query files
|
||||
*
|
||||
* @param array $stageSubmissionFiles The list of submission files in the stage.
|
||||
* @param int $fileStage SubmissionFile::SUBMISSION_FILE_...
|
||||
*/
|
||||
public function execute($stageSubmissionFiles = null, $fileStage = null, ...$functionArgs)
|
||||
{
|
||||
parent::execute($stageSubmissionFiles, SubmissionFile::SUBMISSION_FILE_QUERY);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc ManageSubmissionFilesForm::fileExistsInStage
|
||||
*/
|
||||
protected function fileExistsInStage($submissionFile, $stageSubmissionFiles, $fileStage)
|
||||
{
|
||||
if (!parent::fileExistsInStage($submissionFile, $stageSubmissionFiles, $fileStage)) {
|
||||
return false;
|
||||
}
|
||||
foreach ($stageSubmissionFiles[$submissionFile->getId()] as $stageFile) {
|
||||
if (
|
||||
$stageFile->getFileStage() == $submissionFile->getFileStage() &&
|
||||
$stageFile->getFileStage() == $fileStage &&
|
||||
($stageFile->getData('assocType') != Application::ASSOC_TYPE_NOTE || $stageFile->getData('assocId') == $this->_noteId)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc ManageSubmissionFilesForm::importFile()
|
||||
*/
|
||||
protected function importFile($submissionFile, $fileStage)
|
||||
{
|
||||
$newSubmissionFile = clone $submissionFile;
|
||||
$newSubmissionFile->setData('assocType', Application::ASSOC_TYPE_NOTE);
|
||||
$newSubmissionFile->setData('assocId', $this->_noteId);
|
||||
|
||||
return parent::importFile($newSubmissionFile, $fileStage);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/files/review/AuthorReviewRevisionsGridHandler.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 AuthorReviewRevisionsGridHandler
|
||||
*
|
||||
* @ingroup controllers_grid_files_review
|
||||
*
|
||||
* @brief Display to authors the file revisions that they have uploaded.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\files\review;
|
||||
|
||||
use APP\core\Application;
|
||||
use PKP\controllers\grid\files\fileList\FileListGridHandler;
|
||||
use PKP\controllers\grid\files\FilesGridCapabilities;
|
||||
use PKP\security\Role;
|
||||
use PKP\submissionFile\SubmissionFile;
|
||||
|
||||
class AuthorReviewRevisionsGridHandler extends FileListGridHandler
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$stageId = (int) Application::get()->getRequest()->getUserVar('stageId');
|
||||
$fileStage = $stageId === WORKFLOW_STAGE_ID_INTERNAL_REVIEW ? SubmissionFile::SUBMISSION_FILE_INTERNAL_REVIEW_REVISION : SubmissionFile::SUBMISSION_FILE_REVIEW_REVISION;
|
||||
parent::__construct(
|
||||
new ReviewGridDataProvider($fileStage),
|
||||
null,
|
||||
FilesGridCapabilities::FILE_GRID_ADD | FilesGridCapabilities::FILE_GRID_EDIT | FilesGridCapabilities::FILE_GRID_DELETE
|
||||
);
|
||||
|
||||
$this->addRoleAssignment(
|
||||
[Role::ROLE_ID_AUTHOR],
|
||||
['fetchGrid', 'fetchRow']
|
||||
);
|
||||
|
||||
$this->setTitle('editor.submission.revisions');
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::getJSHandler()
|
||||
*/
|
||||
public function getJSHandler()
|
||||
{
|
||||
return '$.pkp.controllers.grid.files.review.AuthorReviewRevisionsGridHandler';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/files/review/EditorReviewFilesGridHandler.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 EditorReviewFilesGridHandler
|
||||
*
|
||||
* @ingroup controllers_grid_files_review
|
||||
*
|
||||
* @brief Handle the editor review file grid (displays files that are to be reviewed in the current round)
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\files\review;
|
||||
|
||||
use APP\core\Application;
|
||||
use PKP\controllers\grid\files\fileList\FileListGridHandler;
|
||||
use PKP\controllers\grid\files\FilesGridCapabilities;
|
||||
use PKP\controllers\grid\files\review\form\ManageReviewFilesForm;
|
||||
use PKP\core\JSONMessage;
|
||||
use PKP\core\PKPRequest;
|
||||
use PKP\security\Role;
|
||||
use PKP\submissionFile\SubmissionFile;
|
||||
|
||||
class EditorReviewFilesGridHandler extends FileListGridHandler
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$stageId = (int) Application::get()->getRequest()->getUserVar('stageId');
|
||||
$fileStage = $stageId === WORKFLOW_STAGE_ID_INTERNAL_REVIEW ? SubmissionFile::SUBMISSION_FILE_INTERNAL_REVIEW_FILE : SubmissionFile::SUBMISSION_FILE_REVIEW_FILE;
|
||||
parent::__construct(
|
||||
new ReviewGridDataProvider($fileStage),
|
||||
null,
|
||||
FilesGridCapabilities::FILE_GRID_EDIT | FilesGridCapabilities::FILE_GRID_MANAGE | FilesGridCapabilities::FILE_GRID_VIEW_NOTES | FilesGridCapabilities::FILE_GRID_DELETE
|
||||
);
|
||||
|
||||
$this->addRoleAssignment(
|
||||
[Role::ROLE_ID_MANAGER, Role::ROLE_ID_SITE_ADMIN, Role::ROLE_ID_SUB_EDITOR, Role::ROLE_ID_ASSISTANT],
|
||||
['fetchGrid', 'fetchRow', 'selectFiles']
|
||||
);
|
||||
|
||||
$this->setTitle('reviewer.submission.reviewFiles');
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Public handler methods
|
||||
//
|
||||
/**
|
||||
* Show the form to allow the user to select review files
|
||||
* (bring in/take out files from submission stage to review stage)
|
||||
*
|
||||
* FIXME: Move to its own handler so that it can be re-used among grids.
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function selectFiles($args, $request)
|
||||
{
|
||||
$submission = $this->getSubmission();
|
||||
|
||||
$manageReviewFilesForm = new ManageReviewFilesForm($submission->getId(), $this->getRequestArg('stageId'), $this->getRequestArg('reviewRoundId'));
|
||||
|
||||
$manageReviewFilesForm->initData();
|
||||
return new JSONMessage(true, $manageReviewFilesForm->fetch($request));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
/**
|
||||
* @file controllers/grid/files/review/LimitReviewFilesGridHandler.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 LimitReviewFilesGridHandler
|
||||
*
|
||||
* @ingroup controllers_grid_files_review
|
||||
*
|
||||
* @brief Display a selectable list of review files for the round to editors.
|
||||
* Items in this list can be selected or deselected to give a specific subset
|
||||
* to a particular reviewer.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\files\review;
|
||||
|
||||
use APP\core\Application;
|
||||
use PKP\controllers\grid\files\fileList\SelectableFileListGridHandler;
|
||||
use PKP\controllers\grid\files\FilesGridCapabilities;
|
||||
use PKP\db\DAORegistry;
|
||||
use PKP\security\authorization\internal\ReviewAssignmentRequiredPolicy;
|
||||
use PKP\security\authorization\ReviewStageAccessPolicy;
|
||||
use PKP\security\Role;
|
||||
use PKP\submission\ReviewFilesDAO;
|
||||
use PKP\submissionFile\SubmissionFile;
|
||||
|
||||
class LimitReviewFilesGridHandler extends SelectableFileListGridHandler
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$stageId = (int) Application::get()->getRequest()->getUserVar('stageId');
|
||||
$fileStage = $stageId === WORKFLOW_STAGE_ID_INTERNAL_REVIEW ? SubmissionFile::SUBMISSION_FILE_INTERNAL_REVIEW_FILE : SubmissionFile::SUBMISSION_FILE_REVIEW_FILE;
|
||||
// Pass in null stageId to be set in initialize from request var.
|
||||
parent::__construct(
|
||||
new ReviewGridDataProvider($fileStage),
|
||||
null,
|
||||
FilesGridCapabilities::FILE_GRID_VIEW_NOTES
|
||||
);
|
||||
|
||||
$this->addRoleAssignment(
|
||||
[Role::ROLE_ID_MANAGER, Role::ROLE_ID_SITE_ADMIN, Role::ROLE_ID_SUB_EDITOR, Role::ROLE_ID_ASSISTANT],
|
||||
['fetchGrid', 'fetchRow']
|
||||
);
|
||||
|
||||
// Set the grid information.
|
||||
$this->setTitle('editor.submissionReview.restrictFiles');
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc PKPHandler::authorize()
|
||||
*/
|
||||
public function authorize($request, &$args, $roleAssignments)
|
||||
{
|
||||
if ($reviewAssignmentId = $request->getUserVar('reviewAssignmentId')) {
|
||||
// If a review assignment ID is specified, preload the
|
||||
// checkboxes with the currently selected files. To do
|
||||
// this, we'll need the review assignment in the context.
|
||||
// Add the required policies:
|
||||
|
||||
// 1) Review stage access policy (fetches submission in context)
|
||||
$this->addPolicy(new ReviewStageAccessPolicy($request, $args, $roleAssignments, 'submissionId', $request->getUserVar('stageId')));
|
||||
|
||||
// 2) Review assignment
|
||||
$this->addPolicy(new ReviewAssignmentRequiredPolicy($request, $args, 'reviewAssignmentId', ['fetchGrid', 'fetchRow']));
|
||||
}
|
||||
return parent::authorize($request, $args, $roleAssignments);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::isDataElementSelected()
|
||||
*/
|
||||
public function isDataElementSelected($gridDataElement)
|
||||
{
|
||||
$reviewAssignment = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_REVIEW_ASSIGNMENT);
|
||||
if ($reviewAssignment) {
|
||||
$submissionFile = $gridDataElement['submissionFile'];
|
||||
// A review assignment was specified in the request; preset the
|
||||
// checkboxes to the currently available set of files.
|
||||
$reviewFilesDao = DAORegistry::getDAO('ReviewFilesDAO'); /** @var ReviewFilesDAO $reviewFilesDao */
|
||||
return $reviewFilesDao->check($reviewAssignment->getId(), $submissionFile->getId());
|
||||
} else {
|
||||
// No review assignment specified; default to all files available.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
/**
|
||||
* @file controllers/grid/files/review/ManageReviewFilesGridHandler.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 ManageReviewFilesGridHandler
|
||||
*
|
||||
* @ingroup controllers_grid_files_review
|
||||
*
|
||||
* @brief Handle the editor review file selection grid (selects which files to send to review or to next review round)
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\files\review;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\notification\NotificationManager;
|
||||
use PKP\controllers\grid\files\FilesGridCapabilities;
|
||||
use PKP\controllers\grid\files\review\form\ManageReviewFilesForm;
|
||||
use PKP\controllers\grid\files\SelectableSubmissionFileListCategoryGridHandler;
|
||||
use PKP\core\JSONMessage;
|
||||
use PKP\core\PKPRequest;
|
||||
use PKP\notification\PKPNotification;
|
||||
use PKP\security\Role;
|
||||
use PKP\submissionFile\SubmissionFile;
|
||||
|
||||
class ManageReviewFilesGridHandler extends SelectableSubmissionFileListCategoryGridHandler
|
||||
{
|
||||
/** @var array */
|
||||
public $_selectionArgs;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$stageId = (int) Application::get()->getRequest()->getUserVar('stageId');
|
||||
$fileStage = $stageId === WORKFLOW_STAGE_ID_INTERNAL_REVIEW ? SubmissionFile::SUBMISSION_FILE_INTERNAL_REVIEW_FILE : SubmissionFile::SUBMISSION_FILE_REVIEW_FILE;
|
||||
// Pass in null stageId to be set in initialize from request var.
|
||||
parent::__construct(
|
||||
new ReviewCategoryGridDataProvider($fileStage),
|
||||
null,
|
||||
FilesGridCapabilities::FILE_GRID_ADD | FilesGridCapabilities::FILE_GRID_VIEW_NOTES
|
||||
);
|
||||
|
||||
$this->addRoleAssignment(
|
||||
[Role::ROLE_ID_MANAGER, Role::ROLE_ID_SITE_ADMIN, Role::ROLE_ID_SUB_EDITOR, Role::ROLE_ID_ASSISTANT],
|
||||
['fetchGrid', 'fetchCategory', 'fetchRow', 'updateReviewFiles']
|
||||
);
|
||||
|
||||
// Set the grid title.
|
||||
$this->setTitle('reviewer.submission.reviewFiles');
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Public handler methods
|
||||
//
|
||||
/**
|
||||
* Save 'manage review files' form.
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function updateReviewFiles($args, $request)
|
||||
{
|
||||
$submission = $this->getSubmission();
|
||||
|
||||
$manageReviewFilesForm = new ManageReviewFilesForm($submission->getId(), $this->getRequestArg('stageId'), $this->getRequestArg('reviewRoundId'));
|
||||
$manageReviewFilesForm->readInputData();
|
||||
|
||||
if ($manageReviewFilesForm->validate()) {
|
||||
$dataProvider = $this->getDataProvider();
|
||||
$manageReviewFilesForm->execute(
|
||||
$this->getGridCategoryDataElements($request, $this->getStageId())
|
||||
);
|
||||
|
||||
$this->setupTemplate($request);
|
||||
$user = $request->getUser();
|
||||
$notificationManager = new NotificationManager();
|
||||
$notificationManager->createTrivialNotification($user->getId(), PKPNotification::NOTIFICATION_TYPE_SUCCESS, ['contents' => __('notification.updatedReviewFiles')]);
|
||||
|
||||
// Let the calling grid reload itself
|
||||
return \PKP\db\DAO::getDataChangedEvent();
|
||||
} else {
|
||||
return new JSONMessage(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Extended methods from CategoryGridHandler.
|
||||
//
|
||||
/**
|
||||
* @copydoc CategoryGridHandler::getRequestArgs()
|
||||
*/
|
||||
public function getRequestArgs()
|
||||
{
|
||||
$stageId = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_WORKFLOW_STAGE);
|
||||
return array_merge(['stageId' => $stageId], parent::getRequestArgs());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
<?php
|
||||
/**
|
||||
* @file controllers/grid/files/review/ReviewCategoryGridDataProvider.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 ReviewCategoryGridDataProvider
|
||||
*
|
||||
* @ingroup controllers_grid_files_review
|
||||
*
|
||||
* @brief Provide access to review file data for category grids.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\files\review;
|
||||
|
||||
use PKP\controllers\grid\files\SubmissionFilesCategoryGridDataProvider;
|
||||
use PKP\submission\reviewRound\ReviewRound;
|
||||
|
||||
class ReviewCategoryGridDataProvider extends SubmissionFilesCategoryGridDataProvider
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param int $fileStage
|
||||
* @param int $viewableOnly Will be passed to the review grid data provider.
|
||||
* See parameter description there.
|
||||
*/
|
||||
public function __construct($fileStage, $viewableOnly = false)
|
||||
{
|
||||
parent::__construct($fileStage, ['viewableOnly' => $viewableOnly]);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Getters and setters.
|
||||
//
|
||||
/**
|
||||
* @return ReviewRound
|
||||
*/
|
||||
public function getReviewRound()
|
||||
{
|
||||
/** @var ReviewGridDataProvider */
|
||||
$gridDataProvider = $this->getDataProvider();
|
||||
return $gridDataProvider->getReviewRound();
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Overriden public methods from SubmissionFilesCategoryGridDataProvider
|
||||
//
|
||||
/**
|
||||
* @copydoc SubmissionFilesCategoryGridDataProvider::loadCategoryData()
|
||||
*
|
||||
* @param null|mixed $filter
|
||||
* @param null|mixed $reviewRound
|
||||
*/
|
||||
public function loadCategoryData($request, $categoryDataElement, $filter = null, $reviewRound = null)
|
||||
{
|
||||
$reviewRound = $this->getReviewRound();
|
||||
return parent::loadCategoryData($request, $categoryDataElement, $filter, $reviewRound);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc SubmissionFilesCategoryGridDataProvider::initGridDataProvider()
|
||||
*
|
||||
* @param null|mixed $initParams
|
||||
*/
|
||||
public function initGridDataProvider($fileStage, $initParams = null)
|
||||
{
|
||||
// This category grid data provider will use almost all the
|
||||
// same implementation of the ReviewGridDataProvider.
|
||||
$reviewFilesGridDataProvider = new ReviewGridDataProvider($fileStage);
|
||||
$reviewFilesGridDataProvider->setViewableOnly($initParams['viewableOnly']);
|
||||
|
||||
return $reviewFilesGridDataProvider;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Public methods
|
||||
//
|
||||
/**
|
||||
* @copydoc ReviewGridDataProvider::getSelectAction()
|
||||
*/
|
||||
public function getSelectAction($request)
|
||||
{
|
||||
/** @var ReviewGridDataProvider */
|
||||
$gridDataProvider = $this->getDataProvider();
|
||||
return $gridDataProvider->getSelectAction($request);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
<?php
|
||||
/**
|
||||
* @file controllers/grid/files/review/ReviewGridDataProvider.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 ReviewGridDataProvider
|
||||
*
|
||||
* @ingroup controllers_grid_files_review
|
||||
*
|
||||
* @brief Provide access to review file data for grids.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\files\review;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\facades\Repo;
|
||||
use PKP\controllers\api\file\linkAction\AddFileLinkAction;
|
||||
use PKP\controllers\grid\files\fileList\linkAction\SelectReviewFilesLinkAction;
|
||||
use PKP\controllers\grid\files\SubmissionFilesGridDataProvider;
|
||||
use PKP\security\authorization\internal\ReviewRoundRequiredPolicy;
|
||||
use PKP\submission\reviewRound\ReviewRound;
|
||||
|
||||
class ReviewGridDataProvider extends SubmissionFilesGridDataProvider
|
||||
{
|
||||
/** @var bool */
|
||||
protected $_showAll;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @copydoc SubmissionFilesGridDataProvider::__construct()
|
||||
*
|
||||
* @param bool $showAll True iff all review round files should be included.
|
||||
*/
|
||||
public function __construct($fileStageId, $viewableOnly = false, $showAll = false)
|
||||
{
|
||||
$this->_showAll = $showAll;
|
||||
parent::__construct($fileStageId, $viewableOnly);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Implement template methods from GridDataProvider
|
||||
//
|
||||
/**
|
||||
* @copydoc GridDataProvider::getAuthorizationPolicy()
|
||||
*/
|
||||
public function getAuthorizationPolicy($request, $args, $roleAssignments)
|
||||
{
|
||||
// Get the parent authorization policy.
|
||||
$policy = parent::getAuthorizationPolicy($request, $args, $roleAssignments);
|
||||
|
||||
// Add policy to ensure there is a review round id.
|
||||
$policy->addPolicy(new ReviewRoundRequiredPolicy($request, $args));
|
||||
|
||||
return $policy;
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridDataProvider::getRequestArgs()
|
||||
*/
|
||||
public function getRequestArgs()
|
||||
{
|
||||
$reviewRound = $this->getReviewRound();
|
||||
return array_merge(
|
||||
parent::getRequestArgs(),
|
||||
[
|
||||
'reviewRoundId' => $reviewRound->getId()
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridDataProvider::loadData()
|
||||
*/
|
||||
public function loadData($filter = [])
|
||||
{
|
||||
// Get all review files assigned to this submission.
|
||||
$collector = Repo::submissionFile()
|
||||
->getCollector()
|
||||
->filterBySubmissionIds([$this->getSubmission()->getId()])
|
||||
->filterByReviewRoundIds([$this->getReviewRound()->getId()]);
|
||||
|
||||
if (!$this->_showAll) {
|
||||
$collector = $collector->filterByFileStages([(int) $this->getFileStage()]);
|
||||
}
|
||||
|
||||
return $this->prepareSubmissionFileData($collector->getMany()->toArray(), $this->_viewableOnly, $filter);
|
||||
}
|
||||
|
||||
//
|
||||
// Overridden public methods from FilesGridDataProvider
|
||||
//
|
||||
/**
|
||||
* @copydoc FilesGridDataProvider::getSelectAction()
|
||||
*/
|
||||
public function getSelectAction($request)
|
||||
{
|
||||
$reviewRound = $this->getReviewRound();
|
||||
$modalTitle = __('editor.submission.review.currentFiles', ['round' => $reviewRound->getRound()]);
|
||||
return new SelectReviewFilesLinkAction(
|
||||
$request,
|
||||
$reviewRound,
|
||||
__('editor.submission.uploadSelectFiles'),
|
||||
$modalTitle
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc FilesGridDataProvider::getAddFileAction()
|
||||
*/
|
||||
public function getAddFileAction($request)
|
||||
{
|
||||
$submission = $this->getSubmission();
|
||||
$reviewRound = $this->getReviewRound();
|
||||
|
||||
return new AddFileLinkAction(
|
||||
$request,
|
||||
$submission->getId(),
|
||||
$this->getStageId(),
|
||||
$this->getUploaderRoles(),
|
||||
$this->getFileStage(),
|
||||
null,
|
||||
null,
|
||||
$reviewRound->getId()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the review round object.
|
||||
*
|
||||
* @return ReviewRound
|
||||
*/
|
||||
public function getReviewRound()
|
||||
{
|
||||
$reviewRound = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_REVIEW_ROUND);
|
||||
return $reviewRound;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
/**
|
||||
* @file controllers/grid/files/review/ReviewRevisionsGridDataProvider.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 ReviewRevisionsGridDataProvider
|
||||
*
|
||||
* @ingroup controllers_grid_files_review
|
||||
*
|
||||
* @brief Provide access to review revisions (new files added during a
|
||||
* review round) for grids.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\files\review;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\facades\Repo;
|
||||
use PKP\controllers\api\file\linkAction\AddRevisionLinkAction;
|
||||
use PKP\submissionFile\SubmissionFile;
|
||||
|
||||
class ReviewRevisionsGridDataProvider extends ReviewGridDataProvider
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$stageId = (int) Application::get()->getRequest()->getUserVar('stageId');
|
||||
$fileStage = $stageId === WORKFLOW_STAGE_ID_INTERNAL_REVIEW ? SubmissionFile::SUBMISSION_FILE_INTERNAL_REVIEW_REVISION : SubmissionFile::SUBMISSION_FILE_REVIEW_REVISION;
|
||||
parent::__construct($fileStage);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Implement template methods from GridDataProvider
|
||||
//
|
||||
/**
|
||||
* @copydoc GridDataProvider::loadData()
|
||||
*/
|
||||
public function loadData($filter = [])
|
||||
{
|
||||
// Grab the files that are new (incoming) revisions
|
||||
// of those currently assigned to the review round.
|
||||
$submissionFiles = Repo::submissionFile()
|
||||
->getCollector()
|
||||
->filterBySubmissionIds([$this->getSubmission()->getId()])
|
||||
->filterByReviewRoundIds([$this->getReviewRound()->getId()])
|
||||
->filterByFileStages([(int) $this->getFileStage()])
|
||||
->getMany()
|
||||
->toArray();
|
||||
|
||||
return $this->prepareSubmissionFileData($submissionFiles, false, $filter);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Overridden public methods from FilesGridDataProvider
|
||||
//
|
||||
/**
|
||||
* @copydoc FilesGridDataProvider::getAddFileAction()
|
||||
*/
|
||||
public function getAddFileAction($request)
|
||||
{
|
||||
$reviewRound = $this->getReviewRound();
|
||||
return new AddRevisionLinkAction(
|
||||
$request,
|
||||
$reviewRound,
|
||||
$this->getUploaderRoles()
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/files/review/ReviewerReviewFilesGridDataProvider.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 ReviewerReviewFilesGridDataProvider
|
||||
*
|
||||
* @ingroup controllers_grid_files_review
|
||||
*
|
||||
* @brief Provide reviewer access to review file data for review file grids.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\files\review;
|
||||
|
||||
use APP\core\Application;
|
||||
use PKP\db\DAORegistry;
|
||||
use PKP\security\authorization\internal\ReviewAssignmentRequiredPolicy;
|
||||
use PKP\security\authorization\internal\ReviewRoundRequiredPolicy;
|
||||
use PKP\security\authorization\internal\WorkflowStageRequiredPolicy;
|
||||
use PKP\security\authorization\SubmissionAccessPolicy;
|
||||
use PKP\submission\ReviewFilesDAO;
|
||||
use PKP\submissionFile\SubmissionFile;
|
||||
|
||||
class ReviewerReviewFilesGridDataProvider extends ReviewGridDataProvider
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$stageId = (int) Application::get()->getRequest()->getUserVar('stageId');
|
||||
$fileStage = $stageId === WORKFLOW_STAGE_ID_INTERNAL_REVIEW ? SubmissionFile::SUBMISSION_FILE_INTERNAL_REVIEW_FILE : SubmissionFile::SUBMISSION_FILE_REVIEW_FILE;
|
||||
parent::__construct($fileStage);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Implement template methods from GridDataProvider
|
||||
//
|
||||
/**
|
||||
* @see GridDataProvider::getAuthorizationPolicy()
|
||||
* Override the parent class, which defines a Workflow policy, to allow
|
||||
* reviewer access to this grid.
|
||||
*/
|
||||
public function getAuthorizationPolicy($request, $args, $roleAssignments)
|
||||
{
|
||||
$context = $request->getContext();
|
||||
$policy = new SubmissionAccessPolicy($request, $args, $roleAssignments, 'submissionId', !$context->getData('restrictReviewerFileAccess'));
|
||||
|
||||
$stageId = $request->getUserVar('stageId');
|
||||
$policy->addPolicy(new WorkflowStageRequiredPolicy($stageId));
|
||||
|
||||
// Add policy to ensure there is a review round id.
|
||||
$policy->addPolicy(new ReviewRoundRequiredPolicy($request, $args));
|
||||
|
||||
// Add policy to ensure there is a review assignment for certain operations.
|
||||
$policy->addPolicy(new ReviewAssignmentRequiredPolicy($request, $args, 'reviewAssignmentId'));
|
||||
|
||||
return $policy;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ReviewerReviewFilesGridDataProvider
|
||||
* Extend the parent class to filter out review round files that aren't allowed
|
||||
* for this reviewer according to ReviewFilesDAO.
|
||||
*
|
||||
* @param array $filter
|
||||
*/
|
||||
public function loadData($filter = [])
|
||||
{
|
||||
$submissionFileData = parent::loadData();
|
||||
$reviewFilesDao = DAORegistry::getDAO('ReviewFilesDAO'); /** @var ReviewFilesDAO $reviewFilesDao */
|
||||
$reviewAssignment = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_REVIEW_ASSIGNMENT);
|
||||
foreach ($submissionFileData as $submissionFileId => $fileData) {
|
||||
if (!$reviewFilesDao->check($reviewAssignment->getId(), $submissionFileId)) {
|
||||
// Not permitted; remove from list.
|
||||
unset($submissionFileData[$submissionFileId]);
|
||||
}
|
||||
}
|
||||
return $submissionFileData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridDataProvider::getRequestArgs()
|
||||
*/
|
||||
public function getRequestArgs()
|
||||
{
|
||||
$reviewAssignment = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_REVIEW_ASSIGNMENT);
|
||||
return array_merge(parent::getRequestArgs(), [
|
||||
'reviewAssignmentId' => $reviewAssignment->getId()
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/files/review/ReviewerReviewFilesGridHandler.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 ReviewerReviewFilesGridHandler
|
||||
*
|
||||
* @ingroup controllers_grid_files_review
|
||||
*
|
||||
* @brief Handle the reviewer review file grid (for reviewers to download files to review)
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\files\review;
|
||||
|
||||
use PKP\controllers\grid\files\fileList\FileListGridHandler;
|
||||
use PKP\security\Role;
|
||||
|
||||
class ReviewerReviewFilesGridHandler extends FileListGridHandler
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
// Pass in null stageId to be set in initialize from request var.
|
||||
parent::__construct(
|
||||
new ReviewerReviewFilesGridDataProvider(),
|
||||
null
|
||||
);
|
||||
|
||||
$this->addRoleAssignment(
|
||||
[Role::ROLE_ID_MANAGER, Role::ROLE_ID_SITE_ADMIN, Role::ROLE_ID_SUB_EDITOR, Role::ROLE_ID_ASSISTANT, Role::ROLE_ID_REVIEWER],
|
||||
['fetchGrid', 'fetchRow']
|
||||
);
|
||||
|
||||
// Set the grid title.
|
||||
$this->setTitle('reviewer.submission.reviewFiles');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/files/review/WorkflowReviewRevisionsGridHandler.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 WorkflowReviewRevisionsGridHandler
|
||||
*
|
||||
* @ingroup controllers_grid_files_review
|
||||
*
|
||||
* @brief Display in workflow pages the file revisions that authors have uploaded.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\files\review;
|
||||
|
||||
use APP\core\Application;
|
||||
use PKP\controllers\grid\files\fileList\FileListGridHandler;
|
||||
use PKP\controllers\grid\files\FilesGridCapabilities;
|
||||
use PKP\security\Role;
|
||||
use PKP\submissionFile\SubmissionFile;
|
||||
|
||||
class WorkflowReviewRevisionsGridHandler extends FileListGridHandler
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$stageId = (int) Application::get()->getRequest()->getUserVar('stageId');
|
||||
$fileStage = $stageId === WORKFLOW_STAGE_ID_INTERNAL_REVIEW ? SubmissionFile::SUBMISSION_FILE_INTERNAL_REVIEW_REVISION : SubmissionFile::SUBMISSION_FILE_REVIEW_REVISION;
|
||||
parent::__construct(
|
||||
new ReviewGridDataProvider($fileStage),
|
||||
null,
|
||||
FilesGridCapabilities::FILE_GRID_ADD | FilesGridCapabilities::FILE_GRID_EDIT | FilesGridCapabilities::FILE_GRID_VIEW_NOTES | FilesGridCapabilities::FILE_GRID_DELETE
|
||||
);
|
||||
|
||||
$this->addRoleAssignment(
|
||||
[Role::ROLE_ID_MANAGER, Role::ROLE_ID_SITE_ADMIN, Role::ROLE_ID_SUB_EDITOR, Role::ROLE_ID_ASSISTANT],
|
||||
['fetchGrid', 'fetchRow', 'addFile']
|
||||
);
|
||||
|
||||
$this->setTitle('editor.submission.revisions');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/files/review/form/ManageReviewFilesForm.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 ManageReviewFilesForm
|
||||
*
|
||||
* @ingroup controllers_grid_files_review_form
|
||||
*
|
||||
* @brief Form for add or removing files from a review
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\files\review\form;
|
||||
|
||||
use APP\facades\Repo;
|
||||
use PKP\controllers\grid\files\form\ManageSubmissionFilesForm;
|
||||
use PKP\db\DAORegistry;
|
||||
use PKP\submission\reviewRound\ReviewRound;
|
||||
use PKP\submission\reviewRound\ReviewRoundDAO;
|
||||
use PKP\submissionFile\SubmissionFile;
|
||||
|
||||
class ManageReviewFilesForm extends ManageSubmissionFilesForm
|
||||
{
|
||||
/** @var int */
|
||||
public $_stageId;
|
||||
|
||||
/** @var int */
|
||||
public $_reviewRoundId;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct($submissionId, $stageId, $reviewRoundId)
|
||||
{
|
||||
parent::__construct($submissionId, 'controllers/grid/files/review/manageReviewFiles.tpl');
|
||||
$this->_stageId = (int)$stageId;
|
||||
$this->_reviewRoundId = (int)$reviewRoundId;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Getters / Setters
|
||||
//
|
||||
/**
|
||||
* Get the review stage id
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getStageId()
|
||||
{
|
||||
return $this->_stageId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the round
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getReviewRoundId()
|
||||
{
|
||||
return $this->_reviewRoundId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ReviewRound
|
||||
*/
|
||||
public function getReviewRound()
|
||||
{
|
||||
$reviewRoundDao = DAORegistry::getDAO('ReviewRoundDAO'); /** @var ReviewRoundDAO $reviewRoundDao */
|
||||
return $reviewRoundDao->getById($this->getReviewRoundId());
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Overridden template methods
|
||||
//
|
||||
/**
|
||||
* @copydoc ManageSubmissionFilesForm::initData
|
||||
*/
|
||||
public function initData()
|
||||
{
|
||||
$this->setData('stageId', $this->getStageId());
|
||||
$this->setData('reviewRoundId', $this->getReviewRoundId());
|
||||
|
||||
$reviewRound = $this->getReviewRound();
|
||||
$this->setData('round', $reviewRound->getRound());
|
||||
|
||||
parent::initData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Save review round files
|
||||
*
|
||||
* @stageSubmissionFiles array The files that belongs to a file stage
|
||||
* that is currently being used by a grid inside this form.
|
||||
*
|
||||
* @param int $fileStage SubmissionFile::SUBMISSION_FILE_...
|
||||
* @param null|mixed $stageSubmissionFiles
|
||||
*/
|
||||
public function execute($stageSubmissionFiles = null, $fileStage = null, ...$functionArgs)
|
||||
{
|
||||
parent::execute(
|
||||
$stageSubmissionFiles,
|
||||
$this->getReviewRound()->getStageId() == WORKFLOW_STAGE_ID_INTERNAL_REVIEW ? SubmissionFile::SUBMISSION_FILE_INTERNAL_REVIEW_FILE : SubmissionFile::SUBMISSION_FILE_REVIEW_FILE
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc ManageSubmissionFilesForm::importFile()
|
||||
*/
|
||||
protected function importFile($submissionFile, $fileStage)
|
||||
{
|
||||
$newSubmissionFile = parent::importFile($submissionFile, $fileStage);
|
||||
|
||||
Repo::submissionFile()
|
||||
->dao
|
||||
->assignRevisionToReviewRound(
|
||||
$newSubmissionFile,
|
||||
$this->getReviewRound()
|
||||
);
|
||||
|
||||
return $newSubmissionFile;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/files/submission/AuthorSubmissionDetailsFilesGridHandler.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 AuthorSubmissionDetailsFilesGridHandler
|
||||
*
|
||||
* @ingroup controllers_grid_files_submission
|
||||
*
|
||||
* @brief Handle submission file grid requests on the author's submission details pages.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\files\submission;
|
||||
|
||||
use PKP\controllers\grid\files\fileList\FileListGridHandler;
|
||||
use PKP\controllers\grid\files\FilesGridCapabilities;
|
||||
use PKP\controllers\grid\files\SubmissionFilesGridDataProvider;
|
||||
use PKP\security\Role;
|
||||
use PKP\submissionFile\SubmissionFile;
|
||||
|
||||
class AuthorSubmissionDetailsFilesGridHandler extends FileListGridHandler
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$dataProvider = new SubmissionFilesGridDataProvider(SubmissionFile::SUBMISSION_FILE_SUBMISSION);
|
||||
parent::__construct($dataProvider, WORKFLOW_STAGE_ID_SUBMISSION, FilesGridCapabilities::FILE_GRID_DOWNLOAD_ALL | FilesGridCapabilities::FILE_GRID_EDIT);
|
||||
|
||||
$this->addRoleAssignment(
|
||||
[Role::ROLE_ID_MANAGER, Role::ROLE_ID_SITE_ADMIN, Role::ROLE_ID_SUB_EDITOR, Role::ROLE_ID_ASSISTANT, Role::ROLE_ID_AUTHOR],
|
||||
['fetchGrid', 'fetchRow']
|
||||
);
|
||||
|
||||
// Grid title.
|
||||
$this->setTitle('submission.submit.submissionFiles');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/files/submission/EditorSubmissionDetailsFilesGridHandler.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 EditorSubmissionDetailsFilesGridHandler
|
||||
*
|
||||
* @ingroup controllers_grid_files_submission
|
||||
*
|
||||
* @brief Handle submission file grid requests on the editor's submission details pages.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\files\submission;
|
||||
|
||||
use PKP\controllers\grid\files\fileList\FileListGridHandler;
|
||||
use PKP\controllers\grid\files\FilesGridCapabilities;
|
||||
use PKP\controllers\grid\files\SubmissionFilesGridDataProvider;
|
||||
use PKP\security\Role;
|
||||
use PKP\submissionFile\SubmissionFile;
|
||||
|
||||
class EditorSubmissionDetailsFilesGridHandler extends FileListGridHandler
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$dataProvider = new SubmissionFilesGridDataProvider(SubmissionFile::SUBMISSION_FILE_SUBMISSION);
|
||||
parent::__construct(
|
||||
$dataProvider,
|
||||
WORKFLOW_STAGE_ID_SUBMISSION,
|
||||
FilesGridCapabilities::FILE_GRID_ADD | FilesGridCapabilities::FILE_GRID_DELETE | FilesGridCapabilities::FILE_GRID_VIEW_NOTES | FilesGridCapabilities::FILE_GRID_DOWNLOAD_ALL | FilesGridCapabilities::FILE_GRID_EDIT
|
||||
);
|
||||
|
||||
$this->addRoleAssignment(
|
||||
[Role::ROLE_ID_MANAGER, Role::ROLE_ID_SITE_ADMIN, Role::ROLE_ID_SUB_EDITOR, Role::ROLE_ID_ASSISTANT, Role::ROLE_ID_AUTHOR],
|
||||
['fetchGrid', 'fetchRow']
|
||||
);
|
||||
|
||||
// Grid title.
|
||||
$this->setTitle('submission.submit.submissionFiles');
|
||||
}
|
||||
}
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
/**
|
||||
* @file controllers/grid/files/submissionDocuments/SubmissionDocumentsFilesGridDataProvider.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 SubmissionDocumentsFilesGridDataProvider
|
||||
*
|
||||
* @ingroup controllers_grid_files_submissionDocuments
|
||||
*
|
||||
* @brief The base data provider for the submission documents library files grid.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\files\submissionDocuments;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\submission\Submission;
|
||||
use PKP\context\LibraryFileDAO;
|
||||
use PKP\controllers\grid\CategoryGridDataProvider;
|
||||
use PKP\db\DAORegistry;
|
||||
use PKP\security\authorization\SubmissionAccessPolicy;
|
||||
|
||||
class SubmissionDocumentsFilesGridDataProvider extends CategoryGridDataProvider
|
||||
{
|
||||
/**
|
||||
* @copydoc GridDataProvider::getAuthorizationPolicy()
|
||||
*/
|
||||
public function getAuthorizationPolicy($request, $args, $roleAssignments)
|
||||
{
|
||||
return new SubmissionAccessPolicy($request, $args, $roleAssignments, 'submissionId');
|
||||
}
|
||||
|
||||
//
|
||||
// Getters and Setters
|
||||
//
|
||||
|
||||
/**
|
||||
* Get the authorized submission.
|
||||
*
|
||||
* @return Submission
|
||||
*/
|
||||
public function getSubmission()
|
||||
{
|
||||
return $this->getAuthorizedContextObject(Application::ASSOC_TYPE_SUBMISSION);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridDataProvider::getRequestArgs()
|
||||
*/
|
||||
public function getRequestArgs()
|
||||
{
|
||||
$submission = $this->getSubmission();
|
||||
return [
|
||||
'submissionId' => $submission->getId(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc CategoryGridHandler::loadCategoryData()
|
||||
*
|
||||
* @param null|mixed $filter
|
||||
*/
|
||||
public function loadCategoryData($request, $fileType, $filter = null)
|
||||
{
|
||||
// Retrieve all library files for the given submission document category.
|
||||
$submission = $this->getSubmission();
|
||||
$libraryFileDao = DAORegistry::getDAO('LibraryFileDAO'); /** @var LibraryFileDAO $libraryFileDao */
|
||||
$libraryFiles = $libraryFileDao->getBySubmissionId($submission->getId(), $fileType);
|
||||
|
||||
return $libraryFiles->toAssociativeArray();
|
||||
}
|
||||
}
|
||||
+174
@@ -0,0 +1,174 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/files/submissionDocuments/SubmissionDocumentsFilesGridHandler.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 SubmissionDocumentsFilesGridHandler
|
||||
*
|
||||
* @ingroup controllers_grid_files_submissionDocuments
|
||||
*
|
||||
* @brief Handle submission documents file grid requests.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\files\submissionDocuments;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\template\TemplateManager;
|
||||
use PKP\context\Context;
|
||||
use PKP\controllers\grid\files\LibraryFileGridHandler;
|
||||
use PKP\controllers\grid\files\LibraryFileGridRow;
|
||||
use PKP\controllers\grid\files\submissionDocuments\form\EditLibraryFileForm;
|
||||
use PKP\controllers\grid\files\submissionDocuments\form\NewLibraryFileForm;
|
||||
use PKP\core\JSONMessage;
|
||||
use PKP\core\PKPRequest;
|
||||
use PKP\linkAction\LinkAction;
|
||||
use PKP\linkAction\request\AjaxModal;
|
||||
use PKP\security\Role;
|
||||
|
||||
class SubmissionDocumentsFilesGridHandler extends LibraryFileGridHandler
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(new SubmissionDocumentsFilesGridDataProvider());
|
||||
$this->addRoleAssignment(
|
||||
[Role::ROLE_ID_MANAGER, Role::ROLE_ID_SITE_ADMIN, Role::ROLE_ID_SUB_EDITOR, Role::ROLE_ID_ASSISTANT, Role::ROLE_ID_AUTHOR],
|
||||
[
|
||||
'addFile', 'uploadFile', 'saveFile', // Adding new library files
|
||||
'editFile', 'updateFile', // Editing existing library files
|
||||
'deleteFile', 'viewLibrary'
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Overridden template methods
|
||||
//
|
||||
/**
|
||||
* Configure the grid
|
||||
*
|
||||
* @see LibraryFileGridHandler::initialize
|
||||
*
|
||||
* @param null|mixed $args
|
||||
*/
|
||||
public function initialize($request, $args = null)
|
||||
{
|
||||
$this->setCanEdit(true); // this grid can always be edited.
|
||||
parent::initialize($request, $args);
|
||||
|
||||
$this->setTitle(null);
|
||||
|
||||
$router = $request->getRouter();
|
||||
|
||||
// Add grid-level actions
|
||||
|
||||
if ($this->canEdit()) {
|
||||
$this->addAction(
|
||||
new LinkAction(
|
||||
'addFile',
|
||||
new AjaxModal(
|
||||
$router->url($request, null, null, 'addFile', null, $this->getActionArgs()),
|
||||
__('grid.action.addFile'),
|
||||
'modal_add_file'
|
||||
),
|
||||
__('grid.action.addFile'),
|
||||
'add'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$this->addAction(
|
||||
new LinkAction(
|
||||
'viewLibrary',
|
||||
new AjaxModal(
|
||||
$router->url($request, null, null, 'viewLibrary', null, $this->getActionArgs()),
|
||||
__('grid.action.viewLibrary'),
|
||||
'modal_information'
|
||||
),
|
||||
__('grid.action.viewLibrary'),
|
||||
'more_info'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the arguments for the 'add file' action.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getActionArgs()
|
||||
{
|
||||
$submission = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_SUBMISSION);
|
||||
$actionArgs = [
|
||||
'submissionId' => $submission->getId(),
|
||||
];
|
||||
|
||||
return $actionArgs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the row handler - override the default row handler
|
||||
*
|
||||
* @return LibraryFileGridRow
|
||||
*/
|
||||
protected function getRowInstance()
|
||||
{
|
||||
$submission = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_SUBMISSION);
|
||||
return new LibraryFileGridRow($this->canEdit(), $submission);
|
||||
}
|
||||
|
||||
//
|
||||
// Public File Grid Actions
|
||||
//
|
||||
|
||||
/**
|
||||
* Load the (read only) context file library.
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function viewLibrary($args, $request)
|
||||
{
|
||||
$templateMgr = TemplateManager::getManager($request);
|
||||
$templateMgr->assign('isModal', true);
|
||||
$userRoles = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_USER_ROLES);
|
||||
$templateMgr->assign('canEdit', !empty(array_intersect([Role::ROLE_ID_MANAGER, Role::ROLE_ID_SITE_ADMIN], $userRoles)));
|
||||
return $templateMgr->fetchJson('controllers/modals/documentLibrary/publisherLibrary.tpl');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a specific instance of the new form for this grid.
|
||||
*
|
||||
* @param Context $context
|
||||
*
|
||||
* @return NewLibraryFileForm
|
||||
*/
|
||||
public function _getNewFileForm($context)
|
||||
{
|
||||
$submission = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_SUBMISSION);
|
||||
return new NewLibraryFileForm($context->getId(), $submission->getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a specific instance of the edit form for this grid.
|
||||
*
|
||||
* @param Context $context
|
||||
* @param int $fileId
|
||||
*
|
||||
* @return EditLibraryFileForm
|
||||
*/
|
||||
public function _getEditFileForm($context, $fileId)
|
||||
{
|
||||
$submission = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_SUBMISSION);
|
||||
return new EditLibraryFileForm($context->getId(), $fileId, $submission->getId());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/files/submissionDocuments/form/EditLibraryFileForm.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 EditLibraryFileForm
|
||||
*
|
||||
* @ingroup controllers_grid_files_submissionDocuments_form
|
||||
*
|
||||
* @brief Form for editing a library file
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\files\submissionDocuments\form;
|
||||
|
||||
use PKP\context\LibraryFile;
|
||||
use PKP\context\LibraryFileDAO;
|
||||
use PKP\controllers\grid\files\form\LibraryFileForm;
|
||||
use PKP\db\DAORegistry;
|
||||
|
||||
class EditLibraryFileForm extends LibraryFileForm
|
||||
{
|
||||
/** @var LibraryFile the file being edited, or null for new */
|
||||
public $libraryFile;
|
||||
|
||||
/** @var int the id of the submission for this library file */
|
||||
public $submissionId;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param int $contextId
|
||||
* @param int $fileId optional
|
||||
*/
|
||||
public function __construct($contextId, $fileId, $submissionId)
|
||||
{
|
||||
parent::__construct('controllers/grid/files/submissionDocuments/form/editFileForm.tpl', $contextId);
|
||||
|
||||
$this->submissionId = $submissionId;
|
||||
$libraryFileDao = DAORegistry::getDAO('LibraryFileDAO'); /** @var LibraryFileDAO $libraryFileDao */
|
||||
$this->libraryFile = $libraryFileDao->getById($fileId);
|
||||
|
||||
if (!$this->libraryFile || $this->libraryFile->getContextId() != $this->contextId || $this->libraryFile->getSubmissionId() != $this->getSubmissionId()) {
|
||||
fatalError('Invalid library file!');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize form data from current settings.
|
||||
*/
|
||||
public function initData()
|
||||
{
|
||||
$this->_data = [
|
||||
'submissionId' => $this->libraryFile->getSubmissionId(),
|
||||
'libraryFileName' => $this->libraryFile->getName(null), // Localized
|
||||
'libraryFile' => $this->libraryFile // For read-only info
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::execute()
|
||||
*/
|
||||
public function execute(...$functionArgs)
|
||||
{
|
||||
$this->libraryFile->setName($this->getData('libraryFileName'), null); // Localized
|
||||
$this->libraryFile->setType($this->getData('fileType'));
|
||||
|
||||
$libraryFileDao = DAORegistry::getDAO('LibraryFileDAO'); /** @var LibraryFileDAO $libraryFileDao */
|
||||
$libraryFileDao->updateObject($this->libraryFile);
|
||||
|
||||
parent::execute(...$functionArgs);
|
||||
}
|
||||
|
||||
/**
|
||||
* return the submission ID for this library file.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getSubmissionId()
|
||||
{
|
||||
return $this->submissionId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
<?php
|
||||
/**
|
||||
* @file controllers/grid/files/submissionDocuments/form/NewLibraryFileForm.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 NewLibraryFileForm
|
||||
*
|
||||
* @ingroup controllers_grid_files_submissionDocuments_form
|
||||
*
|
||||
* @brief Form for adding/editing a file
|
||||
* stores/retrieves from an associative array
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\files\submissionDocuments\form;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\file\LibraryFileManager;
|
||||
use APP\template\TemplateManager;
|
||||
use PKP\context\LibraryFileDAO;
|
||||
use PKP\controllers\grid\files\form\LibraryFileForm;
|
||||
use PKP\db\DAORegistry;
|
||||
use PKP\file\TemporaryFileDAO;
|
||||
use PKP\file\TemporaryFileManager;
|
||||
|
||||
class NewLibraryFileForm extends LibraryFileForm
|
||||
{
|
||||
/** @var int */
|
||||
public $submissionId;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param int $contextId
|
||||
*/
|
||||
public function __construct($contextId, $submissionId)
|
||||
{
|
||||
parent::__construct('controllers/grid/files/submissionDocuments/form/newFileForm.tpl', $contextId);
|
||||
$this->submissionId = $submissionId;
|
||||
$this->addCheck(new \PKP\form\validation\FormValidator($this, 'temporaryFileId', 'required', 'settings.libraryFiles.fileRequired'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign form data to user-submitted data.
|
||||
*
|
||||
* @copydoc Form::readInputData()
|
||||
*/
|
||||
public function readInputData()
|
||||
{
|
||||
$this->readUserVars(['temporaryFileId', 'submissionId']);
|
||||
return parent::readInputData();
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc LibraryFileForm::fetch()
|
||||
*
|
||||
* @param null|mixed $template
|
||||
*/
|
||||
public function fetch($request, $template = null, $display = false)
|
||||
{
|
||||
$templateMgr = TemplateManager::getManager($request);
|
||||
$templateMgr->assign('submissionId', $this->getSubmissionId());
|
||||
return parent::fetch($request, $template, $display);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::execute()
|
||||
*
|
||||
* @return $fileId int The new library file id.
|
||||
*/
|
||||
public function execute(...$functionArgs)
|
||||
{
|
||||
$userId = Application::get()->getRequest()->getUser()->getId();
|
||||
|
||||
// Fetch the temporary file storing the uploaded library file
|
||||
$temporaryFileDao = DAORegistry::getDAO('TemporaryFileDAO'); /** @var TemporaryFileDAO $temporaryFileDao */
|
||||
$temporaryFile = $temporaryFileDao->getTemporaryFile(
|
||||
$this->getData('temporaryFileId'),
|
||||
$userId
|
||||
);
|
||||
$libraryFileDao = DAORegistry::getDAO('LibraryFileDAO'); /** @var LibraryFileDAO $libraryFileDao */
|
||||
$libraryFileManager = new LibraryFileManager($this->contextId);
|
||||
|
||||
// Convert the temporary file to a library file and store
|
||||
$libraryFile = & $libraryFileManager->copyFromTemporaryFile($temporaryFile, $this->getData('fileType'));
|
||||
assert(isset($libraryFile));
|
||||
$libraryFile->setContextId($this->contextId);
|
||||
$libraryFile->setName($this->getData('libraryFileName'), null); // Localized
|
||||
$libraryFile->setType($this->getData('fileType'));
|
||||
$libraryFile->setSubmissionId($this->getData('submissionId'));
|
||||
|
||||
$fileId = $libraryFileDao->insertObject($libraryFile);
|
||||
|
||||
// Clean up the temporary file
|
||||
$temporaryFileManager = new TemporaryFileManager();
|
||||
$temporaryFileManager->deleteById($this->getData('temporaryFileId'), $userId);
|
||||
|
||||
parent::execute(...$functionArgs);
|
||||
|
||||
return $fileId;
|
||||
}
|
||||
|
||||
/**
|
||||
* return the submission ID for this library file.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getSubmissionId()
|
||||
{
|
||||
return $this->submissionId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/languages/LanguageGridCellProvider.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 LanguageGridCellProvider
|
||||
*
|
||||
* @ingroup controllers_grid_languages
|
||||
*
|
||||
* @brief Subclass for a language grid column's cell provider
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\languages;
|
||||
|
||||
use PKP\controllers\grid\GridCellProvider;
|
||||
use PKP\controllers\grid\GridHandler;
|
||||
use PKP\linkAction\LinkAction;
|
||||
use PKP\linkAction\request\AjaxAction;
|
||||
use PKP\linkAction\request\RemoteActionConfirmationModal;
|
||||
|
||||
class LanguageGridCellProvider extends GridCellProvider
|
||||
{
|
||||
/**
|
||||
* @copydoc GridCellProvider::getTemplateVarsFromRowColumn()
|
||||
*/
|
||||
public function getTemplateVarsFromRowColumn($row, $column)
|
||||
{
|
||||
$element = $row->getData();
|
||||
$columnId = $column->getId();
|
||||
|
||||
switch ($columnId) {
|
||||
case 'enable':
|
||||
return ['selected' => $element['supported'],
|
||||
'disabled' => false];
|
||||
case 'locale':
|
||||
$label = $element['name'];
|
||||
$returnArray = ['label' => $label];
|
||||
if (isset($element['incomplete'])) {
|
||||
$returnArray['incomplete'] = $element['incomplete'];
|
||||
}
|
||||
return $returnArray;
|
||||
case 'code':
|
||||
$label = $element['code'];
|
||||
$returnArray = ['label' => $label];
|
||||
return $returnArray;
|
||||
case 'sitePrimary':
|
||||
return ['selected' => $element['primary'],
|
||||
'disabled' => !$element['supported']];
|
||||
case 'contextPrimary':
|
||||
return ['selected' => $element['primary'],
|
||||
'disabled' => !$element['supported']];
|
||||
case 'uiLocale':
|
||||
return ['selected' => $element['supportedLocales'],
|
||||
'disabled' => !$element['supported']];
|
||||
case 'formLocale':
|
||||
return ['selected' => $element['supportedFormLocales'],
|
||||
'disabled' => !$element['supported']];
|
||||
case 'submissionLocale':
|
||||
return ['selected' => $element['supportedSubmissionLocales'],
|
||||
'disabled' => !$element['supported']];
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridCellProvider::getCellActions()
|
||||
*/
|
||||
public function getCellActions($request, $row, $column, $position = GridHandler::GRID_ACTION_POSITION_DEFAULT)
|
||||
{
|
||||
$element = $row->getData();
|
||||
$router = $request->getRouter();
|
||||
$actions = [];
|
||||
$actionArgs = ['rowId' => $row->getId()];
|
||||
|
||||
$action = null;
|
||||
$actionRequest = null;
|
||||
|
||||
switch ($column->getId()) {
|
||||
case 'enable':
|
||||
$enabled = $element['supported'];
|
||||
if ($enabled) {
|
||||
$action = 'disable-' . $row->getId();
|
||||
$actionRequest = new RemoteActionConfirmationModal(
|
||||
$request->getSession(),
|
||||
__('admin.languages.confirmDisable'),
|
||||
__('common.disable'),
|
||||
$router->url($request, null, null, 'disableLocale', null, $actionArgs)
|
||||
);
|
||||
} else {
|
||||
$action = 'enable-' . $row->getId();
|
||||
$actionRequest = new AjaxAction($router->url($request, null, null, 'enableLocale', null, $actionArgs));
|
||||
}
|
||||
break;
|
||||
case 'sitePrimary':
|
||||
$primary = $element['primary'];
|
||||
if (!$primary) {
|
||||
$action = 'setPrimary-' . $row->getId();
|
||||
$actionRequest = new RemoteActionConfirmationModal(
|
||||
$request->getSession(),
|
||||
__('admin.languages.confirmSitePrimaryLocaleChange'),
|
||||
__('locale.primary'),
|
||||
$router->url($request, null, null, 'setPrimaryLocale', null, $actionArgs)
|
||||
);
|
||||
}
|
||||
break;
|
||||
case 'contextPrimary':
|
||||
$primary = $element['primary'];
|
||||
if (!$primary) {
|
||||
$action = 'setPrimary-' . $row->getId();
|
||||
$actionRequest = new AjaxAction($router->url($request, null, null, 'setContextPrimaryLocale', null, $actionArgs));
|
||||
}
|
||||
break;
|
||||
case 'uiLocale':
|
||||
$action = 'setUiLocale-' . $row->getId();
|
||||
$actionArgs['setting'] = 'supportedLocales';
|
||||
$actionArgs['value'] = !$element['supportedLocales'];
|
||||
$actionRequest = new AjaxAction($router->url($request, null, null, 'saveLanguageSetting', null, $actionArgs));
|
||||
break;
|
||||
case 'formLocale':
|
||||
$action = 'setFormLocale-' . $row->getId();
|
||||
$actionArgs['setting'] = 'supportedFormLocales';
|
||||
$actionArgs['value'] = !$element['supportedFormLocales'];
|
||||
$actionRequest = new AjaxAction($router->url($request, null, null, 'saveLanguageSetting', null, $actionArgs));
|
||||
break;
|
||||
case 'submissionLocale':
|
||||
$action = 'setSubmissionLocale-' . $row->getId();
|
||||
$actionArgs['setting'] = 'supportedSubmissionLocales';
|
||||
$actionArgs['value'] = !$element['supportedSubmissionLocales'];
|
||||
$actionRequest = new AjaxAction($router->url($request, null, null, 'saveLanguageSetting', null, $actionArgs));
|
||||
break;
|
||||
}
|
||||
|
||||
if ($action && $actionRequest) {
|
||||
$linkAction = new LinkAction($action, $actionRequest, null, null);
|
||||
$actions = [$linkAction];
|
||||
}
|
||||
|
||||
return $actions;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,348 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/languages/LanguageGridHandler.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 LanguageGridHandler
|
||||
*
|
||||
* @ingroup classes_controllers_grid_languages
|
||||
*
|
||||
* @brief Handle language grid requests.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\languages;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\core\Request;
|
||||
use APP\core\Services;
|
||||
use APP\notification\NotificationManager;
|
||||
use PKP\controllers\grid\GridColumn;
|
||||
use PKP\controllers\grid\GridHandler;
|
||||
use PKP\core\JSONMessage;
|
||||
use PKP\facades\Locale;
|
||||
use PKP\notification\PKPNotification;
|
||||
use PKP\security\Role;
|
||||
|
||||
class LanguageGridHandler extends GridHandler
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->addRoleAssignment(
|
||||
[Role::ROLE_ID_MANAGER, Role::ROLE_ID_SITE_ADMIN],
|
||||
['saveLanguageSetting', 'setContextPrimaryLocale']
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Implement template methods from PKPHandler.
|
||||
//
|
||||
/**
|
||||
* @copydoc GridHandler::initialize()
|
||||
*
|
||||
* @param null|mixed $args
|
||||
*/
|
||||
public function initialize($request, $args = null)
|
||||
{
|
||||
parent::initialize($request, $args);
|
||||
|
||||
// Basic grid configuration.
|
||||
$this->setTitle('common.languages');
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::getRowInstance()
|
||||
*/
|
||||
protected function getRowInstance()
|
||||
{
|
||||
return new LanguageGridRow();
|
||||
}
|
||||
|
||||
//
|
||||
// Public handler methods.
|
||||
//
|
||||
/**
|
||||
* Save language management settings.
|
||||
*
|
||||
* @param array $args
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JSONMessage JSON message
|
||||
*/
|
||||
public function saveLanguageSetting($args, $request)
|
||||
{
|
||||
if (!$request->checkCSRF()) {
|
||||
return new JSONMessage(false);
|
||||
}
|
||||
$locale = (string) $request->getUserVar('rowId');
|
||||
$settingName = (string) $request->getUserVar('setting');
|
||||
$settingValue = (bool) $request->getUserVar('value');
|
||||
$availableLocales = $this->getGridDataElements($request);
|
||||
$context = $request->getContext();
|
||||
|
||||
$contextService = Services::get('context');
|
||||
|
||||
$permittedSettings = ['supportedFormLocales', 'supportedSubmissionLocales', 'supportedLocales'];
|
||||
if (in_array($settingName, $permittedSettings) && $locale) {
|
||||
$currentSettingValue = (array) $context->getData($settingName);
|
||||
if (Locale::isLocaleValid($locale) && array_key_exists($locale, $availableLocales)) {
|
||||
if ($settingValue) {
|
||||
array_push($currentSettingValue, $locale);
|
||||
if ($settingName == 'supportedFormLocales') {
|
||||
// reload localized default context settings
|
||||
$contextService->restoreLocaleDefaults($context, $request, $locale);
|
||||
} elseif ($settingName == 'supportedSubmissionLocales') {
|
||||
// if a submission locale is enabled, and this locale is not in the form locales, add it
|
||||
$supportedFormLocales = (array) $context->getData('supportedFormLocales');
|
||||
if (!in_array($locale, $supportedFormLocales)) {
|
||||
array_push($supportedFormLocales, $locale);
|
||||
$context = $contextService->edit($context, ['supportedFormLocales' => $supportedFormLocales], $request);
|
||||
// reload localized default context settings
|
||||
$contextService->restoreLocaleDefaults($context, $request, $locale);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$key = array_search($locale, $currentSettingValue);
|
||||
if ($key !== false) {
|
||||
unset($currentSettingValue[$key]);
|
||||
}
|
||||
|
||||
if ($currentSettingValue === []) {
|
||||
return new JSONMessage(false, __('notification.localeSettingsCannotBeSaved'));
|
||||
}
|
||||
|
||||
if ($settingName == 'supportedFormLocales') {
|
||||
// if a form locale is disabled, disable it form submission locales as well
|
||||
$supportedSubmissionLocales = (array) $context->getData('supportedSubmissionLocales');
|
||||
$key = array_search($locale, $supportedSubmissionLocales);
|
||||
if ($key !== false) {
|
||||
unset($supportedSubmissionLocales[$key]);
|
||||
}
|
||||
$supportedSubmissionLocales = array_values($supportedSubmissionLocales);
|
||||
if ($supportedSubmissionLocales == []) {
|
||||
return new JSONMessage(false, __('notification.localeSettingsCannotBeSaved'));
|
||||
}
|
||||
$context = $contextService->edit($context, ['supportedSubmissionLocales' => $supportedSubmissionLocales], $request);
|
||||
}
|
||||
|
||||
if ($settingName == 'supportedSubmissionLocales') {
|
||||
// If someone tried to disable all submissions checkboxes, we should display an error message.
|
||||
$supportedSubmissionLocales = (array) $context->getData('supportedSubmissionLocales');
|
||||
$key = array_search($locale, $supportedSubmissionLocales);
|
||||
if ($key !== false) {
|
||||
unset($supportedSubmissionLocales[$key]);
|
||||
}
|
||||
$supportedSubmissionLocales = array_values($supportedSubmissionLocales);
|
||||
if ($supportedSubmissionLocales == []) {
|
||||
return new JSONMessage(false, __('notification.localeSettingsCannotBeSaved'));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$context = $contextService->edit($context, [$settingName => array_values(array_unique($currentSettingValue))], $request);
|
||||
|
||||
$notificationManager = new NotificationManager();
|
||||
$user = $request->getUser();
|
||||
$notificationManager->createTrivialNotification(
|
||||
$user->getId(),
|
||||
PKPNotification::NOTIFICATION_TYPE_SUCCESS,
|
||||
['contents' => __('notification.localeSettingsSaved')]
|
||||
);
|
||||
|
||||
$locales = $context->getSupportedFormLocaleNames();
|
||||
$locales = array_map(fn (string $locale, string $name) => ['key' => $locale, 'label' => $name], array_keys($locales), $locales);
|
||||
|
||||
$json = \PKP\db\DAO::getDataChangedEvent($locale);
|
||||
$json->setGlobalEvent('set-form-languages', $locales);
|
||||
return $json;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set context primary locale.
|
||||
*
|
||||
* @param array $args
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function setContextPrimaryLocale($args, $request)
|
||||
{
|
||||
if (!$request->checkCSRF()) {
|
||||
return new JSONMessage(false);
|
||||
}
|
||||
$locale = (string) $request->getUserVar('rowId');
|
||||
$context = $request->getContext();
|
||||
$availableLocales = $this->getGridDataElements($request);
|
||||
|
||||
if (Locale::isLocaleValid($locale) && array_key_exists($locale, $availableLocales)) {
|
||||
// Make sure at least the primary locale is chosen as available
|
||||
foreach (['supportedLocales', 'supportedSubmissionLocales', 'supportedFormLocales'] as $name) {
|
||||
$$name = $context->getData($name);
|
||||
if (!in_array($locale, $$name)) {
|
||||
array_push($$name, $locale);
|
||||
$context->updateSetting($name, $$name);
|
||||
}
|
||||
}
|
||||
|
||||
$context->setPrimaryLocale($locale);
|
||||
$contextDao = Application::getContextDAO();
|
||||
$contextDao->updateObject($context);
|
||||
|
||||
$notificationManager = new NotificationManager();
|
||||
$user = $request->getUser();
|
||||
$notificationManager->createTrivialNotification(
|
||||
$user->getId(),
|
||||
PKPNotification::NOTIFICATION_TYPE_SUCCESS,
|
||||
['contents' => __('notification.localeSettingsSaved')]
|
||||
);
|
||||
}
|
||||
|
||||
return \PKP\db\DAO::getDataChangedEvent();
|
||||
}
|
||||
|
||||
//
|
||||
// Protected methods.
|
||||
//
|
||||
/**
|
||||
* Return an instance of the cell provider
|
||||
* used by this grid.
|
||||
*
|
||||
* @return LanguageGridCellProvider
|
||||
*/
|
||||
public function getCellProvider()
|
||||
{
|
||||
return new LanguageGridCellProvider();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add name column.
|
||||
*/
|
||||
public function addNameColumn()
|
||||
{
|
||||
$cellProvider = $this->getCellProvider();
|
||||
|
||||
// Locale name.
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'locale',
|
||||
'grid.columns.locale',
|
||||
null,
|
||||
'controllers/grid/languages/localeNameCell.tpl',
|
||||
$cellProvider
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add locale code column.
|
||||
*/
|
||||
public function addLocaleCodeColumn()
|
||||
{
|
||||
$cellProvider = $this->getCellProvider();
|
||||
|
||||
// Locale code.
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'code',
|
||||
'grid.columns.locale.code',
|
||||
null,
|
||||
null,
|
||||
$cellProvider
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add primary column.
|
||||
*
|
||||
* @param string $columnId The column id.
|
||||
*/
|
||||
public function addPrimaryColumn($columnId)
|
||||
{
|
||||
$cellProvider = $this->getCellProvider();
|
||||
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
$columnId,
|
||||
'locale.primary',
|
||||
null,
|
||||
'controllers/grid/common/cell/radioButtonCell.tpl',
|
||||
$cellProvider
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add columns related to management settings.
|
||||
*/
|
||||
public function addManagementColumns()
|
||||
{
|
||||
$cellProvider = $this->getCellProvider();
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'uiLocale',
|
||||
'manager.language.ui',
|
||||
null,
|
||||
'controllers/grid/common/cell/selectStatusCell.tpl',
|
||||
$cellProvider
|
||||
)
|
||||
);
|
||||
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'formLocale',
|
||||
'manager.language.forms',
|
||||
null,
|
||||
'controllers/grid/common/cell/selectStatusCell.tpl',
|
||||
$cellProvider
|
||||
)
|
||||
);
|
||||
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'submissionLocale',
|
||||
'manager.language.submissions',
|
||||
null,
|
||||
'controllers/grid/common/cell/selectStatusCell.tpl',
|
||||
$cellProvider
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add data related to management settings.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param array $data Data already loaded.
|
||||
*
|
||||
* @return array Same passed array, but with
|
||||
* the extra management data inserted.
|
||||
*/
|
||||
public function addManagementData($request, $data)
|
||||
{
|
||||
$context = $request->getContext();
|
||||
|
||||
if (is_array($data)) {
|
||||
foreach ($data as $locale => $localeData) {
|
||||
foreach (['supportedFormLocales', 'supportedSubmissionLocales', 'supportedLocales'] as $name) {
|
||||
$data[$locale][$name] = in_array($locale, $context->getData($name));
|
||||
// $data[$locale][$name] = in_array($locale, (array) $context->getData($name));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
assert(false);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/languages/LanguageGridRow.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 LanguageGridRow
|
||||
*
|
||||
* @ingroup controllers_grid_languages
|
||||
*
|
||||
* @brief Language grid row definition
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\languages;
|
||||
|
||||
use PKP\controllers\grid\GridRow;
|
||||
use PKP\linkAction\LinkAction;
|
||||
use PKP\linkAction\request\RemoteActionConfirmationModal;
|
||||
use PKP\security\Validation;
|
||||
|
||||
class LanguageGridRow extends GridRow
|
||||
{
|
||||
//
|
||||
// Overridden methods from GridRow
|
||||
//
|
||||
/**
|
||||
* @copydoc GridRow::initialize()
|
||||
*
|
||||
* @param null|mixed $template
|
||||
*/
|
||||
public function initialize($request, $template = null)
|
||||
{
|
||||
parent::initialize($request, $template);
|
||||
|
||||
// Is this a new row or an existing row?
|
||||
$rowId = $this->getId();
|
||||
$rowData = $this->getData();
|
||||
|
||||
if (!empty($rowId)) {
|
||||
// Only add row actions if this is an existing row
|
||||
$router = $request->getRouter();
|
||||
$actionArgs = [
|
||||
'gridId' => $this->getGridId(),
|
||||
'rowId' => $rowId
|
||||
];
|
||||
|
||||
if (Validation::isSiteAdmin()) {
|
||||
if (!$request->getContext() && !$rowData['primary']) {
|
||||
$this->addAction(
|
||||
new LinkAction(
|
||||
'uninstall',
|
||||
new RemoteActionConfirmationModal(
|
||||
$request->getSession(),
|
||||
__('admin.languages.confirmUninstall'),
|
||||
__('grid.action.remove'),
|
||||
$router->url($request, null, null, 'uninstallLocale', null, $actionArgs)
|
||||
),
|
||||
__('grid.action.remove'),
|
||||
'delete'
|
||||
)
|
||||
);
|
||||
}
|
||||
if ($request->getContext()) {
|
||||
$this->addAction(
|
||||
new LinkAction(
|
||||
'reload',
|
||||
new RemoteActionConfirmationModal(
|
||||
$request->getSession(),
|
||||
__('manager.language.confirmDefaultSettingsOverwrite'),
|
||||
__('manager.language.reloadLocalizedDefaultSettings'),
|
||||
$router->url($request, null, null, 'reloadLocale', null, $actionArgs)
|
||||
),
|
||||
__('manager.language.reloadLocalizedDefaultSettings')
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/languages/form/InstallLanguageForm.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 InstallLanguageForm
|
||||
*
|
||||
* @ingroup controllers_grid_languages_form
|
||||
*
|
||||
* @brief Form for installing languages.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\languages\form;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\template\TemplateManager;
|
||||
use PKP\db\DAORegistry;
|
||||
use PKP\facades\Locale;
|
||||
use PKP\form\Form;
|
||||
use PKP\i18n\LocaleMetadata;
|
||||
use PKP\site\SiteDAO;
|
||||
|
||||
class InstallLanguageForm extends Form
|
||||
{
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct('controllers/grid/languages/installLanguageForm.tpl');
|
||||
}
|
||||
|
||||
//
|
||||
// Overridden methods from Form.
|
||||
//
|
||||
/**
|
||||
* @copydoc Form::initData()
|
||||
*/
|
||||
public function initData()
|
||||
{
|
||||
parent::initData();
|
||||
|
||||
$request = Application::get()->getRequest();
|
||||
$site = $request->getSite();
|
||||
$this->setData('installedLocales', $site->getInstalledLocales());
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::fetch()
|
||||
*
|
||||
* @param null|mixed $template
|
||||
*/
|
||||
public function fetch($request, $template = null, $display = false)
|
||||
{
|
||||
$allLocales = Locale::getFormattedDisplayNames(null, null, LocaleMetadata::LANGUAGE_LOCALE_WITH, false);
|
||||
$installedLocales = $this->getData('installedLocales');
|
||||
$notInstalledLocales = array_diff(array_keys($allLocales), $installedLocales);
|
||||
|
||||
$templateMgr = TemplateManager::getManager($request);
|
||||
$templateMgr->assign([
|
||||
'allLocales' => $allLocales,
|
||||
'notInstalledLocales' => $notInstalledLocales,
|
||||
]);
|
||||
|
||||
return parent::fetch($request, $template, $display);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::readInputData()
|
||||
*/
|
||||
public function readInputData()
|
||||
{
|
||||
parent::readInputData();
|
||||
|
||||
$request = Application::get()->getRequest();
|
||||
$localesToInstall = $request->getUserVar('localesToInstall');
|
||||
$this->setData('localesToInstall', $localesToInstall);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::execute()
|
||||
*/
|
||||
public function execute(...$functionArgs)
|
||||
{
|
||||
$request = Application::get()->getRequest();
|
||||
$site = $request->getSite();
|
||||
$localesToInstall = $this->getData('localesToInstall');
|
||||
|
||||
parent::execute(...$functionArgs);
|
||||
|
||||
if (isset($localesToInstall) && is_array($localesToInstall)) {
|
||||
$installedLocales = $site->getInstalledLocales();
|
||||
$supportedLocales = $site->getSupportedLocales();
|
||||
|
||||
foreach ($localesToInstall as $locale) {
|
||||
if (Locale::isLocaleValid($locale) && !in_array($locale, $installedLocales)) {
|
||||
array_push($installedLocales, $locale);
|
||||
// Activate/support by default.
|
||||
if (!in_array($locale, $supportedLocales)) {
|
||||
array_push($supportedLocales, $locale);
|
||||
}
|
||||
Locale::installLocale($locale);
|
||||
}
|
||||
}
|
||||
|
||||
$site->setInstalledLocales($installedLocales);
|
||||
$site->setSupportedLocales($supportedLocales);
|
||||
$siteDao = DAORegistry::getDAO('SiteDAO'); /** @var SiteDAO $siteDao */
|
||||
$siteDao->updateObject($site);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/navigationMenus/NavigationMenuItemsCellProvider.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 NavigationMenuItemsGridCellProvider
|
||||
*
|
||||
* @ingroup controllers_grid_navigationMenus
|
||||
*
|
||||
* @brief Cell provider for title column of a NavigationMenuItems grid.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\navigationMenus;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\core\Services;
|
||||
use APP\template\TemplateManager;
|
||||
use PKP\controllers\grid\GridCellProvider;
|
||||
use PKP\controllers\grid\GridColumn;
|
||||
use PKP\controllers\grid\GridHandler;
|
||||
|
||||
class NavigationMenuItemsGridCellProvider extends GridCellProvider
|
||||
{
|
||||
/**
|
||||
* @copydoc GridCellProvider::getCellActions()
|
||||
*/
|
||||
public function getCellActions($request, $row, $column, $position = GridHandler::GRID_ACTION_POSITION_DEFAULT)
|
||||
{
|
||||
return parent::getCellActions($request, $row, $column, $position);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts variables for a given column from a data element
|
||||
* so that they may be assigned to template before rendering.
|
||||
*
|
||||
* @param \PKP\controllers\grid\GridRow $row
|
||||
* @param GridColumn $column
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getTemplateVarsFromRowColumn($row, $column)
|
||||
{
|
||||
$navigationMenuItem = $row->getData();
|
||||
$columnId = $column->getId();
|
||||
assert($navigationMenuItem instanceof \PKP\navigationMenu\NavigationMenuItem && !empty($columnId));
|
||||
|
||||
switch ($columnId) {
|
||||
case 'title':
|
||||
$templateMgr = TemplateManager::getManager(Application::get()->getRequest());
|
||||
Services::get('navigationMenu')->transformNavMenuItemTitle($templateMgr, $navigationMenuItem);
|
||||
|
||||
return ['label' => $navigationMenuItem->getLocalizedTitle()];
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return parent::getTemplateVarsFromRowColumn($row, $column);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,274 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/navigationMenus/NavigationMenuItemsGridHandler.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 NavigationMenuItemsGridHandler
|
||||
*
|
||||
* @ingroup controllers_grid_navigationMenus
|
||||
*
|
||||
* @brief Handle NavigationMenuItems grid requests.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\navigationMenus;
|
||||
|
||||
use APP\controllers\grid\navigationMenus\form\NavigationMenuItemsForm;
|
||||
use APP\core\Request;
|
||||
use APP\notification\NotificationManager;
|
||||
use PKP\controllers\grid\GridColumn;
|
||||
use PKP\controllers\grid\GridHandler;
|
||||
use PKP\core\JSONMessage;
|
||||
use PKP\core\PKPRequest;
|
||||
use PKP\db\DAORegistry;
|
||||
use PKP\linkAction\LinkAction;
|
||||
use PKP\linkAction\request\AjaxModal;
|
||||
use PKP\navigationMenu\NavigationMenuItemDAO;
|
||||
use PKP\notification\PKPNotification;
|
||||
use PKP\security\authorization\PolicySet;
|
||||
use PKP\security\authorization\RoleBasedHandlerOperationPolicy;
|
||||
use PKP\security\Role;
|
||||
|
||||
class NavigationMenuItemsGridHandler extends GridHandler
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->addRoleAssignment(
|
||||
Role::ROLE_ID_MANAGER,
|
||||
$ops = [
|
||||
'fetchGrid', 'fetchRow',
|
||||
'addNavigationMenuItem', 'editNavigationMenuItem',
|
||||
'updateNavigationMenuItem',
|
||||
'deleteNavigationMenuItem', 'saveSequence',
|
||||
]
|
||||
);
|
||||
$this->addRoleAssignment(Role::ROLE_ID_SITE_ADMIN, $ops);
|
||||
}
|
||||
|
||||
//
|
||||
// Overridden template methods
|
||||
//
|
||||
/**
|
||||
* @copydoc GridHandler::authorize()
|
||||
*/
|
||||
public function authorize($request, &$args, $roleAssignments)
|
||||
{
|
||||
$context = $request->getContext();
|
||||
$contextId = $context ? $context->getId() : \PKP\core\PKPApplication::CONTEXT_ID_NONE;
|
||||
|
||||
$rolePolicy = new PolicySet(PolicySet::COMBINING_PERMIT_OVERRIDES);
|
||||
|
||||
foreach ($roleAssignments as $role => $operations) {
|
||||
$rolePolicy->addPolicy(new RoleBasedHandlerOperationPolicy($request, $role, $operations));
|
||||
}
|
||||
$this->addPolicy($rolePolicy);
|
||||
|
||||
$navigationMenuItemId = $request->getUserVar('navigationMenuItemId');
|
||||
if ($navigationMenuItemId) {
|
||||
$navigationMenuItemDao = DAORegistry::getDAO('NavigationMenuItemDAO'); /** @var NavigationMenuItemDAO $navigationMenuItemDao */
|
||||
$navigationMenuItem = $navigationMenuItemDao->getById($navigationMenuItemId);
|
||||
if (!$navigationMenuItem || $navigationMenuItem->getContextId() != $contextId) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return parent::authorize($request, $args, $roleAssignments);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::initialize()
|
||||
*
|
||||
* @param null|mixed $args
|
||||
*/
|
||||
public function initialize($request, $args = null)
|
||||
{
|
||||
parent::initialize($request, $args);
|
||||
|
||||
// Basic grid configuration
|
||||
$this->setTitle('manager.navigationMenuItems');
|
||||
|
||||
// Set the no items row text
|
||||
$this->setEmptyRowText('grid.navigationMenus.navigationMenuItems.noneExist');
|
||||
|
||||
// Columns
|
||||
$navigationMenuItemsCellProvider = new NavigationMenuItemsGridCellProvider();
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'title',
|
||||
'common.title',
|
||||
null,
|
||||
null,
|
||||
$navigationMenuItemsCellProvider
|
||||
)
|
||||
);
|
||||
|
||||
// Add grid action.
|
||||
$router = $request->getRouter();
|
||||
|
||||
$this->addAction(
|
||||
new LinkAction(
|
||||
'addNavigationMenuItem',
|
||||
new AjaxModal(
|
||||
$router->url($request, null, null, 'addNavigationMenuItem', null, null),
|
||||
__('grid.action.addNavigationMenuItem'),
|
||||
'modal_add_item',
|
||||
true
|
||||
),
|
||||
__('grid.action.addNavigationMenuItem'),
|
||||
'add_item'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::loadData()
|
||||
*/
|
||||
protected function loadData($request, $filter)
|
||||
{
|
||||
$context = $request->getContext();
|
||||
|
||||
$contextId = \PKP\core\PKPApplication::CONTEXT_ID_NONE;
|
||||
if ($context) {
|
||||
$contextId = $context->getId();
|
||||
}
|
||||
|
||||
$navigationMenuItemDao = DAORegistry::getDAO('NavigationMenuItemDAO'); /** @var NavigationMenuItemDAO $navigationMenuItemDao */
|
||||
return $navigationMenuItemDao->getByContextId($contextId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::getRowInstance()
|
||||
*/
|
||||
protected function getRowInstance()
|
||||
{
|
||||
return new NavigationMenuItemsGridRow();
|
||||
}
|
||||
|
||||
//
|
||||
// Public grid actions.
|
||||
//
|
||||
/**
|
||||
* Update NavigationMenuItem
|
||||
*
|
||||
* @param array $args
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function updateNavigationMenuItem($args, $request)
|
||||
{
|
||||
$navigationMenuItemId = (int)$request->getUserVar('navigationMenuItemId');
|
||||
$context = $request->getContext();
|
||||
$contextId = \PKP\core\PKPApplication::CONTEXT_ID_NONE;
|
||||
if ($context) {
|
||||
$contextId = $context->getId();
|
||||
}
|
||||
|
||||
$navigationMenuItemForm = new NavigationMenuItemsForm($contextId, $navigationMenuItemId);
|
||||
|
||||
$navigationMenuItemForm->readInputData();
|
||||
|
||||
if ($navigationMenuItemForm->validate()) {
|
||||
$navigationMenuItemForm->execute();
|
||||
|
||||
if ($navigationMenuItemId) {
|
||||
// Successful edit of an existing $navigationMenuItem.
|
||||
$notificationLocaleKey = 'notification.editedNavigationMenuItem';
|
||||
} else {
|
||||
// Successful added a new $navigationMenuItemForm.
|
||||
$notificationLocaleKey = 'notification.addedNavigationMenuItem';
|
||||
}
|
||||
|
||||
// Record the notification to user.
|
||||
$notificationManager = new NotificationManager();
|
||||
$user = $request->getUser();
|
||||
$notificationManager->createTrivialNotification($user->getId(), PKPNotification::NOTIFICATION_TYPE_SUCCESS, ['contents' => __($notificationLocaleKey)]);
|
||||
|
||||
// Prepare the grid row data.
|
||||
return \PKP\db\DAO::getDataChangedEvent($navigationMenuItemId);
|
||||
} else {
|
||||
return new JSONMessage(false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Display form to edit a navigation menu item object.
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function editNavigationMenuItem($args, $request)
|
||||
{
|
||||
$navigationMenuItemId = (int) $request->getUserVar('navigationMenuItemId');
|
||||
$context = $request->getContext();
|
||||
$contextId = \PKP\core\PKPApplication::CONTEXT_ID_NONE;
|
||||
if ($context) {
|
||||
$contextId = $context->getId();
|
||||
}
|
||||
|
||||
$navigationMenuItemForm = new NavigationMenuItemsForm($contextId, $navigationMenuItemId);
|
||||
$navigationMenuItemForm->initData();
|
||||
|
||||
return new JSONMessage(true, $navigationMenuItemForm->fetch($request));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add NavigationMenuItem
|
||||
*
|
||||
* @param array $args
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function addNavigationMenuItem($args, $request)
|
||||
{
|
||||
$navigationMenuItemId = (int)$request->getUserVar('navigationMenuItemId');
|
||||
$context = $request->getContext();
|
||||
$contextId = \PKP\core\PKPApplication::CONTEXT_ID_NONE;
|
||||
if ($context) {
|
||||
$contextId = $context->getId();
|
||||
}
|
||||
|
||||
$navigationMenuItemForm = new NavigationMenuItemsForm($contextId, $navigationMenuItemId);
|
||||
$navigationMenuItemForm->initData();
|
||||
|
||||
return new JSONMessage(true, $navigationMenuItemForm->fetch($request));
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a navigation Menu item.
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function deleteNavigationMenuItem($args, $request)
|
||||
{
|
||||
if (!$request->checkCSRF()) return new JSONMessage(false);
|
||||
|
||||
$navigationMenuItemId = (int) $request->getUserVar('navigationMenuItemId');
|
||||
$navigationMenuItemDao = DAORegistry::getDAO('NavigationMenuItemDAO'); /** @var NavigationMenuItemDAO $navigationMenuItemDao */
|
||||
$navigationMenuItem = $navigationMenuItemDao->getById($navigationMenuItemId);
|
||||
if ($navigationMenuItem) {
|
||||
$navigationMenuItemDao->deleteObject($navigationMenuItem);
|
||||
|
||||
// Create notification.
|
||||
$notificationManager = new NotificationManager();
|
||||
$user = $request->getUser();
|
||||
$notificationManager->createTrivialNotification($user->getId(), PKPNotification::NOTIFICATION_TYPE_SUCCESS, ['contents' => __('notification.removedNavigationMenuItem')]);
|
||||
|
||||
return \PKP\db\DAO::getDataChangedEvent($navigationMenuItemId);
|
||||
}
|
||||
|
||||
return new JSONMessage(false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/navigationMenus/NavigationMenuItemsGridRow.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 NavigationMenuItemsGridRow
|
||||
*
|
||||
* @ingroup controllers_grid_navigationMenus
|
||||
*
|
||||
* @brief NavigationMenuItem grid row definition
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\navigationMenus;
|
||||
|
||||
use PKP\controllers\grid\GridRow;
|
||||
use PKP\linkAction\LinkAction;
|
||||
use PKP\linkAction\request\AjaxModal;
|
||||
use PKP\linkAction\request\RemoteActionConfirmationModal;
|
||||
|
||||
class NavigationMenuItemsGridRow extends GridRow
|
||||
{
|
||||
//
|
||||
// Overridden methods from GridRow
|
||||
//
|
||||
/**
|
||||
* @copydoc GridRow::initialize()
|
||||
*
|
||||
* @param null|mixed $template
|
||||
*/
|
||||
public function initialize($request, $template = null)
|
||||
{
|
||||
parent::initialize($request, $template);
|
||||
|
||||
$element = $this->getData();
|
||||
assert($element instanceof \PKP\navigationMenu\NavigationMenuItem);
|
||||
|
||||
$rowId = $this->getId();
|
||||
|
||||
// Is this a new row or an existing row?
|
||||
if (!empty($rowId) && is_numeric($rowId)) {
|
||||
// Only add row actions if this is an existing row
|
||||
$router = $request->getRouter();
|
||||
$actionArgs = [
|
||||
'navigationMenuItemId' => $rowId
|
||||
];
|
||||
|
||||
$this->addAction(
|
||||
new LinkAction(
|
||||
'edit',
|
||||
new AjaxModal(
|
||||
$router->url($request, null, null, 'editNavigationMenuItem', null, $actionArgs),
|
||||
__('grid.action.edit'),
|
||||
'modal_edit',
|
||||
true
|
||||
),
|
||||
__('grid.action.edit'),
|
||||
'edit'
|
||||
)
|
||||
);
|
||||
|
||||
$this->addAction(
|
||||
new LinkAction(
|
||||
'remove',
|
||||
new RemoteActionConfirmationModal(
|
||||
$request->getSession(),
|
||||
__('common.confirmDelete'),
|
||||
__('common.remove'),
|
||||
$router->url($request, null, null, 'deleteNavigationMenuItem', null, $actionArgs),
|
||||
'modal_delete'
|
||||
),
|
||||
__('grid.action.remove'),
|
||||
'delete'
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/navigationMenus/NavigationMenusGridCellProvider.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 NavigationMenusGridCellProvider
|
||||
*
|
||||
* @ingroup controllers_grid_navigationMenus
|
||||
*
|
||||
* @brief Cell provider for title column of a NavigationMenu grid.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\navigationMenus;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\core\Services;
|
||||
use APP\template\TemplateManager;
|
||||
use PKP\controllers\grid\GridCellProvider;
|
||||
use PKP\controllers\grid\GridColumn;
|
||||
use PKP\controllers\grid\GridHandler;
|
||||
use PKP\db\DAORegistry;
|
||||
use PKP\linkAction\LinkAction;
|
||||
use PKP\linkAction\request\AjaxModal;
|
||||
use PKP\navigationMenu\NavigationMenuItemDAO;
|
||||
|
||||
class NavigationMenusGridCellProvider extends GridCellProvider
|
||||
{
|
||||
/**
|
||||
* @copydoc GridCellProvider::getCellActions()
|
||||
*/
|
||||
public function getCellActions($request, $row, $column, $position = GridHandler::GRID_ACTION_POSITION_DEFAULT)
|
||||
{
|
||||
switch ($column->getId()) {
|
||||
case 'title':
|
||||
$navigationMenu = $row->getData();
|
||||
$router = $request->getRouter();
|
||||
$actionArgs = ['navigationMenuId' => $row->getId()];
|
||||
|
||||
return [new LinkAction(
|
||||
'edit',
|
||||
new AjaxModal(
|
||||
$router->url($request, null, null, 'editNavigationMenu', null, $actionArgs),
|
||||
__('grid.action.edit'),
|
||||
null,
|
||||
true
|
||||
),
|
||||
htmlspecialchars($navigationMenu->getTitle())
|
||||
)];
|
||||
}
|
||||
return parent::getCellActions($request, $row, $column, $position);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts variables for a given column from a data element
|
||||
* so that they may be assigned to template before rendering.
|
||||
*
|
||||
* @param \PKP\controllers\grid\GridRow $row
|
||||
* @param GridColumn $column
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getTemplateVarsFromRowColumn($row, $column)
|
||||
{
|
||||
$navigationMenu = $row->getData();
|
||||
$columnId = $column->getId();
|
||||
assert($navigationMenu instanceof \PKP\navigationMenu\NavigationMenu && !empty($columnId));
|
||||
|
||||
switch ($columnId) {
|
||||
case 'title':
|
||||
return ['label' => ''];
|
||||
case 'nmis':
|
||||
$navigationMenuItemDao = DAORegistry::getDAO('NavigationMenuItemDAO'); /** @var NavigationMenuItemDAO $navigationMenuItemDao */
|
||||
$items = $navigationMenuItemDao->getByMenuId($navigationMenu->getId())->toArray();
|
||||
|
||||
$navigationMenusTitles = '';
|
||||
|
||||
$templateMgr = TemplateManager::getManager(Application::get()->getRequest());
|
||||
foreach ($items as $item) {
|
||||
Services::get('navigationMenu')->transformNavMenuItemTitle($templateMgr, $item);
|
||||
$navigationMenusTitles = $navigationMenusTitles . $item->getLocalizedTitle() . ', ';
|
||||
}
|
||||
|
||||
$navigationMenusTitles = trim($navigationMenusTitles, ', ');
|
||||
|
||||
return ['label' => $navigationMenusTitles];
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return parent::getTemplateVarsFromRowColumn($row, $column);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,277 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/navigationMenus/NavigationMenusGridHandler.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 NavigationMenusGridHandler
|
||||
*
|
||||
* @ingroup controllers_grid_navigationMenus
|
||||
*
|
||||
* @brief Handle NavigationMenus grid requests.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\navigationMenus;
|
||||
|
||||
use APP\notification\NotificationManager;
|
||||
use PKP\controllers\grid\GridColumn;
|
||||
use PKP\controllers\grid\GridHandler;
|
||||
use PKP\controllers\grid\navigationMenus\form\NavigationMenuForm;
|
||||
use PKP\core\JSONMessage;
|
||||
use PKP\core\PKPRequest;
|
||||
use PKP\db\DAORegistry;
|
||||
use PKP\linkAction\LinkAction;
|
||||
use PKP\linkAction\request\AjaxModal;
|
||||
use PKP\navigationMenu\NavigationMenuDAO;
|
||||
use PKP\notification\PKPNotification;
|
||||
use PKP\security\authorization\PolicySet;
|
||||
use PKP\security\authorization\RoleBasedHandlerOperationPolicy;
|
||||
use PKP\security\Role;
|
||||
|
||||
class NavigationMenusGridHandler extends GridHandler
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->addRoleAssignment(
|
||||
Role::ROLE_ID_MANAGER,
|
||||
$ops = [
|
||||
'fetchGrid', 'fetchRow',
|
||||
'addNavigationMenu', 'editNavigationMenu',
|
||||
'updateNavigationMenu',
|
||||
'deleteNavigationMenu'
|
||||
]
|
||||
);
|
||||
$this->addRoleAssignment(Role::ROLE_ID_SITE_ADMIN, $ops);
|
||||
}
|
||||
|
||||
//
|
||||
// Overridden template methods
|
||||
//
|
||||
/**
|
||||
* @copydoc GridHandler::authorize()
|
||||
*/
|
||||
public function authorize($request, &$args, $roleAssignments)
|
||||
{
|
||||
$context = $request->getContext();
|
||||
$contextId = $context ? $context->getId() : \PKP\core\PKPApplication::CONTEXT_ID_NONE;
|
||||
|
||||
$rolePolicy = new PolicySet(PolicySet::COMBINING_PERMIT_OVERRIDES);
|
||||
|
||||
foreach ($roleAssignments as $role => $operations) {
|
||||
$rolePolicy->addPolicy(new RoleBasedHandlerOperationPolicy($request, $role, $operations));
|
||||
}
|
||||
$this->addPolicy($rolePolicy);
|
||||
|
||||
|
||||
$navigationMenuId = $request->getUserVar('navigationMenuId');
|
||||
if ($navigationMenuId) {
|
||||
// Ensure NavigationMenus is valid and for this context
|
||||
$navigationMenuDao = DAORegistry::getDAO('NavigationMenuDAO'); /** @var NavigationMenuDAO $navigationMenuDao */
|
||||
$navigationMenu = $navigationMenuDao->getById($navigationMenuId);
|
||||
if (!$navigationMenu || $navigationMenu->getContextId() != $contextId) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return parent::authorize($request, $args, $roleAssignments);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::initialize()
|
||||
*
|
||||
* @param null|mixed $args
|
||||
*/
|
||||
public function initialize($request, $args = null)
|
||||
{
|
||||
parent::initialize($request, $args);
|
||||
|
||||
// Basic grid configuration
|
||||
$this->setTitle('manager.navigationMenus');
|
||||
|
||||
// Set the no items row text
|
||||
$this->setEmptyRowText('grid.navigationMenus.navigationMenu.noneExist');
|
||||
|
||||
// Columns
|
||||
$navigationMenuCellProvider = new NavigationMenusGridCellProvider();
|
||||
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'title',
|
||||
'common.title',
|
||||
null,
|
||||
null,
|
||||
$navigationMenuCellProvider
|
||||
)
|
||||
);
|
||||
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'nmis',
|
||||
'manager.navigationMenuItems',
|
||||
null,
|
||||
null,
|
||||
$navigationMenuCellProvider
|
||||
)
|
||||
);
|
||||
|
||||
// Add grid action.
|
||||
$router = $request->getRouter();
|
||||
|
||||
$this->addAction(
|
||||
new LinkAction(
|
||||
'addNavigationMenu',
|
||||
new AjaxModal(
|
||||
$router->url($request, null, null, 'addNavigationMenu', null, null),
|
||||
__('grid.action.addNavigationMenu'),
|
||||
'modal_add_item',
|
||||
true
|
||||
),
|
||||
__('grid.action.addNavigationMenu'),
|
||||
'add_item'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::loadData()
|
||||
*/
|
||||
protected function loadData($request, $filter)
|
||||
{
|
||||
$context = $request->getContext();
|
||||
|
||||
$contextId = \PKP\core\PKPApplication::CONTEXT_ID_NONE;
|
||||
if ($context) {
|
||||
$contextId = $context->getId();
|
||||
}
|
||||
|
||||
$navigationMenuDao = DAORegistry::getDAO('NavigationMenuDAO'); /** @var NavigationMenuDAO $navigationMenuDao */
|
||||
return $navigationMenuDao->getByContextId($contextId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::getRowInstance()
|
||||
*/
|
||||
protected function getRowInstance()
|
||||
{
|
||||
return new NavigationMenusGridRow();
|
||||
}
|
||||
|
||||
//
|
||||
// Public grid actions.
|
||||
//
|
||||
/**
|
||||
* Display form to add NavigationMenus.
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return JSONMessage
|
||||
*/
|
||||
public function addNavigationMenu($args, $request)
|
||||
{
|
||||
return $this->editNavigationMenu($args, $request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display form to edit NavigationMenus.
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function editNavigationMenu($args, $request)
|
||||
{
|
||||
$navigationMenuId = (int)$request->getUserVar('navigationMenuId');
|
||||
$context = $request->getContext();
|
||||
$contextId = \PKP\core\PKPApplication::CONTEXT_ID_NONE;
|
||||
if ($context) {
|
||||
$contextId = $context->getId();
|
||||
}
|
||||
|
||||
$navigationMenuForm = new NavigationMenuForm($contextId, $navigationMenuId);
|
||||
$navigationMenuForm->initData();
|
||||
|
||||
return new JSONMessage(true, $navigationMenuForm->fetch($request));
|
||||
}
|
||||
|
||||
/**
|
||||
* Save an edited/inserted NavigationMenus.
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function updateNavigationMenu($args, $request)
|
||||
{
|
||||
// Identify the NavigationMenu id.
|
||||
$navigationMenuId = $request->getUserVar('navigationMenuId');
|
||||
$context = $request->getContext();
|
||||
$contextId = \PKP\core\PKPApplication::CONTEXT_ID_NONE;
|
||||
if ($context) {
|
||||
$contextId = $context->getId();
|
||||
}
|
||||
|
||||
// Form handling.
|
||||
$navigationMenusForm = new NavigationMenuForm($contextId, $navigationMenuId);
|
||||
$navigationMenusForm->readInputData();
|
||||
|
||||
if ($navigationMenusForm->validate()) {
|
||||
$navigationMenusForm->execute();
|
||||
|
||||
if ($navigationMenuId) {
|
||||
// Successful edit of an existing NavigationMenu.
|
||||
$notificationLocaleKey = 'notification.editedNavigationMenu';
|
||||
} else {
|
||||
// Successful added a new NavigationMenu.
|
||||
$notificationLocaleKey = 'notification.addedNavigationMenu';
|
||||
}
|
||||
|
||||
// Record the notification to user.
|
||||
$notificationManager = new NotificationManager();
|
||||
$user = $request->getUser();
|
||||
$notificationManager->createTrivialNotification($user->getId(), PKPNotification::NOTIFICATION_TYPE_SUCCESS, ['contents' => __($notificationLocaleKey)]);
|
||||
|
||||
// Prepare the grid row data.
|
||||
return \PKP\db\DAO::getDataChangedEvent($navigationMenuId);
|
||||
} else {
|
||||
return new JSONMessage(false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a NavigationMenu.
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function deleteNavigationMenu($args, $request)
|
||||
{
|
||||
$navigationMenuId = (int) $request->getUserVar('navigationMenuId');
|
||||
$context = $request->getContext();
|
||||
|
||||
$navigationMenuDao = DAORegistry::getDAO('NavigationMenuDAO'); /** @var NavigationMenuDAO $navigationMenuDao */
|
||||
$navigationMenu = $navigationMenuDao->getById($navigationMenuId, $context ? $context->getId() : \PKP\core\PKPApplication::CONTEXT_SITE);
|
||||
if ($navigationMenu && $request->checkCSRF()) {
|
||||
$navigationMenuDao->deleteObject($navigationMenu);
|
||||
|
||||
// Create notification.
|
||||
$notificationManager = new NotificationManager();
|
||||
$user = $request->getUser();
|
||||
$notificationManager->createTrivialNotification($user->getId(), PKPNotification::NOTIFICATION_TYPE_SUCCESS, ['contents' => __('notification.removedNavigationMenu')]);
|
||||
|
||||
return \PKP\db\DAO::getDataChangedEvent($navigationMenuId);
|
||||
}
|
||||
|
||||
return new JSONMessage(false);
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user