first commit

This commit is contained in:
CHIEFSOFT\ameye
2024-06-08 17:09:23 -04:00
commit df3a033196
17887 changed files with 8637778 additions and 0 deletions
@@ -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'
]
);
}
}
@@ -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');
}
}
@@ -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();
}
}
@@ -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;
}
}