first commit
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/api/file/ManageFileApiHandler.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 ManageFileApiHandler
|
||||
*
|
||||
* @ingroup controllers_api_file
|
||||
*
|
||||
* @brief Class defining an AJAX API for file manipulation.
|
||||
*/
|
||||
|
||||
namespace APP\controllers\api\file;
|
||||
|
||||
use APP\controllers\tab\pubIds\form\PublicIdentifiersForm;
|
||||
use APP\core\Application;
|
||||
use APP\core\Request;
|
||||
use PKP\controllers\api\file\PKPManageFileApiHandler;
|
||||
use PKP\core\JSONMessage;
|
||||
use PKP\db\DAO;
|
||||
use PKP\security\Role;
|
||||
|
||||
class ManageFileApiHandler extends PKPManageFileApiHandler
|
||||
{
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->addRoleAssignment(
|
||||
[Role::ROLE_ID_MANAGER, Role::ROLE_ID_SITE_ADMIN, Role::ROLE_ID_SUB_EDITOR, Role::ROLE_ID_ASSISTANT, Role::ROLE_ID_REVIEWER, Role::ROLE_ID_AUTHOR],
|
||||
['identifiers', 'updateIdentifiers', 'clearPubId',]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit proof submission file pub ids.
|
||||
*
|
||||
* @param array $args
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function identifiers($args, $request)
|
||||
{
|
||||
$submissionFile = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_SUBMISSION_FILE);
|
||||
$stageId = $request->getUserVar('stageId');
|
||||
$form = new PublicIdentifiersForm($submissionFile, $stageId);
|
||||
$form->initData();
|
||||
return new JSONMessage(true, $form->fetch($request));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update proof submission file pub ids.
|
||||
*
|
||||
* @param array $args
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function updateIdentifiers($args, $request)
|
||||
{
|
||||
$submissionFile = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_SUBMISSION_FILE);
|
||||
$stageId = $request->getUserVar('stageId');
|
||||
$form = new PublicIdentifiersForm($submissionFile, $stageId);
|
||||
$form->readInputData();
|
||||
if ($form->validate()) {
|
||||
$form->execute();
|
||||
return DAO::getDataChangedEvent($submissionFile->getId());
|
||||
} else {
|
||||
return new JSONMessage(true, $form->fetch($request));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear proof submission file pub id.
|
||||
*
|
||||
* @param array $args
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function clearPubId($args, $request)
|
||||
{
|
||||
if (!$request->checkCSRF()) {
|
||||
return new JSONMessage(false);
|
||||
}
|
||||
|
||||
$submissionFile = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_SUBMISSION_FILE);
|
||||
$stageId = $request->getUserVar('stageId');
|
||||
$form = new PublicIdentifiersForm($submissionFile, $stageId);
|
||||
$form->clearPubId($request->getUserVar('pubIdPlugIn'));
|
||||
return new JSONMessage(true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/articleGalleys/ArticleGalleyGridCellProvider.php
|
||||
*
|
||||
* Copyright (c) 2016-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 ArticleGalleyGridCellProvider
|
||||
*
|
||||
* @ingroup controllers_grid_articleGalleys
|
||||
*
|
||||
* @brief Base class for a cell provider for article galleys.
|
||||
*/
|
||||
|
||||
namespace APP\controllers\grid\articleGalleys;
|
||||
|
||||
use APP\facades\Repo;
|
||||
use APP\publication\Publication;
|
||||
use APP\submission\Submission;
|
||||
use PKP\controllers\api\file\linkAction\DownloadFileLinkAction;
|
||||
use PKP\controllers\grid\DataObjectGridCellProvider;
|
||||
use PKP\controllers\grid\GridHandler;
|
||||
use PKP\galley\Galley;
|
||||
|
||||
class ArticleGalleyGridCellProvider extends DataObjectGridCellProvider
|
||||
{
|
||||
/** @var Submission */
|
||||
public $_submission;
|
||||
|
||||
/** @var Publication */
|
||||
public $_publication;
|
||||
|
||||
public $_isEditable;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param Submission $submission
|
||||
*/
|
||||
public function __construct($submission, $publication, $isEditable)
|
||||
{
|
||||
parent::__construct();
|
||||
$this->_submission = $submission;
|
||||
$this->_publication = $publication;
|
||||
$this->_isEditable = $isEditable;
|
||||
}
|
||||
|
||||
//
|
||||
// Template methods from GridCellProvider
|
||||
//
|
||||
/**
|
||||
* @copydoc GridCellProvider::getTemplateVarsFromRowColumn()
|
||||
*/
|
||||
public function getTemplateVarsFromRowColumn($row, $column)
|
||||
{
|
||||
$element = $row->getData();
|
||||
$columnId = $column->getId();
|
||||
assert($element instanceof \PKP\core\DataObject && !empty($columnId));
|
||||
/** @var Galley $element */
|
||||
switch ($columnId) {
|
||||
case 'label':
|
||||
return [
|
||||
'label' => !$element->getRemoteUrl() && $element->getData('submissionFileId') ? '' : $element->getLabel()
|
||||
];
|
||||
default: assert(false);
|
||||
}
|
||||
return parent::getTemplateVarsFromRowColumn($row, $column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get request arguments.
|
||||
*
|
||||
* @param \PKP\controllers\grid\GridRow $row
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getRequestArgs($row)
|
||||
{
|
||||
return [
|
||||
'submissionId' => $this->_submission->getId(),
|
||||
'publicationId' => $this->_publication->getId(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridCellProvider::getCellActions()
|
||||
*/
|
||||
public function getCellActions($request, $row, $column, $position = GridHandler::GRID_ACTION_POSITION_DEFAULT)
|
||||
{
|
||||
switch ($column->getId()) {
|
||||
case 'label':
|
||||
$element = $row->getData();
|
||||
if ($element->getRemoteUrl() || !$element->getData('submissionFileId')) {
|
||||
break;
|
||||
}
|
||||
|
||||
$submissionFile = Repo::submissionFile()
|
||||
->get($element->getData('submissionFileId'));
|
||||
return [new DownloadFileLinkAction($request, $submissionFile, WORKFLOW_STAGE_ID_PRODUCTION, $element->getLabel())];
|
||||
}
|
||||
return parent::getCellActions($request, $row, $column, $position);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,481 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/articleGalleys/ArticleGalleyGridHandler.php
|
||||
*
|
||||
* Copyright (c) 2016-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 ArticleGalleyGridHandler
|
||||
*
|
||||
* @ingroup controllers_grid_articleGalleys
|
||||
*
|
||||
* @brief Handle article galley grid requests.
|
||||
*/
|
||||
|
||||
namespace APP\controllers\grid\articleGalleys;
|
||||
|
||||
use APP\controllers\grid\articleGalleys\form\ArticleGalleyForm;
|
||||
use APP\controllers\tab\pubIds\form\PublicIdentifiersForm;
|
||||
use APP\core\Application;
|
||||
use APP\core\Request;
|
||||
use APP\facades\Repo;
|
||||
use APP\notification\NotificationManager;
|
||||
use APP\publication\Publication;
|
||||
use APP\submission\Submission;
|
||||
use APP\template\TemplateManager;
|
||||
use PKP\controllers\grid\feature\OrderGridItemsFeature;
|
||||
use PKP\controllers\grid\GridColumn;
|
||||
use PKP\controllers\grid\GridHandler;
|
||||
use PKP\core\JSONMessage;
|
||||
use PKP\core\PKPApplication;
|
||||
use PKP\db\DAO;
|
||||
use PKP\db\DAORegistry;
|
||||
use PKP\galley\Galley;
|
||||
use PKP\linkAction\LinkAction;
|
||||
use PKP\linkAction\request\AjaxModal;
|
||||
use PKP\notification\NotificationDAO;
|
||||
use PKP\notification\PKPNotification;
|
||||
use PKP\plugins\PluginRegistry;
|
||||
use PKP\security\authorization\internal\RepresentationRequiredPolicy;
|
||||
use PKP\security\authorization\PublicationAccessPolicy;
|
||||
use PKP\security\authorization\WorkflowStageAccessPolicy;
|
||||
use PKP\security\Role;
|
||||
use PKP\submission\PKPSubmission;
|
||||
|
||||
class ArticleGalleyGridHandler extends GridHandler
|
||||
{
|
||||
/** @var Request */
|
||||
public $_request;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->addRoleAssignment(
|
||||
[Role::ROLE_ID_AUTHOR, Role::ROLE_ID_MANAGER, Role::ROLE_ID_SITE_ADMIN, Role::ROLE_ID_SUB_EDITOR, Role::ROLE_ID_ASSISTANT],
|
||||
['fetchGrid', 'fetchRow']
|
||||
);
|
||||
$this->addRoleAssignment(
|
||||
[Role::ROLE_ID_MANAGER, Role::ROLE_ID_SITE_ADMIN, Role::ROLE_ID_SUB_EDITOR, Role::ROLE_ID_ASSISTANT],
|
||||
['addGalley', 'editGalley', 'editGalleyTab', 'updateGalley', 'deleteGalley', 'identifiers', 'updateIdentifiers', 'clearPubId', 'saveSequence']
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Getters/Setters
|
||||
//
|
||||
/**
|
||||
* Get the authorized submission.
|
||||
*
|
||||
* @return Submission
|
||||
*/
|
||||
public function getSubmission()
|
||||
{
|
||||
return $this->getAuthorizedContextObject(Application::ASSOC_TYPE_SUBMISSION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the authorized publication.
|
||||
*
|
||||
* @return Publication
|
||||
*/
|
||||
public function getPublication()
|
||||
{
|
||||
return $this->getAuthorizedContextObject(Application::ASSOC_TYPE_PUBLICATION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the authorized galley.
|
||||
*
|
||||
* @return Galley
|
||||
*/
|
||||
public function getGalley()
|
||||
{
|
||||
return $this->getAuthorizedContextObject(Application::ASSOC_TYPE_REPRESENTATION);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Overridden methods from PKPHandler.
|
||||
//
|
||||
/**
|
||||
* @see GridHandler::getJSHandler()
|
||||
*/
|
||||
public function getJSHandler()
|
||||
{
|
||||
return '$.pkp.controllers.grid.articleGalleys.ArticleGalleyGridHandler';
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc PKPHandler::authorize()
|
||||
*/
|
||||
public function authorize($request, &$args, $roleAssignments)
|
||||
{
|
||||
$this->_request = $request;
|
||||
|
||||
$this->addPolicy(new WorkflowStageAccessPolicy($request, $args, $roleAssignments, 'submissionId', WORKFLOW_STAGE_ID_PRODUCTION));
|
||||
|
||||
$this->addPolicy(new PublicationAccessPolicy($request, $args, $roleAssignments));
|
||||
|
||||
if ($request->getUserVar('representationId')) {
|
||||
$this->addPolicy(new RepresentationRequiredPolicy($request, $args));
|
||||
}
|
||||
|
||||
return parent::authorize($request, $args, $roleAssignments);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::initialize()
|
||||
*
|
||||
* @param null|mixed $args
|
||||
*/
|
||||
public function initialize($request, $args = null)
|
||||
{
|
||||
parent::initialize($request, $args);
|
||||
$this->setTitle('submission.layout.galleys');
|
||||
|
||||
$cellProvider = new ArticleGalleyGridCellProvider($this->getSubmission(), $this->getPublication(), $this->canEdit());
|
||||
|
||||
// Columns
|
||||
$this->addColumn(new GridColumn(
|
||||
'label',
|
||||
'common.name',
|
||||
null,
|
||||
null,
|
||||
$cellProvider
|
||||
));
|
||||
|
||||
if ($this->canEdit()) {
|
||||
$this->addAction(new LinkAction(
|
||||
'addGalley',
|
||||
new AjaxModal(
|
||||
$request->getRouter()->url($request, null, null, 'addGalley', null, $this->getRequestArgs()),
|
||||
__('submission.layout.newGalley'),
|
||||
'modal_add_item'
|
||||
),
|
||||
__('grid.action.addGalley'),
|
||||
'add_item'
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Overridden methods from GridHandler
|
||||
//
|
||||
/**
|
||||
* @copydoc GridHandler::initFeatures()
|
||||
*/
|
||||
public function initFeatures($request, $args)
|
||||
{
|
||||
if ($this->canEdit()) {
|
||||
return [new OrderGridItemsFeature()];
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::getDataElementSequence()
|
||||
*/
|
||||
public function getDataElementSequence($row)
|
||||
{
|
||||
return $row->getSequence();
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::setDataElementSequence()
|
||||
*/
|
||||
public function setDataElementSequence($request, $rowId, $gridDataElement, $newSequence)
|
||||
{
|
||||
$galley = Repo::galley()->get((int) $rowId);
|
||||
Repo::galley()->edit($galley, ['seq' => $newSequence]);
|
||||
}
|
||||
|
||||
//
|
||||
// Overridden methods from GridHandler
|
||||
//
|
||||
/**
|
||||
* @copydoc GridHandler::getRowInstance()
|
||||
*
|
||||
* @return ArticleGalleyGridRow
|
||||
*/
|
||||
public function getRowInstance()
|
||||
{
|
||||
return new ArticleGalleyGridRow(
|
||||
$this->getSubmission(),
|
||||
$this->getPublication(),
|
||||
$this->canEdit()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the arguments that will identify the data in the grid.
|
||||
* Overridden by child grids.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getRequestArgs()
|
||||
{
|
||||
return [
|
||||
'submissionId' => $this->getSubmission()->getId(),
|
||||
'publicationId' => $this->getPublication()->getId(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::loadData()
|
||||
*
|
||||
* @param null|mixed $filter
|
||||
*/
|
||||
public function loadData($request, $filter = null)
|
||||
{
|
||||
return Repo::galley()->getCollector()
|
||||
->filterByPublicationIds([$this->getPublication()->getId()])
|
||||
->getMany();
|
||||
}
|
||||
|
||||
//
|
||||
// Public Galley Grid Actions
|
||||
//
|
||||
/**
|
||||
* Edit article galley pub ids
|
||||
*
|
||||
* @param array $args
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function identifiers($args, $request)
|
||||
{
|
||||
$representation = $this->getGalley();
|
||||
$form = new PublicIdentifiersForm($representation, null, null, $this->canEdit());
|
||||
$form->initData();
|
||||
return new JSONMessage(true, $form->fetch($request));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update article galley pub ids
|
||||
*
|
||||
* @param array $args
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function updateIdentifiers($args, $request)
|
||||
{
|
||||
$representation = $this->getGalley();
|
||||
$form = new PublicIdentifiersForm($representation, null, array_merge($this->getRequestArgs(), ['representationId' => $representation->getId()]), $this->canEdit());
|
||||
$form->readInputData();
|
||||
if ($form->validate()) {
|
||||
$form->execute();
|
||||
return DAO::getDataChangedEvent();
|
||||
} else {
|
||||
return new JSONMessage(true, $form->fetch($request));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear galley pub id
|
||||
*
|
||||
* @param array $args
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function clearPubId($args, $request)
|
||||
{
|
||||
if (!$request->checkCSRF()) {
|
||||
return new JSONMessage(false);
|
||||
}
|
||||
|
||||
$representation = $this->getGalley();
|
||||
$form = new PublicIdentifiersForm($representation, null, null, $this->canEdit());
|
||||
$form->clearPubId($request->getUserVar('pubIdPlugIn'));
|
||||
return new JSONMessage(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a galley
|
||||
*
|
||||
* @param array $args
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function addGalley($args, $request)
|
||||
{
|
||||
$galleyForm = new ArticleGalleyForm(
|
||||
$request,
|
||||
$this->getSubmission(),
|
||||
$this->getPublication()
|
||||
);
|
||||
$galleyForm->initData();
|
||||
return new JSONMessage(true, $galleyForm->fetch($request));
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a galley.
|
||||
*
|
||||
* @param array $args
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function deleteGalley($args, $request)
|
||||
{
|
||||
$galley = $this->getGalley();
|
||||
if (!$galley || !$request->checkCSRF()) {
|
||||
return new JSONMessage(false);
|
||||
}
|
||||
Repo::galley()->delete($galley);
|
||||
|
||||
$notificationDao = DAORegistry::getDAO('NotificationDAO'); /** @var NotificationDAO $notificationDao */
|
||||
$notificationDao->deleteByAssoc(Application::ASSOC_TYPE_REPRESENTATION, $galley->getId());
|
||||
|
||||
if ($this->getSubmission()->getStageId() == WORKFLOW_STAGE_ID_EDITING ||
|
||||
$this->getSubmission()->getStageId() == WORKFLOW_STAGE_ID_PRODUCTION) {
|
||||
$notificationMgr = new NotificationManager();
|
||||
$notificationMgr->updateNotification(
|
||||
$request,
|
||||
[PKPNotification::NOTIFICATION_TYPE_ASSIGN_PRODUCTIONUSER, PKPNotification::NOTIFICATION_TYPE_AWAITING_REPRESENTATIONS],
|
||||
null,
|
||||
Application::ASSOC_TYPE_SUBMISSION,
|
||||
$this->getSubmission()->getId()
|
||||
);
|
||||
}
|
||||
|
||||
return DAO::getDataChangedEvent($galley->getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit a galley metadata modal
|
||||
*
|
||||
* @param array $args
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function editGalley($args, $request)
|
||||
{
|
||||
$galley = $this->getGalley();
|
||||
|
||||
// Check if this is a remote galley
|
||||
$templateMgr = TemplateManager::getManager($request);
|
||||
$templateMgr->assign([
|
||||
'submissionId' => $this->getSubmission()->getId(),
|
||||
'publicationId' => $this->getPublication()->getId(),
|
||||
'representationId' => $galley->getId(),
|
||||
]);
|
||||
$publisherIdEnabled = in_array('galley', (array) $request->getContext()->getData('enablePublisherId'));
|
||||
$pubIdsEnabled = false;
|
||||
$pubIdPlugins = PluginRegistry::loadCategory('pubIds', true, $request->getContext()->getId());
|
||||
foreach ($pubIdPlugins as $pubIdPlugin) {
|
||||
if ($pubIdPlugin->isObjectTypeEnabled('Representation', $request->getContext()->getId())) {
|
||||
$pubIdsEnabled = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($publisherIdEnabled || $pubIdsEnabled) {
|
||||
$templateMgr->assign('enableIdentifiers', true);
|
||||
}
|
||||
return new JSONMessage(true, $templateMgr->fetch('controllers/grid/articleGalleys/editFormat.tpl'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit a galley
|
||||
*
|
||||
* @param array $args
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function editGalleyTab($args, $request)
|
||||
{
|
||||
// Form handling
|
||||
$galleyForm = new ArticleGalleyForm(
|
||||
$request,
|
||||
$this->getSubmission(),
|
||||
$this->getPublication(),
|
||||
$this->getGalley(),
|
||||
$this->canEdit()
|
||||
);
|
||||
$galleyForm->initData();
|
||||
return new JSONMessage(true, $galleyForm->fetch($request));
|
||||
}
|
||||
|
||||
/**
|
||||
* Save a galley
|
||||
*
|
||||
* @param array $args
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function updateGalley($args, $request)
|
||||
{
|
||||
$galley = $this->getGalley();
|
||||
|
||||
$galleyForm = new ArticleGalleyForm($request, $this->getSubmission(), $this->getPublication(), $galley, $this->canEdit());
|
||||
$galleyForm->readInputData();
|
||||
|
||||
if ($galleyForm->validate()) {
|
||||
$galley = $galleyForm->execute();
|
||||
|
||||
if ($this->getSubmission()->getStageId() == WORKFLOW_STAGE_ID_EDITING ||
|
||||
$this->getSubmission()->getStageId() == WORKFLOW_STAGE_ID_PRODUCTION) {
|
||||
$notificationMgr = new NotificationManager();
|
||||
$notificationMgr->updateNotification(
|
||||
$request,
|
||||
[PKPNotification::NOTIFICATION_TYPE_ASSIGN_PRODUCTIONUSER, PKPNotification::NOTIFICATION_TYPE_AWAITING_REPRESENTATIONS],
|
||||
null,
|
||||
Application::ASSOC_TYPE_SUBMISSION,
|
||||
$this->getSubmission()->getId()
|
||||
);
|
||||
}
|
||||
|
||||
return DAO::getDataChangedEvent($galley->getId());
|
||||
}
|
||||
return new JSONMessage(true, $galleyForm->fetch($request));
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::fetchRow()
|
||||
*/
|
||||
public function fetchRow($args, $request)
|
||||
{
|
||||
$json = parent::fetchRow($args, $request);
|
||||
if ($row = $this->getRequestedRow($request, $args)) {
|
||||
$galley = $row->getData();
|
||||
if (!$galley->getRemoteUrl() && !$galley->getData('submissionFileId')) {
|
||||
$json->setEvent('uploadFile', $galley->getId());
|
||||
}
|
||||
}
|
||||
|
||||
return $json;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can the current user edit the galleys in this grid?
|
||||
*
|
||||
* The user must have an allowed role in one of the assigned stages.
|
||||
* If the user is not assigned, they can edit if they are an editor
|
||||
* or admin.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function canEdit()
|
||||
{
|
||||
return $this->getPublication()->getData('status') !== PKPSubmission::STATUS_PUBLISHED &&
|
||||
Repo::user()->canUserAccessStage(
|
||||
WORKFLOW_STAGE_ID_PRODUCTION,
|
||||
PKPApplication::WORKFLOW_TYPE_EDITORIAL,
|
||||
$this->getAuthorizedContextObject(Application::ASSOC_TYPE_ACCESSIBLE_WORKFLOW_STAGES),
|
||||
$this->getAuthorizedContextObject(Application::ASSOC_TYPE_USER_ROLES)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/articleGalleys/ArticleGalleyGridRow.php
|
||||
*
|
||||
* Copyright (c) 2016-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 ArticleGalleyGridRow
|
||||
*
|
||||
* @ingroup controllers_grid_articleGalleys
|
||||
*
|
||||
* @brief Representation of an article galley grid row.
|
||||
*/
|
||||
|
||||
namespace APP\controllers\grid\articleGalleys;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\publication\Publication;
|
||||
use APP\submission\Submission;
|
||||
use PKP\controllers\api\file\linkAction\AddFileLinkAction;
|
||||
use PKP\controllers\grid\GridRow;
|
||||
use PKP\linkAction\LinkAction;
|
||||
use PKP\linkAction\request\AjaxModal;
|
||||
use PKP\linkAction\request\RemoteActionConfirmationModal;
|
||||
use PKP\security\Role;
|
||||
use PKP\submissionFile\SubmissionFile;
|
||||
|
||||
class ArticleGalleyGridRow extends GridRow
|
||||
{
|
||||
/** @var Submission */
|
||||
public $_submission;
|
||||
|
||||
/** @var Publication */
|
||||
public $_publication;
|
||||
|
||||
/** @var bool */
|
||||
public $_isEditable;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param Submission $submission
|
||||
* @param bool $isEditable
|
||||
*/
|
||||
public function __construct($submission, $publication, $isEditable)
|
||||
{
|
||||
$this->_submission = $submission;
|
||||
$this->_publication = $publication;
|
||||
$this->_isEditable = $isEditable;
|
||||
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
//
|
||||
// Overridden methods from GridRow
|
||||
//
|
||||
/**
|
||||
* @copydoc GridRow::initialize()
|
||||
*
|
||||
* @param null|mixed $template
|
||||
*/
|
||||
public function initialize($request, $template = null)
|
||||
{
|
||||
// Do the default initialization
|
||||
parent::initialize($request, $template);
|
||||
|
||||
// Is this a new row or an existing row?
|
||||
$rowId = $this->getId();
|
||||
if (!empty($rowId) && is_numeric($rowId)) {
|
||||
// Only add row actions if this is an existing row
|
||||
$router = $request->getRouter();
|
||||
$actionArgs = $this->getRequestArgs();
|
||||
$actionArgs['representationId'] = $rowId;
|
||||
|
||||
// Add row-level actions
|
||||
$this->addAction(new LinkAction(
|
||||
'editGalley',
|
||||
new AjaxModal(
|
||||
$router->url($request, null, null, 'editGalley', null, $actionArgs),
|
||||
($this->_isEditable) ? __('submission.layout.editGalley') : __('submission.layout.viewGalley'),
|
||||
'modal_edit'
|
||||
),
|
||||
($this->_isEditable) ? __('grid.action.edit') : __('grid.action.view'),
|
||||
'edit'
|
||||
));
|
||||
|
||||
if ($this->_isEditable) {
|
||||
$galley = $this->getData();
|
||||
if (!$galley->getRemoteUrl()) {
|
||||
$this->addAction(new AddFileLinkAction(
|
||||
$request,
|
||||
$this->getSubmission()->getId(),
|
||||
WORKFLOW_STAGE_ID_PRODUCTION,
|
||||
[Role::ROLE_ID_MANAGER, Role::ROLE_ID_SITE_ADMIN, Role::ROLE_ID_SUB_EDITOR, Role::ROLE_ID_ASSISTANT],
|
||||
SubmissionFile::SUBMISSION_FILE_PROOF,
|
||||
Application::ASSOC_TYPE_REPRESENTATION,
|
||||
$rowId,
|
||||
null
|
||||
));
|
||||
}
|
||||
|
||||
$this->addAction(new LinkAction(
|
||||
'deleteGalley',
|
||||
new RemoteActionConfirmationModal(
|
||||
$request->getSession(),
|
||||
__('common.confirmDelete'),
|
||||
__('grid.action.delete'),
|
||||
$router->url($request, null, null, 'deleteGalley', null, $actionArgs),
|
||||
'modal_delete'
|
||||
),
|
||||
__('grid.action.delete'),
|
||||
'delete'
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the submission for this row (already authorized)
|
||||
*
|
||||
* @return Submission
|
||||
*/
|
||||
public function getSubmission()
|
||||
{
|
||||
return $this->_submission;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the publication for this row (already authorized)
|
||||
*
|
||||
* @return Publication
|
||||
*/
|
||||
public function getPublication()
|
||||
{
|
||||
return $this->_publication;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the base arguments that will identify the data in the grid.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getRequestArgs()
|
||||
{
|
||||
return [
|
||||
'submissionId' => $this->getSubmission()->getId(),
|
||||
'publicationId' => $this->getPublication()->getId(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,193 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/articleGalleys/form/ArticleGalleyForm.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 ArticleGalleyForm
|
||||
*
|
||||
* @ingroup controllers_grid_articleGalleys_form
|
||||
*
|
||||
* @see Galley
|
||||
*
|
||||
* @brief Article galley editing form.
|
||||
*/
|
||||
|
||||
namespace APP\controllers\grid\articleGalleys\form;
|
||||
|
||||
use APP\core\Request;
|
||||
use APP\facades\Repo;
|
||||
use APP\publication\Publication;
|
||||
use APP\submission\Submission;
|
||||
use APP\template\TemplateManager;
|
||||
use PKP\form\Form;
|
||||
use PKP\galley\Galley;
|
||||
|
||||
class ArticleGalleyForm extends Form
|
||||
{
|
||||
/** @var Submission */
|
||||
public $_submission = null;
|
||||
|
||||
/** @var Publication */
|
||||
public $_publication = null;
|
||||
|
||||
/** @var Galley current galley */
|
||||
public $_articleGalley = null;
|
||||
|
||||
public bool $_isEditable = true;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param Submission $submission
|
||||
* @param Publication $publication
|
||||
* @param Galley $articleGalley (optional)
|
||||
* @param bool $isEditable (optional, default = true)
|
||||
*/
|
||||
public function __construct($request, $submission, $publication, $articleGalley = null, bool $isEditable = true)
|
||||
{
|
||||
parent::__construct('controllers/grid/articleGalleys/form/articleGalleyForm.tpl');
|
||||
$this->_submission = $submission;
|
||||
$this->_publication = $publication;
|
||||
$this->_articleGalley = $articleGalley;
|
||||
$this->_isEditable = $isEditable;
|
||||
|
||||
$this->addCheck(new \PKP\form\validation\FormValidator($this, 'label', 'required', 'editor.issues.galleyLabelRequired'));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorRegExp($this, 'urlPath', 'optional', 'validator.alpha_dash_period', '/^[a-zA-Z0-9]+([\\.\\-_][a-zA-Z0-9]+)*$/'));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorPost($this));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorCSRF($this));
|
||||
|
||||
// Ensure a locale is provided and valid
|
||||
$journal = $request->getJournal();
|
||||
$this->addCheck(
|
||||
new \PKP\form\validation\FormValidator(
|
||||
$this,
|
||||
'locale',
|
||||
'required',
|
||||
'editor.issues.galleyLocaleRequired'
|
||||
),
|
||||
function ($locale) use ($journal) {
|
||||
return in_array($locale, $journal->getSupportedSubmissionLocaleNames());
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::fetch()
|
||||
*
|
||||
* @param null|mixed $template
|
||||
*/
|
||||
public function fetch($request, $template = null, $display = false)
|
||||
{
|
||||
$templateMgr = TemplateManager::getManager($request);
|
||||
if ($this->_articleGalley) {
|
||||
$articleGalleyFile = $this->_articleGalley->getFile();
|
||||
$templateMgr->assign([
|
||||
'representationId' => $this->_articleGalley->getId(),
|
||||
'articleGalley' => $this->_articleGalley,
|
||||
'articleGalleyFile' => $articleGalleyFile,
|
||||
'supportsDependentFiles' => $articleGalleyFile ? Repo::submissionFile()->supportsDependentFiles($articleGalleyFile) : null,
|
||||
]);
|
||||
}
|
||||
$context = $request->getContext();
|
||||
$templateMgr->assign([
|
||||
'supportedLocales' => $context->getSupportedSubmissionLocaleNames(),
|
||||
'submissionId' => $this->_submission->getId(),
|
||||
'publicationId' => $this->_publication->getId(),
|
||||
'formDisabled' => !$this->_isEditable
|
||||
]);
|
||||
|
||||
return parent::fetch($request, $template, $display);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::validate
|
||||
*/
|
||||
public function validate($callHooks = true)
|
||||
{
|
||||
// Validate the urlPath
|
||||
if (strlen((string) $this->getData('urlPath'))) {
|
||||
if (ctype_digit((string) $this->getData('urlPath'))) {
|
||||
$this->addError('urlPath', __('publication.urlPath.numberInvalid'));
|
||||
$this->addErrorField('urlPath');
|
||||
} else {
|
||||
$existingGalley = Repo::galley()->getByUrlPath((string) $this->getData('urlPath'), $this->_publication);
|
||||
if ($existingGalley && $this->_articleGalley?->getId() !== $existingGalley->getId()) {
|
||||
$this->addError('urlPath', __('publication.urlPath.duplicate'));
|
||||
$this->addErrorField('urlPath');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$this->_isEditable) {
|
||||
$this->addError('', __('galley.cantEditPublished'));
|
||||
}
|
||||
|
||||
return parent::validate($callHooks);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize form data from current galley (if applicable).
|
||||
*/
|
||||
public function initData()
|
||||
{
|
||||
if ($this->_articleGalley) {
|
||||
$this->_data = [
|
||||
'label' => $this->_articleGalley->getLabel(),
|
||||
'locale' => $this->_articleGalley->getLocale(),
|
||||
'urlPath' => $this->_articleGalley->getData('urlPath'),
|
||||
'urlRemote' => $this->_articleGalley->getData('urlRemote'),
|
||||
];
|
||||
} else {
|
||||
$this->_data = [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign form data to user-submitted data.
|
||||
*/
|
||||
public function readInputData()
|
||||
{
|
||||
$this->readUserVars(
|
||||
[
|
||||
'label',
|
||||
'locale',
|
||||
'urlPath',
|
||||
'urlRemote',
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save changes to the galley.
|
||||
*
|
||||
* @return Galley The resulting article galley.
|
||||
*/
|
||||
public function execute(...$functionArgs)
|
||||
{
|
||||
$data = [
|
||||
'publicationId' => $this->_publication->getId(),
|
||||
'label' => $this->getData('label'),
|
||||
'locale' => $this->getData('locale'),
|
||||
'urlPath' => strlen($urlPath = (string) $this->getData('urlPath')) ? $urlPath : null,
|
||||
'urlRemote' => strlen($urlRemote = (string) $this->getData('urlRemote')) ? $urlRemote : null
|
||||
];
|
||||
|
||||
if ($this->_articleGalley) {
|
||||
// Update galley in the db
|
||||
Repo::galley()->edit($this->_articleGalley, $data);
|
||||
$articleGalleyId = $this->_articleGalley->getId();
|
||||
} else {
|
||||
// Create a new galley
|
||||
$articleGalleyId = Repo::galley()->add(Repo::galley()->newDataObject($data));
|
||||
}
|
||||
|
||||
parent::execute(...$functionArgs);
|
||||
|
||||
return $this->_articleGalley = Repo::galley()->get($articleGalleyId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/issueGalleys/IssueGalleyGridCellProvider.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 IssueGalleyGridCellProvider
|
||||
*
|
||||
* @ingroup issue_galley
|
||||
*
|
||||
* @brief Grid cell provider for the issue galleys grid
|
||||
*/
|
||||
|
||||
namespace APP\controllers\grid\issueGalleys;
|
||||
|
||||
use PKP\controllers\grid\GridCellProvider;
|
||||
use PKP\controllers\grid\GridColumn;
|
||||
use PKP\facades\Locale;
|
||||
|
||||
class IssueGalleyGridCellProvider 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)
|
||||
{
|
||||
$issueGalley = $row->getData();
|
||||
$columnId = $column->getId();
|
||||
assert(is_a($issueGalley, 'IssueGalley'));
|
||||
assert(!empty($columnId));
|
||||
|
||||
switch ($columnId) {
|
||||
case 'label': return ['label' => $issueGalley->getLabel()];
|
||||
case 'locale': return ['label' => Locale::getMetadata($issueGalley->getLocale())->getDisplayName()];
|
||||
case 'publicGalleyId': return ['label' => $issueGalley->getStoredPubId('publisher-id')];
|
||||
default: assert(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,323 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/issueGalleys/IssueGalleyGridHandler.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 IssueGalleyGridHandler
|
||||
*
|
||||
* @ingroup issue_galley
|
||||
*
|
||||
* @brief Handle issues grid requests.
|
||||
*/
|
||||
|
||||
namespace APP\controllers\grid\issueGalleys;
|
||||
|
||||
use APP\controllers\grid\issues\form\IssueGalleyForm;
|
||||
use APP\core\Application;
|
||||
use APP\core\Request;
|
||||
use APP\file\IssueFileManager;
|
||||
use APP\issue\IssueGalleyDAO;
|
||||
use APP\security\authorization\OjsIssueGalleyRequiredPolicy;
|
||||
use APP\security\authorization\OjsIssueRequiredPolicy;
|
||||
use PKP\controllers\grid\feature\OrderGridItemsFeature;
|
||||
use PKP\controllers\grid\GridColumn;
|
||||
use PKP\controllers\grid\GridHandler;
|
||||
use PKP\core\JSONMessage;
|
||||
use PKP\db\DAO;
|
||||
use PKP\db\DAORegistry;
|
||||
use PKP\file\TemporaryFileManager;
|
||||
use PKP\linkAction\LinkAction;
|
||||
use PKP\linkAction\request\AjaxModal;
|
||||
use PKP\security\authorization\ContextAccessPolicy;
|
||||
use PKP\security\Role;
|
||||
|
||||
class IssueGalleyGridHandler extends GridHandler
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->addRoleAssignment(
|
||||
[Role::ROLE_ID_MANAGER, Role::ROLE_ID_SITE_ADMIN],
|
||||
[
|
||||
'fetchGrid', 'fetchRow', 'saveSequence',
|
||||
'add', 'edit', 'upload', 'download', 'update', 'delete'
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Implement template methods from PKPHandler
|
||||
//
|
||||
/**
|
||||
* @copydoc PKPHandler::authorize()
|
||||
*/
|
||||
public function authorize($request, &$args, $roleAssignments)
|
||||
{
|
||||
$this->addPolicy(new ContextAccessPolicy($request, $roleAssignments));
|
||||
|
||||
$this->addPolicy(new OjsIssueRequiredPolicy($request, $args));
|
||||
|
||||
// If a signoff ID was specified, authorize it.
|
||||
if ($request->getUserVar('issueGalleyId')) {
|
||||
$this->addPolicy(new OjsIssueGalleyRequiredPolicy($request, $args));
|
||||
}
|
||||
|
||||
return parent::authorize($request, $args, $roleAssignments);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::getDataElementSequence()
|
||||
*/
|
||||
public function getDataElementSequence($issueGalley)
|
||||
{
|
||||
return $issueGalley->getSequence();
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::setDataElementSequence()
|
||||
*/
|
||||
public function setDataElementSequence($request, $rowId, $gridDataElement, $newSequence)
|
||||
{
|
||||
$issueGalleyDao = DAORegistry::getDAO('IssueGalleyDAO'); /** @var IssueGalleyDAO $issueGalleyDao */
|
||||
$gridDataElement->setSequence($newSequence);
|
||||
$issueGalleyDao->updateObject($gridDataElement);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::addFeatures()
|
||||
*/
|
||||
public function initFeatures($request, $args)
|
||||
{
|
||||
return [new OrderGridItemsFeature()];
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridDataProvider::getRequestArgs()
|
||||
*/
|
||||
public function getRequestArgs()
|
||||
{
|
||||
$issue = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_ISSUE);
|
||||
$issueGalley = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_ISSUE_GALLEY);
|
||||
$requestArgs = (array) parent::getRequestArgs();
|
||||
$requestArgs['issueId'] = $issue->getId();
|
||||
if ($issueGalley) {
|
||||
$requestArgs['issueGalleyId'] = $issueGalley->getId();
|
||||
}
|
||||
return $requestArgs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::initialize()
|
||||
*
|
||||
* @param null|mixed $args
|
||||
*/
|
||||
public function initialize($request, $args = null)
|
||||
{
|
||||
parent::initialize($request, $args);
|
||||
|
||||
// Add action
|
||||
$router = $request->getRouter();
|
||||
$this->addAction(
|
||||
new LinkAction(
|
||||
'add',
|
||||
new AjaxModal(
|
||||
$router->url(
|
||||
$request,
|
||||
null,
|
||||
null,
|
||||
'add',
|
||||
null,
|
||||
array_merge($this->getRequestArgs(), ['gridId' => $this->getId()])
|
||||
),
|
||||
__('grid.action.addIssueGalley'),
|
||||
'modal_add'
|
||||
),
|
||||
__('grid.action.addIssueGalley'),
|
||||
'add_category'
|
||||
)
|
||||
);
|
||||
|
||||
// Grid columns.
|
||||
$issueGalleyGridCellProvider = new IssueGalleyGridCellProvider();
|
||||
|
||||
// Issue identification
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'label',
|
||||
'submission.layout.galleyLabel',
|
||||
null,
|
||||
null,
|
||||
$issueGalleyGridCellProvider
|
||||
)
|
||||
);
|
||||
|
||||
// Language, if more than one is supported
|
||||
$journal = $request->getJournal();
|
||||
if (count($journal->getSupportedLocaleNames()) > 1) {
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'locale',
|
||||
'common.language',
|
||||
null,
|
||||
null,
|
||||
$issueGalleyGridCellProvider
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Public ID, if enabled
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'publicGalleyId',
|
||||
'submission.publisherId',
|
||||
null,
|
||||
null,
|
||||
$issueGalleyGridCellProvider
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the row handler - override the default row handler
|
||||
*
|
||||
* @return IssueGalleyGridRow
|
||||
*/
|
||||
protected function getRowInstance()
|
||||
{
|
||||
$issue = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_ISSUE);
|
||||
return new IssueGalleyGridRow($issue->getId());
|
||||
}
|
||||
|
||||
//
|
||||
// Public operations
|
||||
//
|
||||
/**
|
||||
* An action to add a new issue
|
||||
*
|
||||
* @param array $args
|
||||
* @param Request $request
|
||||
*/
|
||||
public function add($args, $request)
|
||||
{
|
||||
// Calling editIssueData with an empty ID will add
|
||||
// a new issue.
|
||||
return $this->edit($args, $request);
|
||||
}
|
||||
|
||||
/**
|
||||
* An action to edit a issue galley
|
||||
*
|
||||
* @param array $args
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function edit($args, $request)
|
||||
{
|
||||
$issue = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_ISSUE);
|
||||
$issueGalley = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_ISSUE_GALLEY);
|
||||
|
||||
$issueGalleyForm = new IssueGalleyForm($request, $issue, $issueGalley);
|
||||
$issueGalleyForm->initData();
|
||||
return new JSONMessage(true, $issueGalleyForm->fetch($request));
|
||||
}
|
||||
|
||||
/**
|
||||
* An action to upload an issue galley file.
|
||||
*
|
||||
* @param array $args
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function upload($args, $request)
|
||||
{
|
||||
$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'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An action to download an issue galley
|
||||
*
|
||||
* @param array $args
|
||||
* @param Request $request
|
||||
*
|
||||
* @return string Serialized JSON object
|
||||
*/
|
||||
public function download($args, $request)
|
||||
{
|
||||
$issue = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_ISSUE);
|
||||
$issueGalley = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_ISSUE_GALLEY);
|
||||
$issueFileManager = new IssueFileManager($issue->getId());
|
||||
return $issueFileManager->downloadById($issueGalley->getFileId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a issue
|
||||
*
|
||||
* @param array $args
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function update($args, $request)
|
||||
{
|
||||
$issue = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_ISSUE);
|
||||
$issueGalley = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_ISSUE_GALLEY);
|
||||
|
||||
$issueGalleyForm = new IssueGalleyForm($request, $issue, $issueGalley);
|
||||
$issueGalleyForm->readInputData();
|
||||
|
||||
if ($issueGalleyForm->validate()) {
|
||||
$issueId = $issueGalleyForm->execute();
|
||||
return DAO::getDataChangedEvent($issueId);
|
||||
}
|
||||
return new JSONMessage(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an issue galley
|
||||
*
|
||||
* @param array $args
|
||||
* @param Request $request
|
||||
*/
|
||||
public function delete($args, $request)
|
||||
{
|
||||
$issueGalleyDao = DAORegistry::getDAO('IssueGalleyDAO'); /** @var IssueGalleyDAO $issueGalleyDao */
|
||||
$issueGalley = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_ISSUE_GALLEY);
|
||||
if ($issueGalley && $request->checkCSRF()) {
|
||||
$issueGalleyDao->deleteObject($issueGalley);
|
||||
return DAO::getDataChangedEvent();
|
||||
}
|
||||
return new JSONMessage(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::loadData
|
||||
*/
|
||||
protected function loadData($request, $filter)
|
||||
{
|
||||
$issue = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_ISSUE);
|
||||
$issueGalleyDao = DAORegistry::getDAO('IssueGalleyDAO'); /** @var IssueGalleyDAO $issueGalleyDao */
|
||||
return $issueGalleyDao->getByIssueId($issue->getId());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/issueGalleys/IssueGalleyGridRow.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 IssueGalleyGridRow
|
||||
*
|
||||
* @ingroup issue_galley
|
||||
*
|
||||
* @brief Handle issue galley grid row requests.
|
||||
*/
|
||||
|
||||
namespace APP\controllers\grid\issueGalleys;
|
||||
|
||||
use PKP\controllers\grid\GridRow;
|
||||
use PKP\linkAction\LinkAction;
|
||||
use PKP\linkAction\request\AjaxModal;
|
||||
use PKP\linkAction\request\RemoteActionConfirmationModal;
|
||||
|
||||
class IssueGalleyGridRow extends GridRow
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct($issueId)
|
||||
{
|
||||
parent::__construct();
|
||||
$this->setRequestArgs(
|
||||
array_merge(
|
||||
((array) $this->getRequestArgs()),
|
||||
['issueId' => $issueId]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// Overridden template methods
|
||||
//
|
||||
/**
|
||||
* @copydoc GridRow::initialize
|
||||
*
|
||||
* @param null|mixed $template
|
||||
*/
|
||||
public function initialize($request, $template = null)
|
||||
{
|
||||
parent::initialize($request, $template);
|
||||
|
||||
// Is this a new row or an existing row?
|
||||
$issueGalleyId = $this->getId();
|
||||
if (!empty($issueGalleyId) && is_numeric($issueGalleyId)) {
|
||||
$issue = $this->getData();
|
||||
assert(is_a($issue, 'IssueGalley'));
|
||||
$router = $request->getRouter();
|
||||
|
||||
$this->addAction(
|
||||
new LinkAction(
|
||||
'edit',
|
||||
new AjaxModal(
|
||||
$router->url(
|
||||
$request,
|
||||
null,
|
||||
null,
|
||||
'edit',
|
||||
null,
|
||||
array_merge($this->getRequestArgs(), ['issueGalleyId' => $issueGalleyId])
|
||||
),
|
||||
__('editor.issues.editIssueGalley'),
|
||||
'modal_edit',
|
||||
true
|
||||
),
|
||||
__('grid.action.edit'),
|
||||
'edit'
|
||||
)
|
||||
);
|
||||
|
||||
$this->addAction(
|
||||
new LinkAction(
|
||||
'delete',
|
||||
new RemoteActionConfirmationModal(
|
||||
$request->getSession(),
|
||||
__('common.confirmDelete'),
|
||||
__('grid.action.delete'),
|
||||
$router->url(
|
||||
$request,
|
||||
null,
|
||||
null,
|
||||
'delete',
|
||||
null,
|
||||
array_merge($this->getRequestArgs(), ['issueGalleyId' => $issueGalleyId])
|
||||
),
|
||||
'modal_delete'
|
||||
),
|
||||
__('grid.action.delete'),
|
||||
'delete'
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/issues/IssueGridHandler.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 BackIssueGridHandler
|
||||
*
|
||||
* @ingroup controllers_grid_issues
|
||||
*
|
||||
* @brief Handle issues grid requests.
|
||||
*/
|
||||
|
||||
namespace APP\controllers\grid\issues;
|
||||
|
||||
use APP\facades\Repo;
|
||||
use APP\issue\Collector;
|
||||
use PKP\controllers\grid\feature\OrderGridItemsFeature;
|
||||
use PKP\controllers\grid\GridColumn;
|
||||
use PKP\security\Role;
|
||||
|
||||
class BackIssueGridHandler extends IssueGridHandler
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->addRoleAssignment(
|
||||
[Role::ROLE_ID_MANAGER, Role::ROLE_ID_SITE_ADMIN],
|
||||
['saveSequence']
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Implement template methods from PKPHandler
|
||||
//
|
||||
/**
|
||||
* @copydoc IssueGridHandler::initialize()
|
||||
*
|
||||
* @param null|mixed $args
|
||||
*/
|
||||
public function initialize($request, $args = null)
|
||||
{
|
||||
parent::initialize($request, $args);
|
||||
|
||||
// Basic grid configuration.
|
||||
$this->setTitle('editor.issues.backIssues');
|
||||
}
|
||||
|
||||
/**
|
||||
* Private function to add central columns to the grid.
|
||||
*
|
||||
* @param IssueGridCellProvider $issueGridCellProvider
|
||||
*/
|
||||
protected function _addCenterColumns($issueGridCellProvider)
|
||||
{
|
||||
// Published state
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'published',
|
||||
'editor.issues.published',
|
||||
null,
|
||||
null,
|
||||
$issueGridCellProvider
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::setDataElementSequence()
|
||||
*/
|
||||
public function setDataElementSequence($request, $rowId, $gridDataElement, $newSequence)
|
||||
{
|
||||
Repo::issue()->dao->moveCustomIssueOrder($gridDataElement->getJournalId(), $gridDataElement->getId(), $newSequence);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::getDataElementSequence()
|
||||
*/
|
||||
public function getDataElementSequence($gridDataElement)
|
||||
{
|
||||
$customOrder = Repo::issue()->dao->getCustomIssueOrder($gridDataElement->getJournalId(), $gridDataElement->getId());
|
||||
if ($customOrder !== null) {
|
||||
return $customOrder;
|
||||
}
|
||||
|
||||
$currentIssue = Repo::issue()->getCurrent($gridDataElement->getJournalId());
|
||||
if ($currentIssue != null && $gridDataElement->getId() == $currentIssue->getId()) {
|
||||
return 0;
|
||||
}
|
||||
return $gridDataElement->getDatePublished();
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::addFeatures()
|
||||
*/
|
||||
public function initFeatures($request, $args)
|
||||
{
|
||||
return [new OrderGridItemsFeature()];
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::loadData()
|
||||
*/
|
||||
protected function loadData($request, $filter)
|
||||
{
|
||||
$journal = $request->getJournal();
|
||||
return Repo::issue()->getCollector()
|
||||
->filterByContextIds([$journal->getId()])
|
||||
->filterByPublished(true)
|
||||
->orderBy(Collector::ORDERBY_PUBLISHED_ISSUES)
|
||||
->getMany()
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the js handler for this component.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getJSHandler()
|
||||
{
|
||||
return '$.pkp.controllers.grid.issues.BackIssueGridHandler';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/issues/IssueGridHandler.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 ExportableIssuesListGridHandler
|
||||
*
|
||||
* @ingroup controllers_grid_issues
|
||||
*
|
||||
* @brief Handle exportable issues grid requests.
|
||||
*/
|
||||
|
||||
namespace APP\controllers\grid\issues;
|
||||
|
||||
use APP\facades\Repo;
|
||||
use PKP\controllers\grid\feature\PagingFeature;
|
||||
use PKP\controllers\grid\feature\selectableItems\SelectableItemsFeature;
|
||||
use PKP\controllers\grid\GridRow;
|
||||
|
||||
class ExportableIssuesListGridHandler extends IssueGridHandler
|
||||
{
|
||||
//
|
||||
// Implemented methods from GridHandler.
|
||||
//
|
||||
/**
|
||||
* @copydoc GridHandler::isDataElementSelected()
|
||||
*/
|
||||
public function isDataElementSelected($gridDataElement)
|
||||
{
|
||||
return false; // Nothing is selected by default
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::getSelectName()
|
||||
*/
|
||||
public function getSelectName()
|
||||
{
|
||||
return 'selectedIssues';
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::loadData()
|
||||
*/
|
||||
protected function loadData($request, $filter)
|
||||
{
|
||||
$journal = $request->getJournal();
|
||||
|
||||
// Handle grid paging (deprecated style)
|
||||
|
||||
$rangeInfo = $this->getGridRangeInfo($request, $this->getId());
|
||||
$collector = Repo::issue()->getCollector()
|
||||
->filterByContextIds([$journal->getId()]);
|
||||
|
||||
$totalCount = $collector->getCount();
|
||||
$collector->limit($rangeInfo->getCount());
|
||||
$collector->offset($rangeInfo->getOffset() + max(0, $rangeInfo->getPage() - 1) * $rangeInfo->getCount());
|
||||
|
||||
return new \PKP\core\VirtualArrayIterator($collector->getMany()->toArray(), $totalCount, $rangeInfo->getPage(), $rangeInfo->getCount());
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::initFeatures()
|
||||
*/
|
||||
public function initFeatures($request, $args)
|
||||
{
|
||||
return [new SelectableItemsFeature(), new PagingFeature()];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the row handler - override the parent row handler. We do not need grid row actions.
|
||||
*
|
||||
* @return GridRow
|
||||
*/
|
||||
protected function getRowInstance()
|
||||
{
|
||||
return new GridRow();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/issues/IssueGridHandler.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 FutureIssueGridHandler
|
||||
*
|
||||
* @ingroup controllers_grid_issues
|
||||
*
|
||||
* @brief Handle issues grid requests.
|
||||
*/
|
||||
|
||||
namespace APP\controllers\grid\issues;
|
||||
|
||||
use APP\facades\Repo;
|
||||
use APP\issue\Collector;
|
||||
use PKP\linkAction\LinkAction;
|
||||
use PKP\linkAction\request\AjaxModal;
|
||||
|
||||
class FutureIssueGridHandler extends IssueGridHandler
|
||||
{
|
||||
//
|
||||
// Implement template methods from PKPHandler
|
||||
//
|
||||
/**
|
||||
* @copydoc IssueGridHandler::initialize()
|
||||
*
|
||||
* @param null|mixed $args
|
||||
*/
|
||||
public function initialize($request, $args = null)
|
||||
{
|
||||
// Basic grid configuration.
|
||||
$this->setTitle('editor.issues.futureIssues');
|
||||
|
||||
parent::initialize($request, $args);
|
||||
|
||||
// Add Create Issue action
|
||||
$router = $request->getRouter();
|
||||
$this->addAction(
|
||||
new LinkAction(
|
||||
'addIssue',
|
||||
new AjaxModal(
|
||||
$router->url($request, null, null, 'addIssue', null, ['gridId' => $this->getId()]),
|
||||
__('grid.action.addIssue'),
|
||||
'modal_manage'
|
||||
),
|
||||
__('grid.action.addIssue'),
|
||||
'add_category'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::loadData()
|
||||
*/
|
||||
protected function loadData($request, $filter)
|
||||
{
|
||||
$journal = $request->getJournal();
|
||||
return Repo::issue()->getCollector()
|
||||
->filterByContextIds([$journal->getId()])
|
||||
->filterByPublished(false)
|
||||
->orderBy(Collector::ORDERBY_UNPUBLISHED_ISSUES)
|
||||
->getMany();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the js handler for this component.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getJSHandler()
|
||||
{
|
||||
return '$.pkp.controllers.grid.issues.FutureIssueGridHandler';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/issues/IssueGridCellProvider.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 IssueGridCellProvider
|
||||
*
|
||||
* @ingroup controllers_grid_issues
|
||||
*
|
||||
* @brief Grid cell provider for the issue management grid
|
||||
*/
|
||||
|
||||
namespace APP\controllers\grid\issues;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\issue\Issue;
|
||||
use PKP\controllers\grid\GridCellProvider;
|
||||
use PKP\controllers\grid\GridColumn;
|
||||
use PKP\controllers\grid\GridHandler;
|
||||
use PKP\core\PKPString;
|
||||
use PKP\linkAction\LinkAction;
|
||||
use PKP\linkAction\request\AjaxModal;
|
||||
|
||||
class IssueGridCellProvider extends GridCellProvider
|
||||
{
|
||||
/** @var string */
|
||||
public $dateFormatShort;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->dateFormatShort = PKPString::convertStrftimeFormat(Application::get()->getRequest()->getContext()->getLocalizedDateFormatShort());
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
if ($column->getId() == 'identification') {
|
||||
$issue = $row->getData();
|
||||
assert(is_a($issue, 'Issue'));
|
||||
$router = $request->getRouter();
|
||||
return [
|
||||
new LinkAction(
|
||||
'edit',
|
||||
new AjaxModal(
|
||||
$router->url($request, null, null, 'editIssue', null, ['issueId' => $issue->getId()]),
|
||||
__('editor.issues.editIssue', ['issueIdentification' => htmlspecialchars($issue->getIssueIdentification())]),
|
||||
'modal_edit',
|
||||
true
|
||||
),
|
||||
$issue->getIssueIdentification()
|
||||
)
|
||||
];
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
$issue = $row->getData(); /** @var Issue $issue */
|
||||
$columnId = $column->getId();
|
||||
assert(is_a($issue, 'Issue'));
|
||||
assert(!empty($columnId));
|
||||
switch ($columnId) {
|
||||
case 'identification':
|
||||
return ['label' => '']; // Title returned as action
|
||||
case 'published':
|
||||
$datePublished = $issue->getDatePublished();
|
||||
if ($datePublished) {
|
||||
$datePublished = strtotime($datePublished);
|
||||
}
|
||||
return ['label' => $datePublished ? date($this->dateFormatShort, $datePublished) : ''];
|
||||
case 'numArticles':
|
||||
return ['label' => $issue->getNumArticles()];
|
||||
default: assert(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/issues/IssueGridRow.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 IssueGridRow
|
||||
*
|
||||
* @ingroup controllers_grid_issues
|
||||
*
|
||||
* @brief Handle issue grid row requests.
|
||||
*/
|
||||
|
||||
namespace APP\controllers\grid\issues;
|
||||
|
||||
use APP\facades\Repo;
|
||||
use PKP\controllers\grid\GridRow;
|
||||
use PKP\core\PKPApplication;
|
||||
use PKP\linkAction\LinkAction;
|
||||
use PKP\linkAction\request\AjaxModal;
|
||||
use PKP\linkAction\request\OpenWindowAction;
|
||||
use PKP\linkAction\request\RemoteActionConfirmationModal;
|
||||
|
||||
class IssueGridRow extends GridRow
|
||||
{
|
||||
//
|
||||
// Overridden template methods
|
||||
//
|
||||
/**
|
||||
* @copydoc GridRow::initialize
|
||||
*
|
||||
* @param null|mixed $template
|
||||
*/
|
||||
public function initialize($request, $template = null)
|
||||
{
|
||||
parent::initialize($request, $template);
|
||||
|
||||
// Is this a new row or an existing row?
|
||||
$issueId = $this->getId();
|
||||
if (!empty($issueId) && is_numeric($issueId)) {
|
||||
$issue = $this->getData();
|
||||
assert(is_a($issue, 'Issue'));
|
||||
$router = $request->getRouter();
|
||||
|
||||
$this->addAction(
|
||||
new LinkAction(
|
||||
'edit',
|
||||
new AjaxModal(
|
||||
$router->url($request, null, null, 'editIssue', null, ['issueId' => $issueId]),
|
||||
__('editor.issues.editIssue', ['issueIdentification' => htmlspecialchars($issue->getIssueIdentification())]),
|
||||
'modal_edit',
|
||||
true
|
||||
),
|
||||
__('grid.action.edit'),
|
||||
'edit'
|
||||
)
|
||||
);
|
||||
|
||||
$dispatcher = $request->getDispatcher();
|
||||
$this->addAction(
|
||||
new LinkAction(
|
||||
$issue->getDatePublished() ? 'viewIssue' : 'previewIssue',
|
||||
new OpenWindowAction(
|
||||
$dispatcher->url($request, PKPApplication::ROUTE_PAGE, null, 'issue', 'view', [$issueId])
|
||||
),
|
||||
__($issue->getDatePublished() ? 'grid.action.viewIssue' : 'grid.action.previewIssue'),
|
||||
'information'
|
||||
)
|
||||
);
|
||||
|
||||
if ($issue->getDatePublished()) {
|
||||
$this->addAction(
|
||||
new LinkAction(
|
||||
'unpublish',
|
||||
new RemoteActionConfirmationModal(
|
||||
$request->getSession(),
|
||||
__('editor.issues.confirmUnpublish'),
|
||||
__('editor.issues.unpublishIssue'),
|
||||
$router->url($request, null, null, 'unpublishIssue', null, ['issueId' => $issueId]),
|
||||
'modal_delete'
|
||||
),
|
||||
__('editor.issues.unpublishIssue'),
|
||||
'delete'
|
||||
)
|
||||
);
|
||||
} else {
|
||||
$this->addAction(
|
||||
new LinkAction(
|
||||
'publish',
|
||||
new AjaxModal(
|
||||
$router->url(
|
||||
$request,
|
||||
null,
|
||||
null,
|
||||
'publishIssue',
|
||||
null,
|
||||
['issueId' => $issueId]
|
||||
),
|
||||
__('editor.issues.publishIssue'),
|
||||
'modal_confirm'
|
||||
),
|
||||
__('editor.issues.publishIssue'),
|
||||
'advance'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$currentIssue = Repo::issue()->getCurrent($issue->getJournalId());
|
||||
$isCurrentIssue = $currentIssue != null && $issue->getId() == $currentIssue->getId();
|
||||
if ($issue->getDatePublished() && !$isCurrentIssue) {
|
||||
$this->addAction(
|
||||
new LinkAction(
|
||||
'setCurrentIssue',
|
||||
new RemoteActionConfirmationModal(
|
||||
$request->getSession(),
|
||||
__('editor.issues.confirmSetCurrentIssue'),
|
||||
__('editor.issues.currentIssue'),
|
||||
$router->url($request, null, null, 'setCurrentIssue', null, ['issueId' => $issueId]),
|
||||
'modal_delete'
|
||||
),
|
||||
__('editor.issues.currentIssue'),
|
||||
'delete'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$this->addAction(
|
||||
new LinkAction(
|
||||
'delete',
|
||||
new RemoteActionConfirmationModal(
|
||||
$request->getSession(),
|
||||
__('common.confirmDelete'),
|
||||
__('grid.action.delete'),
|
||||
$router->url($request, null, null, 'deleteIssue', null, ['issueId' => $issueId]),
|
||||
'modal_delete'
|
||||
),
|
||||
__('grid.action.delete'),
|
||||
'delete'
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/issues/form/IssueAccessForm.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 IssueAccessForm
|
||||
*
|
||||
* @ingroup controllers_grid_issues_form
|
||||
*
|
||||
* @see Issue
|
||||
*
|
||||
* @brief Form to edit an issue's access settings
|
||||
*/
|
||||
|
||||
namespace APP\controllers\grid\issues\form;
|
||||
|
||||
use APP\facades\Repo;
|
||||
use APP\issue\Issue;
|
||||
use APP\template\TemplateManager;
|
||||
use PKP\form\Form;
|
||||
use PKP\plugins\Hook;
|
||||
|
||||
class IssueAccessForm extends Form
|
||||
{
|
||||
/** @var Issue current issue */
|
||||
public $_issue;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param Issue $issue
|
||||
*/
|
||||
public function __construct($issue)
|
||||
{
|
||||
parent::__construct('controllers/grid/issues/form/issueAccessForm.tpl');
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorPost($this));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorCSRF($this));
|
||||
$this->_issue = $issue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::fetch()
|
||||
*
|
||||
* @param null|mixed $template
|
||||
*/
|
||||
public function fetch($request, $template = null, $display = false)
|
||||
{
|
||||
$templateMgr = TemplateManager::getManager($request);
|
||||
$templateMgr->assign([
|
||||
'accessOptions' => [
|
||||
Issue::ISSUE_ACCESS_OPEN => 'editor.issues.openAccess',
|
||||
Issue::ISSUE_ACCESS_SUBSCRIPTION => 'editor.issues.subscription',
|
||||
],
|
||||
'issueId' => $this->_issue->getId(),
|
||||
]);
|
||||
return parent::fetch($request, $template, $display);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize form data from current issue.
|
||||
*/
|
||||
public function initData()
|
||||
{
|
||||
$this->_data = [
|
||||
'accessStatus' => $this->_issue->getAccessStatus(),
|
||||
'openAccessDate' => $this->_issue->getOpenAccessDate(),
|
||||
];
|
||||
parent::initData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign form data to user-submitted data.
|
||||
*/
|
||||
public function readInputData()
|
||||
{
|
||||
$this->readUserVars([
|
||||
'accessStatus',
|
||||
'openAccessDate',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::execute()
|
||||
*
|
||||
* @return int Issue ID for created/updated issue
|
||||
*/
|
||||
public function execute(...$functionArgs)
|
||||
{
|
||||
$this->_issue->setAccessStatus($this->getData('accessStatus') ? $this->getData('accessStatus') : Issue::ISSUE_ACCESS_OPEN);
|
||||
if ($openAccessDate = $this->getData('openAccessDate')) {
|
||||
$this->_issue->setOpenAccessDate($openAccessDate);
|
||||
} else {
|
||||
$this->_issue->setOpenAccessDate(null);
|
||||
}
|
||||
|
||||
Hook::call('IssueAccessForm::execute', [$this, $this->_issue]);
|
||||
Repo::issue()->edit($this->_issue, []);
|
||||
parent::execute(...$functionArgs);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,281 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/issues/form/IssueForm.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 IssueForm
|
||||
*
|
||||
* @ingroup controllers_grid_issues_form
|
||||
*
|
||||
* @see Issue
|
||||
*
|
||||
* @brief Form to create or edit an issue
|
||||
*/
|
||||
|
||||
namespace APP\controllers\grid\issues\form;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\facades\Repo;
|
||||
use APP\file\PublicFileManager;
|
||||
use APP\issue\Issue;
|
||||
use APP\template\TemplateManager;
|
||||
use PKP\db\DAORegistry;
|
||||
use PKP\facades\Locale;
|
||||
use PKP\file\TemporaryFileDAO;
|
||||
use PKP\form\Form;
|
||||
use PKP\linkAction\LinkAction;
|
||||
use PKP\linkAction\request\RemoteActionConfirmationModal;
|
||||
|
||||
class IssueForm extends Form
|
||||
{
|
||||
/** @var Issue current issue */
|
||||
public $issue;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param Issue $issue (optional)
|
||||
*/
|
||||
public function __construct($issue = null)
|
||||
{
|
||||
parent::__construct('controllers/grid/issues/form/issueForm.tpl');
|
||||
|
||||
$form = $this;
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorRegExp($this, 'volume', 'optional', 'editor.issues.volumeRequired', '/^[0-9]+$/i'));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorCustom($this, 'showVolume', 'optional', 'editor.issues.volumeRequired', function ($showVolume) use ($form) {
|
||||
return !$showVolume || $form->getData('volume') ? true : false;
|
||||
}));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorCustom($this, 'showNumber', 'optional', 'editor.issues.numberRequired', function ($showNumber) use ($form) {
|
||||
return !$showNumber || $form->getData('number') ? true : false;
|
||||
}));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorCustom($this, 'showYear', 'optional', 'editor.issues.yearRequired', function ($showYear) use ($form) {
|
||||
return !$showYear || $form->getData('year') ? true : false;
|
||||
}));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorCustom($this, 'showTitle', 'optional', 'editor.issues.titleRequired', function ($showTitle) use ($form) {
|
||||
return !$showTitle || implode('', $form->getData('title')) != '' ? true : false;
|
||||
}));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorRegExp($this, 'urlPath', 'optional', 'validator.alpha_dash_period', '/^[a-zA-Z0-9]+([\\.\\-_][a-zA-Z0-9]+)*$/'));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorPost($this));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorCSRF($this));
|
||||
$this->issue = $issue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::fetch()
|
||||
*
|
||||
* @param null|mixed $template
|
||||
*/
|
||||
public function fetch($request, $template = null, $display = false)
|
||||
{
|
||||
if ($this->issue) {
|
||||
$templateMgr = TemplateManager::getManager($request);
|
||||
$templateMgr->assign([
|
||||
'issue' => $this->issue,
|
||||
'issueId' => $this->issue->getId(),
|
||||
]);
|
||||
|
||||
// Cover image delete link action
|
||||
if ($coverImage = $this->issue->getCoverImage(Locale::getLocale())) {
|
||||
$templateMgr->assign(
|
||||
'deleteCoverImageLinkAction',
|
||||
new LinkAction(
|
||||
'deleteCoverImage',
|
||||
new RemoteActionConfirmationModal(
|
||||
$request->getSession(),
|
||||
__('common.confirmDelete'),
|
||||
null,
|
||||
$request->getRouter()->url(
|
||||
$request,
|
||||
null,
|
||||
null,
|
||||
'deleteCoverImage',
|
||||
null,
|
||||
[
|
||||
'coverImage' => $coverImage,
|
||||
'issueId' => $this->issue->getId(),
|
||||
]
|
||||
),
|
||||
'modal_delete'
|
||||
),
|
||||
__('common.delete'),
|
||||
null
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return parent::fetch($request, $template, $display);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::validate()
|
||||
*/
|
||||
public function validate($callHooks = true)
|
||||
{
|
||||
if ($temporaryFileId = $this->getData('temporaryFileId')) {
|
||||
$request = Application::get()->getRequest();
|
||||
$user = $request->getUser();
|
||||
$temporaryFileDao = DAORegistry::getDAO('TemporaryFileDAO'); /** @var TemporaryFileDAO $temporaryFileDao */
|
||||
$temporaryFile = $temporaryFileDao->getTemporaryFile($temporaryFileId, $user->getId());
|
||||
|
||||
$publicFileManager = new PublicFileManager();
|
||||
if (!$publicFileManager->getImageExtension($temporaryFile->getFileType())) {
|
||||
$this->addError('coverImage', __('editor.issues.invalidCoverImageFormat'));
|
||||
}
|
||||
}
|
||||
|
||||
// Check if urlPath is already being used
|
||||
if (strlen((string) $this->getData('urlPath'))) {
|
||||
if (ctype_digit((string) $this->getData('urlPath'))) {
|
||||
$this->addError('urlPath', __('publication.urlPath.numberInvalid'));
|
||||
$this->addErrorField('urlPath');
|
||||
} else {
|
||||
$issue = Repo::issue()->getByBestId($this->getData('urlPath'), Application::get()->getRequest()->getContext()->getId());
|
||||
if ($issue && $this->issue?->getId() !== $issue->getId()) {
|
||||
$this->addError('urlPath', __('publication.urlPath.duplicate'));
|
||||
$this->addErrorField('urlPath');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return parent::validate($callHooks);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::initData()
|
||||
*/
|
||||
public function initData()
|
||||
{
|
||||
if (isset($this->issue)) {
|
||||
$locale = Locale::getLocale();
|
||||
$this->_data = [
|
||||
'title' => $this->issue->getTitle(null), // Localized
|
||||
'volume' => $this->issue->getVolume(),
|
||||
'number' => $this->issue->getNumber(),
|
||||
'year' => $this->issue->getYear(),
|
||||
'datePublished' => $this->issue->getDatePublished(),
|
||||
'description' => $this->issue->getDescription(null), // Localized
|
||||
'showVolume' => $this->issue->getShowVolume(),
|
||||
'showNumber' => $this->issue->getShowNumber(),
|
||||
'showYear' => $this->issue->getShowYear(),
|
||||
'showTitle' => $this->issue->getShowTitle(),
|
||||
'coverImage' => $this->issue->getCoverImage($locale),
|
||||
'coverImageAltText' => $this->issue->getCoverImageAltText($locale),
|
||||
'urlPath' => $this->issue->getData('urlPath'),
|
||||
];
|
||||
parent::initData();
|
||||
} else {
|
||||
$this->_data = [
|
||||
'showVolume' => 1,
|
||||
'showNumber' => 1,
|
||||
'showYear' => 1,
|
||||
'showTitle' => 1,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign form data to user-submitted data.
|
||||
*/
|
||||
public function readInputData()
|
||||
{
|
||||
$this->readUserVars([
|
||||
'title',
|
||||
'volume',
|
||||
'number',
|
||||
'year',
|
||||
'description',
|
||||
'showVolume',
|
||||
'showNumber',
|
||||
'showYear',
|
||||
'showTitle',
|
||||
'temporaryFileId',
|
||||
'coverImageAltText',
|
||||
'datePublished',
|
||||
'urlPath',
|
||||
]);
|
||||
|
||||
$form = $this;
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorCustom($this, 'issueForm', 'required', 'editor.issues.issueIdentificationRequired', function () use ($form) {
|
||||
return $form->getData('showVolume') || $form->getData('showNumber') || $form->getData('showYear') || $form->getData('showTitle');
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* Save issue settings.
|
||||
*/
|
||||
public function execute(...$functionArgs)
|
||||
{
|
||||
$request = Application::get()->getRequest();
|
||||
$journal = $request->getJournal();
|
||||
|
||||
if ($this->issue) {
|
||||
$isNewIssue = false;
|
||||
$issue = $this->issue;
|
||||
} else {
|
||||
$issue = Repo::issue()->newDataObject();
|
||||
$this->issue = $issue;
|
||||
switch ($journal->getData('publishingMode')) {
|
||||
case \APP\journal\Journal::PUBLISHING_MODE_SUBSCRIPTION:
|
||||
case \APP\journal\Journal::PUBLISHING_MODE_NONE:
|
||||
$issue->setAccessStatus(Issue::ISSUE_ACCESS_SUBSCRIPTION);
|
||||
break;
|
||||
case \APP\journal\Journal::PUBLISHING_MODE_OPEN:
|
||||
default:
|
||||
$issue->setAccessStatus(Issue::ISSUE_ACCESS_OPEN);
|
||||
break;
|
||||
}
|
||||
$isNewIssue = true;
|
||||
}
|
||||
$volume = $this->getData('volume');
|
||||
$number = $this->getData('number');
|
||||
$year = $this->getData('year');
|
||||
|
||||
$issue->setJournalId($journal->getId());
|
||||
$issue->setTitle($this->getData('title'), null); // Localized
|
||||
$issue->setVolume(empty($volume) ? null : $volume);
|
||||
$issue->setNumber(empty($number) ? null : $number);
|
||||
$issue->setYear(empty($year) ? null : $year);
|
||||
if (!$isNewIssue) {
|
||||
$issue->setDatePublished($this->getData('datePublished'));
|
||||
}
|
||||
$issue->setDescription($this->getData('description'), null); // Localized
|
||||
$issue->setShowVolume((int) $this->getData('showVolume'));
|
||||
$issue->setShowNumber((int) $this->getData('showNumber'));
|
||||
$issue->setShowYear((int) $this->getData('showYear'));
|
||||
$issue->setShowTitle((int) $this->getData('showTitle'));
|
||||
$issue->setData('urlPath', strlen($urlPath = (string) $this->getData('urlPath')) ? $urlPath : null);
|
||||
|
||||
// If it is a new issue, first insert it, then update the cover
|
||||
// because the cover name needs an issue id.
|
||||
if ($isNewIssue) {
|
||||
$issue->setPublished(0);
|
||||
Repo::issue()->add($issue);
|
||||
}
|
||||
|
||||
$locale = Locale::getLocale();
|
||||
// Copy an uploaded cover file for the issue, if there is one.
|
||||
if ($temporaryFileId = $this->getData('temporaryFileId')) {
|
||||
$user = $request->getUser();
|
||||
$temporaryFileDao = DAORegistry::getDAO('TemporaryFileDAO'); /** @var TemporaryFileDAO $temporaryFileDao */
|
||||
$temporaryFile = $temporaryFileDao->getTemporaryFile($temporaryFileId, $user->getId());
|
||||
|
||||
$publicFileManager = new PublicFileManager();
|
||||
$newFileName = 'cover_issue_' . $issue->getId() . '_' . $locale . $publicFileManager->getImageExtension($temporaryFile->getFileType());
|
||||
$journal = $request->getJournal();
|
||||
$publicFileManager->copyContextFile($journal->getId(), $temporaryFile->getFilePath(), $newFileName);
|
||||
$issue->setCoverImage($newFileName, $locale);
|
||||
Repo::issue()->edit($issue, []);
|
||||
}
|
||||
|
||||
$issue->setCoverImageAltText($this->getData('coverImageAltText'), $locale);
|
||||
|
||||
parent::execute(...$functionArgs);
|
||||
|
||||
Repo::issue()->edit($issue, []);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,237 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/issues/form/IssueGalleyForm.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 IssueGalleyForm
|
||||
*
|
||||
* @ingroup issue_galley
|
||||
*
|
||||
* @see IssueGalley
|
||||
*
|
||||
* @brief Issue galley editing form.
|
||||
*/
|
||||
|
||||
namespace APP\controllers\grid\issues\form;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\core\Request;
|
||||
use APP\file\IssueFileManager;
|
||||
use APP\issue\Issue;
|
||||
use APP\issue\IssueGalley;
|
||||
use APP\issue\IssueGalleyDAO;
|
||||
use APP\journal\JournalDAO;
|
||||
use APP\template\TemplateManager;
|
||||
use PKP\db\DAORegistry;
|
||||
use PKP\file\TemporaryFileDAO;
|
||||
use PKP\form\Form;
|
||||
|
||||
class IssueGalleyForm extends Form
|
||||
{
|
||||
/** @var Issue the issue the galley belongs to */
|
||||
public $_issue = null;
|
||||
|
||||
/** @var IssueGalley current galley */
|
||||
public $_issueGalley = null;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param Issue $issue
|
||||
* @param IssueGalley $issueGalley (optional)
|
||||
*/
|
||||
public function __construct($request, $issue, $issueGalley = null)
|
||||
{
|
||||
parent::__construct('controllers/grid/issueGalleys/form/issueGalleyForm.tpl');
|
||||
$this->_issue = $issue;
|
||||
$this->_issueGalley = $issueGalley;
|
||||
|
||||
$this->addCheck(new \PKP\form\validation\FormValidator($this, 'label', 'required', 'editor.issues.galleyLabelRequired'));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorRegExp($this, 'urlPath', 'optional', 'validator.alpha_dash_period', '/^[a-zA-Z0-9]+([\\.\\-_][a-zA-Z0-9]+)*$/'));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorPost($this));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorCSRF($this));
|
||||
|
||||
// Ensure a locale is provided and valid
|
||||
$journal = $request->getJournal();
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorCustom(
|
||||
$this,
|
||||
'galleyLocale',
|
||||
'required',
|
||||
'editor.issues.galleyLocaleRequired',
|
||||
function ($galleyLocale) use ($journal) {
|
||||
return in_array($galleyLocale, $journal->getSupportedFormLocales());
|
||||
}
|
||||
));
|
||||
|
||||
if (!$issueGalley) {
|
||||
// A file must be uploaded with a newly-created issue galley.
|
||||
$this->addCheck(new \PKP\form\validation\FormValidator($this, 'temporaryFileId', 'required', 'form.fileRequired'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::fetch()
|
||||
*
|
||||
* @param Request $request
|
||||
* @param null|mixed $template
|
||||
*/
|
||||
public function fetch($request, $template = null, $display = false)
|
||||
{
|
||||
$journal = $request->getJournal();
|
||||
$templateMgr = TemplateManager::getManager($request);
|
||||
|
||||
$templateMgr->assign([
|
||||
'issueId' => $this->_issue->getId(),
|
||||
'supportedLocales' => $journal->getSupportedLocaleNames(),
|
||||
'enablePublisherId' => in_array('issueGalley', (array) $request->getContext()->getData('enablePublisherId')),
|
||||
]);
|
||||
if ($this->_issueGalley) {
|
||||
$templateMgr->assign([
|
||||
'issueGalleyId' => $this->_issueGalley->getId(),
|
||||
'issueGalley' => $this->_issueGalley,
|
||||
]);
|
||||
}
|
||||
|
||||
return parent::fetch($request, $template, $display);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::validate
|
||||
*/
|
||||
public function validate($callHooks = true)
|
||||
{
|
||||
// Check if public galley ID is already being used
|
||||
$request = Application::get()->getRequest();
|
||||
$journal = $request->getJournal();
|
||||
$journalDao = DAORegistry::getDAO('JournalDAO'); /** @var JournalDAO $journalDao */
|
||||
|
||||
$publicGalleyId = $this->getData('publicGalleyId');
|
||||
if ($publicGalleyId) {
|
||||
if (ctype_digit((string) $publicGalleyId)) {
|
||||
$this->addError('publicGalleyId', __('editor.publicIdentificationNumericNotAllowed', ['publicIdentifier' => $publicGalleyId]));
|
||||
$this->addErrorField('publicGalleyId');
|
||||
} elseif ($journalDao->anyPubIdExists($journal->getId(), 'publisher-id', $publicGalleyId, Application::ASSOC_TYPE_ISSUE_GALLEY, $this->_issueGalley ? $this->_issueGalley->getId() : null, true)) {
|
||||
$this->addError('publicGalleyId', __('editor.publicIdentificationExistsForTheSameType', ['publicIdentifier' => $publicGalleyId]));
|
||||
$this->addErrorField('publicGalleyId');
|
||||
}
|
||||
}
|
||||
|
||||
if (strlen((string) $this->getData('urlPath'))) {
|
||||
if (ctype_digit((string) $this->getData('urlPath'))) {
|
||||
$this->addError('urlPath', __('publication.urlPath.numberInvalid'));
|
||||
$this->addErrorField('urlPath');
|
||||
} else {
|
||||
$issueGalleyDao = DAORegistry::getDAO('IssueGalleyDAO'); /** @var IssueGalleyDAO $issueGalleyDao */
|
||||
$issueGalley = $issueGalleyDao->getByBestId($this->getData('urlPath'), $this->_issue->getId());
|
||||
if ($issueGalley && $this->_issueGalley?->getId() !== $issueGalley->getId()) {
|
||||
$this->addError('urlPath', __('publication.urlPath.duplicate'));
|
||||
$this->addErrorField('urlPath');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return parent::validate($callHooks);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize form data from current galley (if applicable).
|
||||
*/
|
||||
public function initData()
|
||||
{
|
||||
if ($this->_issueGalley) {
|
||||
$this->_data = [
|
||||
'label' => $this->_issueGalley->getLabel(),
|
||||
'publicGalleyId' => $this->_issueGalley->getStoredPubId('publisher-id'),
|
||||
'galleyLocale' => $this->_issueGalley->getLocale(),
|
||||
'urlPath' => $this->_issueGalley->getData('urlPath'),
|
||||
];
|
||||
} else {
|
||||
$this->_data = [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign form data to user-submitted data.
|
||||
*/
|
||||
public function readInputData()
|
||||
{
|
||||
$this->readUserVars(
|
||||
[
|
||||
'label',
|
||||
'publicGalleyId',
|
||||
'galleyLocale',
|
||||
'temporaryFileId',
|
||||
'urlPath',
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::execute()
|
||||
*/
|
||||
public function execute(...$functionArgs)
|
||||
{
|
||||
$issueFileManager = new IssueFileManager($this->_issue->getId());
|
||||
|
||||
$request = Application::get()->getRequest();
|
||||
$user = $request->getUser();
|
||||
|
||||
$issueGalley = $this->_issueGalley;
|
||||
$issueGalleyDao = DAORegistry::getDAO('IssueGalleyDAO'); /** @var IssueGalleyDAO $issueGalleyDao */
|
||||
|
||||
// If a temporary file ID was specified (i.e. an upload occurred), get the file for later.
|
||||
$temporaryFileDao = DAORegistry::getDAO('TemporaryFileDAO'); /** @var TemporaryFileDAO $temporaryFileDao */
|
||||
$temporaryFile = $temporaryFileDao->getTemporaryFile($this->getData('temporaryFileId'), $user->getId());
|
||||
|
||||
parent::execute(...$functionArgs);
|
||||
|
||||
if ($issueGalley) {
|
||||
// Update an existing galley
|
||||
$oldFileId = null;
|
||||
|
||||
if ($temporaryFile) {
|
||||
$oldFileId = $issueGalley->getFileId();
|
||||
|
||||
// Upload new file
|
||||
$issueFile = $issueFileManager->fromTemporaryFile($temporaryFile);
|
||||
$issueGalley->setFileId($issueFile->getId());
|
||||
}
|
||||
|
||||
$issueGalley->setLabel($this->getData('label'));
|
||||
$issueGalley->setStoredPubId('publisher-id', $this->getData('publicGalleyId'));
|
||||
$issueGalley->setLocale($this->getData('galleyLocale'));
|
||||
$issueGalley->setData('urlPath', strlen($urlPath = (string) $this->getData('urlPath')) ? $urlPath : null);
|
||||
|
||||
// Update galley in the db
|
||||
$issueGalleyDao->updateObject($issueGalley);
|
||||
|
||||
if ($oldFileId) {
|
||||
// If the galley previously had a file, delete it
|
||||
$issueFileManager->deleteById($oldFileId);
|
||||
}
|
||||
} else {
|
||||
// Create a new galley
|
||||
$issueGalleyFile = $issueFileManager->fromTemporaryFile($temporaryFile);
|
||||
|
||||
$issueGalley = $issueGalleyDao->newDataObject();
|
||||
$issueGalley->setIssueId($this->_issue->getId());
|
||||
$issueGalley->setFileId($issueGalleyFile->getId());
|
||||
$issueGalley->setData('urlPath', $this->getData('urlPath'));
|
||||
$issueGalley->setLabel($this->getData('label'));
|
||||
$issueGalley->setLocale($this->getData('galleyLocale'));
|
||||
|
||||
$issueGalley->setStoredPubId('publisher-id', $this->getData('publicGalleyId'));
|
||||
|
||||
// Insert new galley into the db
|
||||
$issueGalleyDao->insertObject($issueGalley);
|
||||
$this->_issueGalley = $issueGalley;
|
||||
}
|
||||
|
||||
return $this->_issueGalley->getId();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/navigationMenus/form/NavigationMenuItemsForm.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 NavigationMenuItemsForm
|
||||
*
|
||||
* @ingroup controllers_grid_navigationMenus
|
||||
*
|
||||
* @brief Form for managers to create/edit navigationMenuItems.
|
||||
*/
|
||||
|
||||
namespace APP\controllers\grid\navigationMenus\form;
|
||||
|
||||
use PKP\controllers\grid\navigationMenus\form\PKPNavigationMenuItemsForm;
|
||||
|
||||
class NavigationMenuItemsForm extends PKPNavigationMenuItemsForm
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/pubIds/PubIdExportIssuesListGridCellProvider.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 PubIdExportIssuesListGridCellProvider
|
||||
*
|
||||
* @ingroup controllers_grid_pubIds
|
||||
*
|
||||
* @brief Class for a cell provider that can retrieve labels from issues with pub ids
|
||||
*/
|
||||
|
||||
namespace APP\controllers\grid\pubIds;
|
||||
|
||||
use APP\core\Application;
|
||||
use PKP\controllers\grid\DataObjectGridCellProvider;
|
||||
use PKP\controllers\grid\GridHandler;
|
||||
use PKP\core\PKPApplication;
|
||||
use PKP\linkAction\LinkAction;
|
||||
use PKP\linkAction\request\AjaxModal;
|
||||
use PKP\linkAction\request\RedirectAction;
|
||||
use PKP\plugins\ImportExportPlugin;
|
||||
|
||||
class PubIdExportIssuesListGridCellProvider extends DataObjectGridCellProvider
|
||||
{
|
||||
/** @var ImportExportPlugin */
|
||||
public $_plugin;
|
||||
|
||||
public $_authorizedRoles;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param null|mixed $authorizedRoles
|
||||
*/
|
||||
public function __construct($plugin, $authorizedRoles = null)
|
||||
{
|
||||
$this->_plugin = $plugin;
|
||||
if ($authorizedRoles) {
|
||||
$this->_authorizedRoles = $authorizedRoles;
|
||||
}
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
//
|
||||
// Template methods from GridCellProvider
|
||||
//
|
||||
/**
|
||||
* Get cell actions associated with this row/column combination
|
||||
*
|
||||
* @copydoc GridCellProvider::getCellActions()
|
||||
*/
|
||||
public function getCellActions($request, $row, $column, $position = GridHandler::GRID_ACTION_POSITION_DEFAULT)
|
||||
{
|
||||
$publishedIssue = $row->getData();
|
||||
$columnId = $column->getId();
|
||||
assert(is_a($publishedIssue, 'Issue') && !empty($columnId));
|
||||
|
||||
switch ($columnId) {
|
||||
case 'identification':
|
||||
// Link to the issue edit modal
|
||||
$application = Application::get();
|
||||
$dispatcher = $application->getDispatcher();
|
||||
return [
|
||||
new LinkAction(
|
||||
'edit',
|
||||
new AjaxModal(
|
||||
$dispatcher->url($request, PKPApplication::ROUTE_COMPONENT, null, 'grid.issues.BackIssueGridHandler', 'editIssue', null, ['issueId' => $publishedIssue->getId()]),
|
||||
__('plugins.importexport.common.settings.DOIPluginSettings')
|
||||
),
|
||||
$publishedIssue->getIssueIdentification(),
|
||||
null
|
||||
)
|
||||
];
|
||||
case 'status':
|
||||
$status = $publishedIssue->getData($this->_plugin->getDepositStatusSettingName());
|
||||
$statusNames = $this->_plugin->getStatusNames();
|
||||
$statusActions = $this->_plugin->getStatusActions($publishedIssue);
|
||||
if ($status && array_key_exists($status, $statusActions)) {
|
||||
assert(array_key_exists($status, $statusNames));
|
||||
return [
|
||||
new LinkAction(
|
||||
'edit',
|
||||
new RedirectAction(
|
||||
$statusActions[$status],
|
||||
'_blank'
|
||||
),
|
||||
$statusNames[$status]
|
||||
)
|
||||
];
|
||||
}
|
||||
}
|
||||
return parent::getCellActions($request, $row, $column, $position);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts variables for a given column from a data element
|
||||
* so that they may be assigned to template before rendering.
|
||||
*
|
||||
* @copydoc DataObjectGridCellProvider::getTemplateVarsFromRowColumn()
|
||||
*/
|
||||
public function getTemplateVarsFromRowColumn($row, $column)
|
||||
{
|
||||
$publishedIssue = $row->getData();
|
||||
$columnId = $column->getId();
|
||||
assert(is_a($publishedIssue, 'Issue') && !empty($columnId));
|
||||
|
||||
switch ($columnId) {
|
||||
case 'identification':
|
||||
return ['label' => ''];
|
||||
case 'published':
|
||||
return ['label' => $publishedIssue->getDatePublished()];
|
||||
case 'pubId':
|
||||
return ['label' => $publishedIssue->getStoredPubId($this->_plugin->getPubIdType())];
|
||||
case 'status':
|
||||
$status = $publishedIssue->getData($this->_plugin->getDepositStatusSettingName());
|
||||
$statusNames = $this->_plugin->getStatusNames();
|
||||
$statusActions = $this->_plugin->getStatusActions($publishedIssue);
|
||||
if ($status) {
|
||||
if (array_key_exists($status, $statusActions)) {
|
||||
$label = '';
|
||||
} else {
|
||||
assert(array_key_exists($status, $statusNames));
|
||||
$label = $statusNames[$status];
|
||||
}
|
||||
} else {
|
||||
$label = $statusNames[EXPORT_STATUS_NOT_DEPOSITED];
|
||||
}
|
||||
return ['label' => $label];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,247 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/pubIds/PubIdExportIssuesListGridHandler.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 PubIdExportIssuesListGridHandler
|
||||
*
|
||||
* @ingroup controllers_grid_pubIds
|
||||
*
|
||||
* @brief Handle exportable issues with pub ids list grid requests.
|
||||
*/
|
||||
|
||||
namespace APP\controllers\grid\pubIds;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\plugins\PubIdPlugin;
|
||||
use APP\plugins\PubObjectsExportPlugin;
|
||||
use PKP\controllers\grid\feature\PagingFeature;
|
||||
use PKP\controllers\grid\feature\selectableItems\SelectableItemsFeature;
|
||||
use PKP\controllers\grid\GridColumn;
|
||||
use PKP\controllers\grid\GridHandler;
|
||||
use PKP\plugins\PluginRegistry;
|
||||
use PKP\security\authorization\PolicySet;
|
||||
use PKP\security\authorization\RoleBasedHandlerOperationPolicy;
|
||||
use PKP\security\Role;
|
||||
|
||||
class PubIdExportIssuesListGridHandler extends GridHandler
|
||||
{
|
||||
/** @var PubObjectsExportPlugin */
|
||||
public $_plugin;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->addRoleAssignment(
|
||||
[Role::ROLE_ID_MANAGER, Role::ROLE_ID_SITE_ADMIN],
|
||||
['fetchGrid', 'fetchRow']
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// Implement template methods from PKPHandler
|
||||
//
|
||||
/**
|
||||
* @copydoc PKPHandler::authorize()
|
||||
*/
|
||||
public function authorize($request, &$args, $roleAssignments)
|
||||
{
|
||||
$rolePolicy = new PolicySet(PolicySet::COMBINING_PERMIT_OVERRIDES);
|
||||
|
||||
foreach ($roleAssignments as $role => $operations) {
|
||||
$rolePolicy->addPolicy(new RoleBasedHandlerOperationPolicy($request, $role, $operations));
|
||||
}
|
||||
$this->addPolicy($rolePolicy);
|
||||
|
||||
return parent::authorize($request, $args, $roleAssignments);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::initialize()
|
||||
*
|
||||
* @param null|mixed $args
|
||||
*/
|
||||
public function initialize($request, $args = null)
|
||||
{
|
||||
parent::initialize($request, $args);
|
||||
|
||||
// Basic grid configuration.
|
||||
$this->setTitle('plugins.importexport.common.export.issues');
|
||||
|
||||
$pluginCategory = $request->getUserVar('category');
|
||||
$pluginPathName = $request->getUserVar('plugin');
|
||||
|
||||
// Allow for plugins that have already been loaded (e.g. by injection from a generic plugin)
|
||||
$this->_plugin = PluginRegistry::getPlugin($pluginCategory, $pluginPathName);
|
||||
|
||||
// Otherwise, load the plugin as specified
|
||||
/** @var PubIdPlugin */
|
||||
$this->_plugin ??= PluginRegistry::loadPlugin($pluginCategory, $pluginPathName);
|
||||
|
||||
assert(isset($this->_plugin));
|
||||
|
||||
// Fetch the authorized roles.
|
||||
$authorizedRoles = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_USER_ROLES);
|
||||
|
||||
// Grid columns.
|
||||
$cellProvider = new PubIdExportIssuesListGridCellProvider($this->_plugin, $authorizedRoles);
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'identification',
|
||||
'issue.issue',
|
||||
null,
|
||||
null,
|
||||
$cellProvider,
|
||||
['html' => true,
|
||||
'alignment' => GridColumn::COLUMN_ALIGNMENT_LEFT]
|
||||
)
|
||||
);
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'published',
|
||||
'editor.issues.published',
|
||||
null,
|
||||
null,
|
||||
$cellProvider,
|
||||
['html' => true,
|
||||
'alignment' => GridColumn::COLUMN_ALIGNMENT_LEFT]
|
||||
)
|
||||
);
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'pubId',
|
||||
null,
|
||||
$this->_plugin->getPubIdDisplayType(),
|
||||
null,
|
||||
$cellProvider,
|
||||
['alignment' => GridColumn::COLUMN_ALIGNMENT_LEFT,
|
||||
'width' => 15]
|
||||
)
|
||||
);
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'status',
|
||||
'common.status',
|
||||
null,
|
||||
null,
|
||||
$cellProvider,
|
||||
['alignment' => GridColumn::COLUMN_ALIGNMENT_LEFT,
|
||||
'width' => 10]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Implemented methods from GridHandler.
|
||||
//
|
||||
/**
|
||||
* @copydoc GridHandler::initFeatures()
|
||||
*/
|
||||
public function initFeatures($request, $args)
|
||||
{
|
||||
return [new SelectableItemsFeature(), new PagingFeature()];
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::getRequestArgs()
|
||||
*/
|
||||
public function getRequestArgs()
|
||||
{
|
||||
return array_merge(parent::getRequestArgs(), ['category' => $this->_plugin->getCategory(), 'plugin' => basename($this->_plugin->getPluginPath())]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::isDataElementSelected()
|
||||
*/
|
||||
public function isDataElementSelected($gridDataElement)
|
||||
{
|
||||
return false; // Nothing is selected by default
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::getSelectName()
|
||||
*/
|
||||
public function getSelectName()
|
||||
{
|
||||
return 'selectedIssues';
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::getFilterForm()
|
||||
*/
|
||||
protected function getFilterForm()
|
||||
{
|
||||
return 'controllers/grid/pubIds/pubIdExportIssuesGridFilter.tpl';
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::renderFilter()
|
||||
*/
|
||||
public function renderFilter($request, $filterData = [])
|
||||
{
|
||||
$statusNames = $this->_plugin->getStatusNames();
|
||||
$allFilterData = array_merge(
|
||||
$filterData,
|
||||
[
|
||||
'status' => $statusNames,
|
||||
'gridId' => $this->getId(),
|
||||
]
|
||||
);
|
||||
return parent::renderFilter($request, $allFilterData);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::getFilterSelectionData()
|
||||
*/
|
||||
public function getFilterSelectionData($request)
|
||||
{
|
||||
$statusId = (string) $request->getUserVar('statusId');
|
||||
return [
|
||||
'statusId' => $statusId,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::loadData()
|
||||
*/
|
||||
protected function loadData($request, $filter)
|
||||
{
|
||||
$context = $request->getContext();
|
||||
[$statusId] = $this->getFilterValues($filter);
|
||||
$pubIdStatusSettingName = null;
|
||||
if ($statusId) {
|
||||
$pubIdStatusSettingName = $this->_plugin->getDepositStatusSettingName();
|
||||
}
|
||||
return \APP\facades\Repo::issue()->dao->getExportable(
|
||||
$context->getId(),
|
||||
$this->_plugin->getPubIdType(),
|
||||
$pubIdStatusSettingName,
|
||||
$statusId,
|
||||
$this->getGridRangeInfo($request, $this->getId())
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process filter values, assigning default ones if
|
||||
* none was set.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getFilterValues($filter)
|
||||
{
|
||||
if (isset($filter['statusId']) && $filter['statusId'] != EXPORT_STATUS_ANY) {
|
||||
$statusId = $filter['statusId'];
|
||||
} else {
|
||||
$statusId = null;
|
||||
}
|
||||
return [$statusId];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/pubIds/PubIdExportRepresentationsListGridCellProvider.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 PubIdExportRepresentationsListGridCellProvider
|
||||
*
|
||||
* @ingroup controllers_grid_pubIds
|
||||
*
|
||||
* @brief Class for a cell provider that can retrieve labels from representations with pub ids
|
||||
*/
|
||||
|
||||
namespace APP\controllers\grid\pubIds;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\facades\Repo;
|
||||
use PKP\controllers\grid\DataObjectGridCellProvider;
|
||||
use PKP\controllers\grid\GridHandler;
|
||||
use PKP\core\PKPApplication;
|
||||
use PKP\linkAction\LinkAction;
|
||||
use PKP\linkAction\request\AjaxModal;
|
||||
use PKP\linkAction\request\RedirectAction;
|
||||
use PKP\plugins\ImportExportPlugin;
|
||||
|
||||
class PubIdExportRepresentationsListGridCellProvider extends DataObjectGridCellProvider
|
||||
{
|
||||
/** @var ImportExportPlugin */
|
||||
public $_plugin;
|
||||
|
||||
public $_authorizedRoles;
|
||||
|
||||
public $_titleColumn;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param null|mixed $authorizedRoles
|
||||
*/
|
||||
public function __construct($plugin, $authorizedRoles = null)
|
||||
{
|
||||
$this->_plugin = $plugin;
|
||||
if ($authorizedRoles) {
|
||||
$this->_authorizedRoles = $authorizedRoles;
|
||||
}
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
//
|
||||
// Template methods from GridCellProvider
|
||||
//
|
||||
/**
|
||||
* Get cell actions associated with this row/column combination
|
||||
*
|
||||
* @copydoc GridCellProvider::getCellActions()
|
||||
*/
|
||||
public function getCellActions($request, $row, $column, $position = GridHandler::GRID_ACTION_POSITION_DEFAULT)
|
||||
{
|
||||
$galley = $row->getData();
|
||||
$columnId = $column->getId();
|
||||
assert(is_a($galley, 'Galley') && !empty($columnId));
|
||||
|
||||
$publication = Repo::publication()->get($galley->getData('publicationId'));
|
||||
$submission = Repo::submission()->get($publication->getData('submissionId'));
|
||||
switch ($columnId) {
|
||||
case 'title':
|
||||
$this->_titleColumn = $column;
|
||||
$title = $submission->getLocalizedTitle();
|
||||
if (empty($title)) {
|
||||
$title = __('common.untitled');
|
||||
}
|
||||
$authorsInTitle = $publication->getShortAuthorString();
|
||||
$title = $authorsInTitle . '; ' . $title;
|
||||
return [
|
||||
new LinkAction(
|
||||
'itemWorkflow',
|
||||
new RedirectAction(
|
||||
Repo::submission()->getWorkflowUrlByUserRoles($submission)
|
||||
),
|
||||
htmlspecialchars($title)
|
||||
)
|
||||
];
|
||||
case 'issue':
|
||||
$contextId = $submission->getContextId();
|
||||
$issueId = $submission->getCurrentPublication()->getData('issueId');
|
||||
$issue = Repo::issue()->get($issueId);
|
||||
$issue = $issue->getJournalId() == $contextId ? $issue : null;
|
||||
// Link to the issue edit modal
|
||||
$application = Application::get();
|
||||
$dispatcher = $application->getDispatcher();
|
||||
return [
|
||||
new LinkAction(
|
||||
'edit',
|
||||
new AjaxModal(
|
||||
$dispatcher->url($request, PKPApplication::ROUTE_COMPONENT, null, 'grid.issues.BackIssueGridHandler', 'editIssue', null, ['issueId' => $issue->getId()]),
|
||||
__('plugins.importexport.common.settings.DOIPluginSettings')
|
||||
),
|
||||
$issue->getIssueIdentification(),
|
||||
null
|
||||
)
|
||||
];
|
||||
case 'status':
|
||||
$status = $galley->getData($this->_plugin->getDepositStatusSettingName());
|
||||
$statusNames = $this->_plugin->getStatusNames();
|
||||
$statusActions = $this->_plugin->getStatusActions($submission);
|
||||
if ($status && array_key_exists($status, $statusActions)) {
|
||||
assert(array_key_exists($status, $statusNames));
|
||||
return [
|
||||
new LinkAction(
|
||||
'edit',
|
||||
new RedirectAction(
|
||||
$statusActions[$status],
|
||||
'_blank'
|
||||
),
|
||||
htmlspecialchars($statusNames[$status])
|
||||
)
|
||||
];
|
||||
}
|
||||
}
|
||||
return parent::getCellActions($request, $row, $column, $position);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts variables for a given column from a data element
|
||||
* so that they may be assigned to template before rendering.
|
||||
*
|
||||
* @copydoc DataObjectGridCellProvider::getTemplateVarsFromRowColumn()
|
||||
*/
|
||||
public function getTemplateVarsFromRowColumn($row, $column)
|
||||
{
|
||||
$submissionGalley = $row->getData();
|
||||
$columnId = $column->getId();
|
||||
assert(is_a($submissionGalley, 'Galley') && !empty($columnId));
|
||||
|
||||
switch ($columnId) {
|
||||
case 'id':
|
||||
return ['label' => $submissionGalley->getId()];
|
||||
case 'title':
|
||||
return ['label' => ''];
|
||||
case 'issue':
|
||||
return ['label' => ''];
|
||||
case 'galley':
|
||||
return ['label' => $submissionGalley->getGalleyLabel()];
|
||||
case 'pubId':
|
||||
return ['label' => $submissionGalley->getStoredPubId($this->_plugin->getPubIdType())];
|
||||
case 'status':
|
||||
$status = $submissionGalley->getData($this->_plugin->getDepositStatusSettingName());
|
||||
$statusNames = $this->_plugin->getStatusNames();
|
||||
$statusActions = $this->_plugin->getStatusActions($submissionGalley);
|
||||
if ($status) {
|
||||
if (array_key_exists($status, $statusActions)) {
|
||||
$label = '';
|
||||
} else {
|
||||
assert(array_key_exists($status, $statusNames));
|
||||
$label = $statusNames[$status];
|
||||
}
|
||||
} else {
|
||||
$label = $statusNames[EXPORT_STATUS_NOT_DEPOSITED];
|
||||
}
|
||||
return ['label' => $label];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,331 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/pubIds/PubIdExportRepresentationsListGridHandler.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 PubIdExportRepresentationsListGridHandler
|
||||
*
|
||||
* @ingroup controllers_grid_pubIds
|
||||
*
|
||||
* @brief Handle exportable representations with pub ids list grid requests.
|
||||
*/
|
||||
|
||||
namespace APP\controllers\grid\pubIds;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\facades\Repo;
|
||||
use APP\issue\Collector;
|
||||
use APP\plugins\PubObjectsExportPlugin;
|
||||
use PKP\controllers\grid\feature\PagingFeature;
|
||||
use PKP\controllers\grid\feature\selectableItems\SelectableItemsFeature;
|
||||
use PKP\controllers\grid\GridColumn;
|
||||
use PKP\controllers\grid\GridHandler;
|
||||
use PKP\plugins\PluginRegistry;
|
||||
use PKP\security\authorization\PolicySet;
|
||||
use PKP\security\authorization\RoleBasedHandlerOperationPolicy;
|
||||
use PKP\security\Role;
|
||||
|
||||
class PubIdExportRepresentationsListGridHandler extends GridHandler
|
||||
{
|
||||
/** @var PubObjectsExportPlugin */
|
||||
public $_plugin;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->addRoleAssignment(
|
||||
[Role::ROLE_ID_MANAGER, Role::ROLE_ID_SITE_ADMIN],
|
||||
['fetchGrid', 'fetchRow']
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// Implement template methods from PKPHandler
|
||||
//
|
||||
/**
|
||||
* @copydoc PKPHandler::authorize()
|
||||
*/
|
||||
public function authorize($request, &$args, $roleAssignments)
|
||||
{
|
||||
$rolePolicy = new PolicySet(PolicySet::COMBINING_PERMIT_OVERRIDES);
|
||||
|
||||
foreach ($roleAssignments as $role => $operations) {
|
||||
$rolePolicy->addPolicy(new RoleBasedHandlerOperationPolicy($request, $role, $operations));
|
||||
}
|
||||
$this->addPolicy($rolePolicy);
|
||||
|
||||
return parent::authorize($request, $args, $roleAssignments);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::initialize()
|
||||
*
|
||||
* @param null|mixed $args
|
||||
*/
|
||||
public function initialize($request, $args = null)
|
||||
{
|
||||
parent::initialize($request, $args);
|
||||
$context = $request->getContext();
|
||||
|
||||
// Basic grid configuration.
|
||||
$this->setTitle('plugins.importexport.common.export.articles');
|
||||
|
||||
$pluginCategory = $request->getUserVar('category');
|
||||
$pluginPathName = $request->getUserVar('plugin');
|
||||
|
||||
// Allow for plugins that have already been loaded (e.g. by injection from a generic plugin)
|
||||
$this->_plugin = PluginRegistry::getPlugin($pluginCategory, $pluginPathName);
|
||||
|
||||
// Otherwise, load the plugin as specified
|
||||
$this->_plugin ??= PluginRegistry::loadPlugin($pluginCategory, $pluginPathName);
|
||||
|
||||
assert(isset($this->_plugin));
|
||||
|
||||
// Fetch the authorized roles.
|
||||
$authorizedRoles = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_USER_ROLES);
|
||||
|
||||
// Grid columns.
|
||||
$cellProvider = new PubIdExportRepresentationsListGridCellProvider($this->_plugin, $authorizedRoles);
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'id',
|
||||
null,
|
||||
__('common.id'),
|
||||
'controllers/grid/gridCell.tpl',
|
||||
$cellProvider,
|
||||
['alignment' => GridColumn::COLUMN_ALIGNMENT_LEFT,
|
||||
'width' => 10]
|
||||
)
|
||||
);
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'title',
|
||||
'grid.submission.itemTitle',
|
||||
null,
|
||||
null,
|
||||
$cellProvider,
|
||||
['html' => true,
|
||||
'alignment' => GridColumn::COLUMN_ALIGNMENT_LEFT]
|
||||
)
|
||||
);
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'issue',
|
||||
'issue.issue',
|
||||
null,
|
||||
null,
|
||||
$cellProvider,
|
||||
['alignment' => GridColumn::COLUMN_ALIGNMENT_LEFT,
|
||||
'width' => 20]
|
||||
)
|
||||
);
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'galley',
|
||||
'submission.layout.galleyLabel',
|
||||
null,
|
||||
null,
|
||||
$cellProvider,
|
||||
['alignment' => GridColumn::COLUMN_ALIGNMENT_LEFT,
|
||||
'width' => 20]
|
||||
)
|
||||
);
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'pubId',
|
||||
null,
|
||||
$this->_plugin->getPubIdDisplayType(),
|
||||
null,
|
||||
$cellProvider,
|
||||
['alignment' => GridColumn::COLUMN_ALIGNMENT_LEFT,
|
||||
'width' => 15]
|
||||
)
|
||||
);
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'status',
|
||||
'common.status',
|
||||
null,
|
||||
null,
|
||||
$cellProvider,
|
||||
['alignment' => GridColumn::COLUMN_ALIGNMENT_LEFT,
|
||||
'width' => 10]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Implemented methods from GridHandler.
|
||||
//
|
||||
/**
|
||||
* @copydoc GridHandler::initFeatures()
|
||||
*/
|
||||
public function initFeatures($request, $args)
|
||||
{
|
||||
return [new SelectableItemsFeature(), new PagingFeature()];
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::getRequestArgs()
|
||||
*/
|
||||
public function getRequestArgs()
|
||||
{
|
||||
return array_merge(parent::getRequestArgs(), ['category' => $this->_plugin->getCategory(), 'plugin' => basename($this->_plugin->getPluginPath())]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::isDataElementSelected()
|
||||
*/
|
||||
public function isDataElementSelected($gridDataElement)
|
||||
{
|
||||
return false; // Nothing is selected by default
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::getSelectName()
|
||||
*/
|
||||
public function getSelectName()
|
||||
{
|
||||
return 'selectedRepresentations';
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::getFilterForm()
|
||||
*/
|
||||
protected function getFilterForm()
|
||||
{
|
||||
return 'controllers/grid/pubIds/pubIdExportRepresentationsGridFilter.tpl';
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::renderFilter()
|
||||
*/
|
||||
public function renderFilter($request, $filterData = [])
|
||||
{
|
||||
$context = $request->getContext();
|
||||
$issues = Repo::issue()->getCollector()
|
||||
->filterByContextIds([$context->getId()])
|
||||
->filterByPublished(true)
|
||||
->orderBy(Collector::ORDERBY_PUBLISHED_ISSUES)
|
||||
->getMany();
|
||||
foreach ($issues as $issue) {
|
||||
$issueOptions[$issue->getId()] = $issue->getIssueIdentification();
|
||||
}
|
||||
$issueOptions[0] = __('plugins.importexport.common.filter.issue');
|
||||
ksort($issueOptions);
|
||||
$statusNames = $this->_plugin->getStatusNames();
|
||||
$filterColumns = $this->getFilterColumns();
|
||||
$allFilterData = array_merge(
|
||||
$filterData,
|
||||
[
|
||||
'columns' => $filterColumns,
|
||||
'issues' => $issueOptions,
|
||||
'status' => $statusNames,
|
||||
'gridId' => $this->getId(),
|
||||
]
|
||||
);
|
||||
return parent::renderFilter($request, $allFilterData);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::getFilterSelectionData()
|
||||
*/
|
||||
public function getFilterSelectionData($request)
|
||||
{
|
||||
$search = (string) $request->getUserVar('search');
|
||||
$column = (string) $request->getUserVar('column');
|
||||
$issueId = (int) $request->getUserVar('issueId');
|
||||
$statusId = (string) $request->getUserVar('statusId');
|
||||
return [
|
||||
'search' => $search,
|
||||
'column' => $column,
|
||||
'issueId' => $issueId,
|
||||
'statusId' => $statusId,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::loadData()
|
||||
*/
|
||||
protected function loadData($request, $filter)
|
||||
{
|
||||
$context = $request->getContext();
|
||||
[$search, $column, $issueId, $statusId] = $this->getFilterValues($filter);
|
||||
$title = $author = null;
|
||||
if ($column == 'title') {
|
||||
$title = $search;
|
||||
} elseif ($column == 'author') {
|
||||
$author = $search;
|
||||
}
|
||||
$pubIdStatusSettingName = null;
|
||||
if ($statusId) {
|
||||
$pubIdStatusSettingName = $this->_plugin->getDepositStatusSettingName();
|
||||
}
|
||||
return Repo::galley()->dao->getExportable(
|
||||
$context->getId(),
|
||||
$this->_plugin->getPubIdType(),
|
||||
$title,
|
||||
$author,
|
||||
$issueId,
|
||||
$pubIdStatusSettingName,
|
||||
$statusId,
|
||||
$this->getGridRangeInfo($request, $this->getId())
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Own protected methods
|
||||
//
|
||||
/**
|
||||
* Get which columns can be used by users to filter data.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getFilterColumns()
|
||||
{
|
||||
return [
|
||||
'title' => __('submission.title'),
|
||||
'author' => __('submission.authors')
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Process filter values, assigning default ones if
|
||||
* none was set.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getFilterValues($filter)
|
||||
{
|
||||
if (isset($filter['search']) && $filter['search']) {
|
||||
$search = $filter['search'];
|
||||
} else {
|
||||
$search = null;
|
||||
}
|
||||
if (isset($filter['column']) && $filter['column']) {
|
||||
$column = $filter['column'];
|
||||
} else {
|
||||
$column = null;
|
||||
}
|
||||
if (isset($filter['issueId']) && $filter['issueId']) {
|
||||
$issueId = $filter['issueId'];
|
||||
} else {
|
||||
$issueId = null;
|
||||
}
|
||||
if (isset($filter['statusId']) && $filter['statusId'] != EXPORT_STATUS_ANY) {
|
||||
$statusId = $filter['statusId'];
|
||||
} else {
|
||||
$statusId = null;
|
||||
}
|
||||
return [$search, $column, $issueId, $statusId];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/pubIds/PubIdExportSubmissionsListGridCellProvider.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 PubIdExportSubmissionsListGridCellProvider
|
||||
*
|
||||
* @ingroup controllers_grid_pubIds
|
||||
*
|
||||
* @brief Class for a cell provider that can retrieve labels from submissions with pub ids
|
||||
*/
|
||||
|
||||
namespace APP\controllers\grid\pubIds;
|
||||
|
||||
use APP\controllers\grid\submissions\ExportPublishedSubmissionsListGridCellProvider;
|
||||
use APP\submission\Submission;
|
||||
|
||||
class PubIdExportSubmissionsListGridCellProvider extends ExportPublishedSubmissionsListGridCellProvider
|
||||
{
|
||||
/**
|
||||
* @copydoc ExportPublishedSubmissionsListGridCellProvider::getTemplateVarsFromRowColumn()
|
||||
*/
|
||||
public function getTemplateVarsFromRowColumn($row, $column)
|
||||
{
|
||||
$submission = $row->getData();
|
||||
$columnId = $column->getId();
|
||||
assert($submission instanceof Submission && !empty($columnId));
|
||||
|
||||
switch ($columnId) {
|
||||
case 'pubId':
|
||||
return ['label' => $submission->getStoredPubId($this->_plugin->getPubIdType())];
|
||||
}
|
||||
return parent::getTemplateVarsFromRowColumn($row, $column);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/pubIds/PubIdExportSubmissionsListGridHandler.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 PubIdExportSubmissionsListGridHandler
|
||||
*
|
||||
* @ingroup controllers_grid_pubIds
|
||||
*
|
||||
* @brief Handle exportable submissions with pub ids list grid requests.
|
||||
*/
|
||||
|
||||
namespace APP\controllers\grid\pubIds;
|
||||
|
||||
use APP\controllers\grid\submissions\ExportPublishedSubmissionsListGridHandler;
|
||||
use APP\core\Application;
|
||||
use APP\facades\Repo;
|
||||
use PKP\controllers\grid\DataObjectGridCellProvider;
|
||||
use PKP\controllers\grid\GridColumn;
|
||||
|
||||
class PubIdExportSubmissionsListGridHandler extends ExportPublishedSubmissionsListGridHandler
|
||||
{
|
||||
/**
|
||||
* @copydoc GridHandler::loadData()
|
||||
*/
|
||||
protected function loadData($request, $filter)
|
||||
{
|
||||
$context = $request->getContext();
|
||||
[$search, $column, $issueId, $statusId] = $this->getFilterValues($filter);
|
||||
$title = $author = null;
|
||||
if ($column == 'title') {
|
||||
$title = $search;
|
||||
} elseif ($column == 'author') {
|
||||
$author = $search;
|
||||
}
|
||||
$pubIdStatusSettingName = null;
|
||||
if ($statusId) {
|
||||
$pubIdStatusSettingName = $this->_plugin->getDepositStatusSettingName();
|
||||
}
|
||||
return Repo::submission()->dao->getExportable(
|
||||
$context->getId(),
|
||||
$this->_plugin->getPubIdType(),
|
||||
$title,
|
||||
$author,
|
||||
$issueId,
|
||||
$pubIdStatusSettingName,
|
||||
$statusId,
|
||||
$this->getGridRangeInfo($request, $this->getId())
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc ExportPublishedSubmissionsListGridHandler::getGridCellProvider()
|
||||
*/
|
||||
public function getGridCellProvider()
|
||||
{
|
||||
// Fetch the authorized roles.
|
||||
$authorizedRoles = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_USER_ROLES);
|
||||
return new PubIdExportSubmissionsListGridCellProvider($this->_plugin, $authorizedRoles);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the grid cell provider instance
|
||||
*
|
||||
* @return DataObjectGridCellProvider
|
||||
*/
|
||||
public function addAdditionalColumns($cellProvider)
|
||||
{
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'pubId',
|
||||
null,
|
||||
$this->_plugin->getPubIdDisplayType(),
|
||||
null,
|
||||
$cellProvider,
|
||||
['alignment' => GridColumn::COLUMN_ALIGNMENT_LEFT,
|
||||
'width' => 15]
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/pubIds/form/AssignPublicIdentifiersForm.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 AssignPublicIdentifiersForm
|
||||
*
|
||||
* @ingroup controllers_grid_pubIds_form
|
||||
*
|
||||
* @brief Displays the assign pub id form.
|
||||
*/
|
||||
|
||||
namespace APP\controllers\grid\pubIds\form;
|
||||
|
||||
use APP\template\TemplateManager;
|
||||
use PKP\controllers\grid\pubIds\form\PKPAssignPublicIdentifiersForm;
|
||||
|
||||
class AssignPublicIdentifiersForm extends PKPAssignPublicIdentifiersForm
|
||||
{
|
||||
/**
|
||||
* @var array Parameters to configure the form template.
|
||||
*/
|
||||
public $_formParams;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $template Form template
|
||||
* @param object $pubObject
|
||||
* @param bool $approval
|
||||
* @param string $confirmationText
|
||||
* @param array $formParams
|
||||
*/
|
||||
public function __construct($template, $pubObject, $approval, $confirmationText, $formParams = null)
|
||||
{
|
||||
parent::__construct($template, $pubObject, $approval, $confirmationText);
|
||||
|
||||
$this->_formParams = $formParams;
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::fetch()
|
||||
*
|
||||
* @param null|mixed $template
|
||||
*/
|
||||
public function fetch($request, $template = null, $display = false)
|
||||
{
|
||||
$templateMgr = TemplateManager::getManager($request);
|
||||
$templateMgr->assign('formParams', $this->getFormParams());
|
||||
return parent::fetch($request, $template, $display);
|
||||
}
|
||||
|
||||
//
|
||||
// Getters and Setters
|
||||
//
|
||||
/**
|
||||
* Get the extra form parameters.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getFormParams()
|
||||
{
|
||||
return $this->_formParams;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/settings/plugins/SettingsPluginGridHandler.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 SettingsPluginGridHandler
|
||||
*
|
||||
* @ingroup controllers_grid_settings_plugins
|
||||
*
|
||||
* @brief Handle plugin grid requests.
|
||||
*/
|
||||
|
||||
namespace APP\controllers\grid\settings\plugins;
|
||||
|
||||
use APP\core\Application;
|
||||
use PKP\controllers\grid\plugins\PluginGridHandler;
|
||||
use PKP\controllers\grid\plugins\PluginGridRow;
|
||||
use PKP\security\authorization\ContextAccessPolicy;
|
||||
use PKP\security\authorization\PluginAccessPolicy;
|
||||
use PKP\security\Role;
|
||||
|
||||
class SettingsPluginGridHandler extends PluginGridHandler
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$roles = [Role::ROLE_ID_SITE_ADMIN, Role::ROLE_ID_MANAGER];
|
||||
$this->addRoleAssignment($roles, ['manage']);
|
||||
parent::__construct($roles);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Extended methods from PluginGridHandler
|
||||
//
|
||||
/**
|
||||
* @copydoc PluginGridHandler::loadCategoryData()
|
||||
*
|
||||
* @param null|mixed $filter
|
||||
*/
|
||||
public function loadCategoryData($request, &$categoryDataElement, $filter = null)
|
||||
{
|
||||
$plugins = parent::loadCategoryData($request, $categoryDataElement, $filter);
|
||||
$userRoles = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_USER_ROLES);
|
||||
|
||||
$showSitePlugins = false;
|
||||
if (in_array(Role::ROLE_ID_SITE_ADMIN, $userRoles)) {
|
||||
$showSitePlugins = true;
|
||||
}
|
||||
|
||||
if ($showSitePlugins) {
|
||||
return $plugins;
|
||||
} else {
|
||||
$contextLevelPlugins = [];
|
||||
foreach ($plugins as $plugin) {
|
||||
if (!$plugin->isSitePlugin()) {
|
||||
$contextLevelPlugins[$plugin->getName()] = $plugin;
|
||||
}
|
||||
unset($plugin);
|
||||
}
|
||||
return $contextLevelPlugins;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Overridden template methods.
|
||||
//
|
||||
/**
|
||||
* @copydoc CategoryGridHandler::getCategoryRowInstance()
|
||||
*/
|
||||
protected function getRowInstance()
|
||||
{
|
||||
return new PluginGridRow($this->getAuthorizedContextObject(Application::ASSOC_TYPE_USER_ROLES));
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::authorize()
|
||||
*/
|
||||
public function authorize($request, &$args, $roleAssignments)
|
||||
{
|
||||
$categoryName = $request->getUserVar('category');
|
||||
$pluginName = $request->getUserVar('plugin');
|
||||
if ($categoryName && $pluginName) {
|
||||
switch ($request->getRequestedOp()) {
|
||||
case 'enable':
|
||||
case 'disable':
|
||||
case 'manage':
|
||||
$accessMode = PluginAccessPolicy::ACCESS_MODE_MANAGE;
|
||||
break;
|
||||
default:
|
||||
$accessMode = PluginAccessPolicy::ACCESS_MODE_ADMIN;
|
||||
break;
|
||||
}
|
||||
$this->addPolicy(new PluginAccessPolicy($request, $args, $roleAssignments, $accessMode));
|
||||
} else {
|
||||
$this->addPolicy(new ContextAccessPolicy($request, $roleAssignments));
|
||||
}
|
||||
return parent::authorize($request, $args, $roleAssignments);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
/**
|
||||
* @file controllers/grid/settings/sections/SectionGridCellProvider.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 SectionGridCellProvider
|
||||
*
|
||||
* @ingroup controllers_grid_settings_sections
|
||||
*
|
||||
* @brief Grid cell provider for section grid
|
||||
*/
|
||||
|
||||
namespace APP\controllers\grid\settings\sections;
|
||||
|
||||
use PKP\controllers\grid\GridCellProvider;
|
||||
use PKP\controllers\grid\GridColumn;
|
||||
use PKP\controllers\grid\GridHandler;
|
||||
use PKP\linkAction\LinkAction;
|
||||
use PKP\linkAction\request\RemoteActionConfirmationModal;
|
||||
|
||||
class SectionGridCellProvider 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();
|
||||
switch ($columnId) {
|
||||
case 'inactive':
|
||||
return ['selected' => $element['inactive']];
|
||||
}
|
||||
return parent::getTemplateVarsFromRowColumn($row, $column);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see GridCellProvider::getCellActions()
|
||||
*/
|
||||
public function getCellActions($request, $row, $column, $position = GridHandler::GRID_ACTION_POSITION_DEFAULT)
|
||||
{
|
||||
switch ($column->getId()) {
|
||||
case 'inactive':
|
||||
$element = $row->getData(); /** @var array $element */
|
||||
|
||||
$router = $request->getRouter();
|
||||
|
||||
if ($element['inactive']) {
|
||||
return [new LinkAction(
|
||||
'activateSection',
|
||||
new RemoteActionConfirmationModal(
|
||||
$request->getSession(),
|
||||
__('manager.sections.confirmActivateSection'),
|
||||
null,
|
||||
$router->url(
|
||||
$request,
|
||||
null,
|
||||
'grid.settings.sections.SectionGridHandler',
|
||||
'activateSection',
|
||||
null,
|
||||
['sectionKey' => $row->getId()]
|
||||
)
|
||||
)
|
||||
)];
|
||||
} else {
|
||||
return [new LinkAction(
|
||||
'deactivateSection',
|
||||
new RemoteActionConfirmationModal(
|
||||
$request->getSession(),
|
||||
__('manager.sections.confirmDeactivateSection'),
|
||||
null,
|
||||
$router->url(
|
||||
$request,
|
||||
null,
|
||||
'grid.settings.sections.SectionGridHandler',
|
||||
'deactivateSection',
|
||||
null,
|
||||
['sectionKey' => $row->getId()]
|
||||
)
|
||||
)
|
||||
)];
|
||||
}
|
||||
}
|
||||
return parent::getCellActions($request, $row, $column, $position);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,355 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/settings/sections/SectionGridHandler.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 SectionGridHandler
|
||||
*
|
||||
* @ingroup controllers_grid_settings_section
|
||||
*
|
||||
* @brief Handle section grid requests.
|
||||
*/
|
||||
|
||||
namespace APP\controllers\grid\settings\sections;
|
||||
|
||||
use APP\controllers\grid\settings\sections\form\SectionForm;
|
||||
use APP\core\Application;
|
||||
use APP\core\Request;
|
||||
use APP\facades\Repo;
|
||||
use APP\notification\NotificationManager;
|
||||
use PKP\context\SubEditorsDAO;
|
||||
use PKP\controllers\grid\feature\OrderGridItemsFeature;
|
||||
use PKP\controllers\grid\GridColumn;
|
||||
use PKP\controllers\grid\settings\SetupGridHandler;
|
||||
use PKP\core\JSONMessage;
|
||||
use PKP\db\DAO;
|
||||
use PKP\db\DAORegistry;
|
||||
use PKP\linkAction\LinkAction;
|
||||
use PKP\linkAction\request\AjaxModal;
|
||||
use PKP\notification\PKPNotification;
|
||||
use PKP\security\Role;
|
||||
|
||||
class SectionGridHandler extends SetupGridHandler
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->addRoleAssignment(
|
||||
[Role::ROLE_ID_MANAGER, Role::ROLE_ID_SITE_ADMIN],
|
||||
['fetchGrid', 'fetchRow', 'addSection', 'editSection', 'updateSection', 'deleteSection', 'saveSequence', 'deactivateSection','activateSection']
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Overridden template methods
|
||||
//
|
||||
/**
|
||||
* @copydoc SetupGridHandler::initialize()
|
||||
*
|
||||
* @param null|mixed $args
|
||||
*/
|
||||
public function initialize($request, $args = null)
|
||||
{
|
||||
parent::initialize($request, $args);
|
||||
$journal = $request->getJournal();
|
||||
|
||||
// Set the grid title.
|
||||
$this->setTitle('section.sections');
|
||||
|
||||
// Elements to be displayed in the grid
|
||||
$subEditorsDao = DAORegistry::getDAO('SubEditorsDAO'); /** @var SubEditorsDAO $subEditorsDao */
|
||||
$sections = Repo::section()->getCollector()->filterByContextIds([$journal->getId()])->getMany();
|
||||
|
||||
$gridData = [];
|
||||
foreach ($sections as $section) {
|
||||
// Get the section editors data for the row
|
||||
$users = $subEditorsDao->getBySubmissionGroupIds([$section->getId()], Application::ASSOC_TYPE_SECTION, $journal->getId());
|
||||
if ($users->isEmpty()) {
|
||||
$editorsString = __('common.none');
|
||||
} else {
|
||||
$editorsString = Repo::user()
|
||||
->getCollector()
|
||||
->filterByUserIds($users->map(fn ($user) => $user->userId)->toArray())
|
||||
->getMany()
|
||||
->map(fn ($user) => $user->getFullName())
|
||||
->join(__('common.commaListSeparator'));
|
||||
}
|
||||
|
||||
$sectionId = $section->getId();
|
||||
$gridData[$sectionId] = [
|
||||
'title' => $section->getLocalizedTitle(),
|
||||
'editors' => $editorsString,
|
||||
'inactive' => $section->getIsInactive(),
|
||||
'seq' => $section->getSequence()
|
||||
];
|
||||
}
|
||||
uasort($gridData, function ($a, $b) {
|
||||
return $a['seq'] - $b['seq'];
|
||||
});
|
||||
|
||||
$this->setGridDataElements($gridData);
|
||||
|
||||
// Add grid-level actions
|
||||
$router = $request->getRouter();
|
||||
$this->addAction(
|
||||
new LinkAction(
|
||||
'addSection',
|
||||
new AjaxModal(
|
||||
$router->url($request, null, null, 'addSection', null, ['gridId' => $this->getId()]),
|
||||
__('manager.sections.create'),
|
||||
'modal_manage'
|
||||
),
|
||||
__('manager.sections.create'),
|
||||
'add_section'
|
||||
)
|
||||
);
|
||||
|
||||
//
|
||||
// Grid columns.
|
||||
//
|
||||
$sectionGridCellProvider = new SectionGridCellProvider();
|
||||
|
||||
// Section name
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'title',
|
||||
'common.title'
|
||||
)
|
||||
);
|
||||
// Section 'editors'
|
||||
$this->addColumn(new GridColumn('editors', 'user.role.editors'));
|
||||
//Section 'inactive'
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'inactive',
|
||||
'common.inactive',
|
||||
null,
|
||||
'controllers/grid/common/cell/selectStatusCell.tpl',
|
||||
$sectionGridCellProvider,
|
||||
['alignment' => GridColumn::COLUMN_ALIGNMENT_CENTER,
|
||||
'width' => 20]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// Overridden methods from GridHandler
|
||||
//
|
||||
/**
|
||||
* @copydoc GridHandler::initFeatures()
|
||||
*/
|
||||
public function initFeatures($request, $args)
|
||||
{
|
||||
return [new OrderGridItemsFeature()];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the row handler - override the default row handler
|
||||
*
|
||||
* @return SectionGridRow
|
||||
*/
|
||||
protected function getRowInstance()
|
||||
{
|
||||
return new SectionGridRow();
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::getDataElementSequence()
|
||||
*/
|
||||
public function getDataElementSequence($row)
|
||||
{
|
||||
return $row['seq'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::setDataElementSequence()
|
||||
*/
|
||||
public function setDataElementSequence($request, $rowId, $gridDataElement, $newSequence)
|
||||
{
|
||||
$journal = $request->getJournal();
|
||||
$section = Repo::section()->get($rowId, $journal->getId());
|
||||
$section->setSequence($newSequence);
|
||||
Repo::section()->edit($section, []);
|
||||
}
|
||||
|
||||
//
|
||||
// Public Section Grid Actions
|
||||
//
|
||||
/**
|
||||
* An action to add a new section
|
||||
*
|
||||
* @param array $args
|
||||
* @param Request $request
|
||||
*/
|
||||
public function addSection($args, $request)
|
||||
{
|
||||
// Calling editSection with an empty ID will add
|
||||
// a new section.
|
||||
return $this->editSection($args, $request);
|
||||
}
|
||||
|
||||
/**
|
||||
* An action to edit a section
|
||||
*
|
||||
* @param array $args
|
||||
* @param Request $request
|
||||
*
|
||||
* @return string Serialized JSON object
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function editSection($args, $request)
|
||||
{
|
||||
$sectionId = $args['sectionId'] ?? null;
|
||||
$this->setupTemplate($request);
|
||||
|
||||
$sectionForm = new SectionForm($request, $sectionId);
|
||||
$sectionForm->initData();
|
||||
return new JSONMessage(true, $sectionForm->fetch($request));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a section
|
||||
*
|
||||
* @param array $args
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function updateSection($args, $request)
|
||||
{
|
||||
$sectionId = $request->getUserVar('sectionId');
|
||||
|
||||
$sectionForm = new SectionForm($request, $sectionId);
|
||||
$sectionForm->readInputData();
|
||||
|
||||
if ($sectionForm->validate()) {
|
||||
$sectionForm->execute();
|
||||
$notificationManager = new NotificationManager();
|
||||
$notificationManager->createTrivialNotification($request->getUser()->getId());
|
||||
return DAO::getDataChangedEvent($sectionForm->getSectionId());
|
||||
}
|
||||
return new JSONMessage(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a section
|
||||
*
|
||||
* @param array $args
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function deleteSection($args, $request)
|
||||
{
|
||||
if (!$request->checkCSRF()) {
|
||||
return new JSONMessage(false, __('form.csrfInvalid'));
|
||||
}
|
||||
|
||||
$journal = $request->getJournal();
|
||||
|
||||
$section = Repo::section()->get($request->getUserVar('sectionId'), $journal->getId());
|
||||
if (!$section) {
|
||||
return new JSONMessage(false, __('manager.setup.errorDeletingItem'));
|
||||
}
|
||||
|
||||
// Validate if it can be deleted
|
||||
$sectionEmpty = Repo::section()->isEmpty($section->getId(), $journal->getId());
|
||||
if (!$sectionEmpty) {
|
||||
return new JSONMessage(false, __('manager.sections.alertDelete'));
|
||||
}
|
||||
|
||||
$activeSectionsCount = Repo::section()->getCollector()->filterByContextIds([$journal->getId()])->excludeInactive()->getCount();
|
||||
$activeSectionsCount = (!$section->getIsInactive()) ? $activeSectionsCount - 1 : $activeSectionsCount;
|
||||
if ($activeSectionsCount < 1) {
|
||||
return new JSONMessage(false, __('manager.sections.confirmDeactivateSection.error'));
|
||||
}
|
||||
|
||||
Repo::section()->delete($section);
|
||||
return DAO::getDataChangedEvent($section->getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Deactivate a section.
|
||||
*
|
||||
* @param array $args
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function deactivateSection($args, $request)
|
||||
{
|
||||
// Identify the current section
|
||||
$sectionId = (int) $request->getUserVar('sectionKey');
|
||||
|
||||
// Identify the context id.
|
||||
$context = $request->getContext();
|
||||
|
||||
// Validate if it can be inactive
|
||||
$activeSectionsCount = Repo::section()->getCollector()->filterByContextIds([$context->getId()])->excludeInactive()->getCount();
|
||||
if ($activeSectionsCount > 1) {
|
||||
$section = Repo::section()->get($sectionId, $context->getId());
|
||||
|
||||
if ($request->checkCSRF() && isset($section) && !$section->getIsInactive()) {
|
||||
$section->setIsInactive(1);
|
||||
Repo::section()->edit($section, []);
|
||||
|
||||
// Create the notification.
|
||||
$notificationMgr = new NotificationManager();
|
||||
$user = $request->getUser();
|
||||
$notificationMgr->createTrivialNotification($user->getId());
|
||||
|
||||
return DAO::getDataChangedEvent($sectionId);
|
||||
}
|
||||
} else {
|
||||
// Create the notification.
|
||||
$notificationMgr = new NotificationManager();
|
||||
$user = $request->getUser();
|
||||
$notificationMgr->createTrivialNotification($user->getId(), PKPNotification::NOTIFICATION_TYPE_ERROR, ['contents' => __('manager.sections.confirmDeactivateSection.error')]);
|
||||
return DAO::getDataChangedEvent($sectionId);
|
||||
}
|
||||
|
||||
return new JSONMessage(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Activate a section.
|
||||
*
|
||||
* @param array $args
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function activateSection($args, $request)
|
||||
{
|
||||
// Identify the current section
|
||||
$sectionId = (int) $request->getUserVar('sectionKey');
|
||||
|
||||
// Identify the context id.
|
||||
$context = $request->getContext();
|
||||
|
||||
// Get section object
|
||||
$section = Repo::section()->get($sectionId, $context->getId());
|
||||
|
||||
if ($request->checkCSRF() && isset($section) && $section->getIsInactive()) {
|
||||
$section->setIsInactive(0);
|
||||
Repo::section()->edit($section, []);
|
||||
|
||||
// Create the notification.
|
||||
$notificationMgr = new NotificationManager();
|
||||
$user = $request->getUser();
|
||||
$notificationMgr->createTrivialNotification($user->getId());
|
||||
|
||||
return DAO::getDataChangedEvent($sectionId);
|
||||
}
|
||||
|
||||
return new JSONMessage(false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/settings/sections/SectionGridRow.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 SectionGridRow
|
||||
*
|
||||
* @ingroup controllers_grid_settings_section
|
||||
*
|
||||
* @brief Handle section grid row requests.
|
||||
*/
|
||||
|
||||
namespace APP\controllers\grid\settings\sections;
|
||||
|
||||
use PKP\controllers\grid\GridRow;
|
||||
use PKP\linkAction\LinkAction;
|
||||
use PKP\linkAction\request\AjaxModal;
|
||||
use PKP\linkAction\request\RemoteActionConfirmationModal;
|
||||
|
||||
class SectionGridRow extends GridRow
|
||||
{
|
||||
//
|
||||
// Overridden template methods
|
||||
//
|
||||
/**
|
||||
* @copydoc GridRow::initialize()
|
||||
*
|
||||
* @param null|mixed $template
|
||||
*/
|
||||
public function initialize($request, $template = null)
|
||||
{
|
||||
parent::initialize($request, $template);
|
||||
|
||||
// Is this a new row or an existing row?
|
||||
$sectionId = $this->getId();
|
||||
if (!empty($sectionId) && is_numeric($sectionId)) {
|
||||
$router = $request->getRouter();
|
||||
|
||||
$this->addAction(
|
||||
new LinkAction(
|
||||
'editSection',
|
||||
new AjaxModal(
|
||||
$router->url($request, null, null, 'editSection', null, ['sectionId' => $sectionId]),
|
||||
__('grid.action.edit'),
|
||||
'modal_edit',
|
||||
true
|
||||
),
|
||||
__('grid.action.edit'),
|
||||
'edit'
|
||||
)
|
||||
);
|
||||
|
||||
$this->addAction(
|
||||
new LinkAction(
|
||||
'deleteSection',
|
||||
new RemoteActionConfirmationModal(
|
||||
$request->getSession(),
|
||||
__('manager.sections.confirmDelete'),
|
||||
__('grid.action.delete'),
|
||||
$router->url($request, null, null, 'deleteSection', null, ['sectionId' => $sectionId]),
|
||||
'modal_delete'
|
||||
),
|
||||
__('grid.action.delete'),
|
||||
'delete'
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,198 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/settings/sections/form/SectionForm.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 SectionForm
|
||||
*
|
||||
* @ingroup controllers_grid_settings_section_form
|
||||
*
|
||||
* @brief Form for adding/editing a section
|
||||
*/
|
||||
|
||||
namespace APP\controllers\grid\settings\sections\form;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\core\Request;
|
||||
use APP\facades\Repo;
|
||||
use APP\template\TemplateManager;
|
||||
use PKP\controllers\grid\settings\sections\form\PKPSectionForm;
|
||||
use PKP\db\DAORegistry;
|
||||
use PKP\reviewForm\ReviewFormDAO;
|
||||
|
||||
class SectionForm extends PKPSectionForm
|
||||
{
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param int $sectionId optional
|
||||
*/
|
||||
public function __construct($request, $sectionId = null)
|
||||
{
|
||||
parent::__construct(
|
||||
$request,
|
||||
'controllers/grid/settings/sections/form/sectionForm.tpl',
|
||||
$sectionId
|
||||
);
|
||||
|
||||
// Validation checks for this form
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorLocale($this, 'title', 'required', 'manager.setup.form.section.nameRequired'));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorLocale($this, 'abbrev', 'required', 'manager.sections.form.abbrevRequired'));
|
||||
$journal = $request->getJournal();
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorCustom($this, 'reviewFormId', 'optional', 'manager.sections.form.reviewFormId', [DAORegistry::getDAO('ReviewFormDAO'), 'reviewFormExists'], [Application::ASSOC_TYPE_JOURNAL, $journal->getId()]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize form data from current settings.
|
||||
*/
|
||||
public function initData()
|
||||
{
|
||||
$request = Application::get()->getRequest();
|
||||
$journal = $request->getJournal();
|
||||
|
||||
$sectionId = $this->getSectionId();
|
||||
if ($sectionId) {
|
||||
$this->section = Repo::section()->get($sectionId, $journal->getId());
|
||||
}
|
||||
|
||||
if (isset($this->section)) {
|
||||
$this->setData([
|
||||
'title' => $this->section->getTitle(null), // Localized
|
||||
'abbrev' => $this->section->getAbbrev(null), // Localized
|
||||
'reviewFormId' => $this->section->getReviewFormId(),
|
||||
'isInactive' => $this->section->getIsInactive(),
|
||||
'metaIndexed' => !$this->section->getMetaIndexed(), // #2066: Inverted
|
||||
'metaReviewed' => !$this->section->getMetaReviewed(), // #2066: Inverted
|
||||
'abstractsNotRequired' => $this->section->getAbstractsNotRequired(),
|
||||
'identifyType' => $this->section->getIdentifyType(null), // Localized
|
||||
'editorRestricted' => $this->section->getEditorRestricted(),
|
||||
'hideTitle' => $this->section->getHideTitle(),
|
||||
'hideAuthor' => $this->section->getHideAuthor(),
|
||||
'policy' => $this->section->getPolicy(null), // Localized
|
||||
'wordCount' => $this->section->getAbstractWordCount(),
|
||||
]);
|
||||
}
|
||||
|
||||
parent::initData();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Form::validate()
|
||||
*/
|
||||
public function validate($callHooks = true)
|
||||
{
|
||||
// Validate if it can be inactive
|
||||
if ($this->getData('isInactive')) {
|
||||
$request = Application::get()->getRequest();
|
||||
$context = $request->getContext();
|
||||
$sectionId = $this->getSectionId();
|
||||
|
||||
$activeSections = Repo::section()->getCollector()->filterByContextIds([$context->getId()])->excludeInactive()->getMany();
|
||||
$otherActiveSections = $activeSections->filter(function ($activeSection) use ($sectionId) {
|
||||
return $activeSection->getId() != $sectionId;
|
||||
});
|
||||
if ($otherActiveSections->count() < 1) {
|
||||
$this->addError('isInactive', __('manager.sections.confirmDeactivateSection.error'));
|
||||
}
|
||||
}
|
||||
|
||||
return parent::validate($callHooks);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::fetch()
|
||||
*
|
||||
* @param null|mixed $template
|
||||
*/
|
||||
public function fetch($request, $template = null, $display = false)
|
||||
{
|
||||
$templateMgr = TemplateManager::getManager($request);
|
||||
$templateMgr->assign('sectionId', $this->getSectionId());
|
||||
|
||||
$journal = $request->getContext();
|
||||
|
||||
$reviewFormDao = DAORegistry::getDAO('ReviewFormDAO'); /** @var ReviewFormDAO $reviewFormDao */
|
||||
$reviewForms = $reviewFormDao->getActiveByAssocId(Application::ASSOC_TYPE_JOURNAL, $journal->getId());
|
||||
$reviewFormOptions = [];
|
||||
while ($reviewForm = $reviewForms->next()) {
|
||||
$reviewFormOptions[$reviewForm->getId()] = $reviewForm->getLocalizedTitle();
|
||||
}
|
||||
$templateMgr->assign('reviewFormOptions', $reviewFormOptions);
|
||||
|
||||
return parent::fetch($request, $template, $display);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::readInputData()
|
||||
*/
|
||||
public function readInputData()
|
||||
{
|
||||
parent::readInputData();
|
||||
$this->readUserVars(['abbrev', 'policy', 'reviewFormId', 'identifyType', 'isInactive', 'metaIndexed', 'metaReviewed', 'abstractsNotRequired', 'editorRestricted', 'hideTitle', 'hideAuthor', 'wordCount']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the names of fields for which localized data is allowed.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getLocaleFieldNames()
|
||||
{
|
||||
return ['title', 'policy', 'abbrev', 'identifyType'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Save section.
|
||||
*/
|
||||
public function execute(...$functionArgs)
|
||||
{
|
||||
$request = Application::get()->getRequest();
|
||||
$journal = $request->getJournal();
|
||||
|
||||
// Get or create the section object
|
||||
if ($this->getSectionId()) {
|
||||
$section = Repo::section()->get($this->getSectionId(), $journal->getId());
|
||||
} else {
|
||||
$section = Repo::section()->newDataObject();
|
||||
$section->setContextId($journal->getId());
|
||||
}
|
||||
|
||||
// Populate/update the section object from the form
|
||||
$section->setTitle($this->getData('title'), null); // Localized
|
||||
$section->setAbbrev($this->getData('abbrev'), null); // Localized
|
||||
|
||||
$reviewFormId = $this->getData('reviewFormId');
|
||||
if (!$reviewFormId) {
|
||||
$reviewFormId = null;
|
||||
}
|
||||
|
||||
$section->setReviewFormId($reviewFormId);
|
||||
$section->setIsInactive($this->getData('isInactive') ? 1 : 0);
|
||||
$section->setMetaIndexed($this->getData('metaIndexed') ? 0 : 1); // #2066: Inverted
|
||||
$section->setMetaReviewed($this->getData('metaReviewed') ? 0 : 1); // #2066: Inverted
|
||||
$section->setAbstractsNotRequired($this->getData('abstractsNotRequired') ? 1 : 0);
|
||||
$section->setIdentifyType($this->getData('identifyType'), null); // Localized
|
||||
$section->setEditorRestricted($this->getData('editorRestricted') ? 1 : 0);
|
||||
$section->setHideTitle($this->getData('hideTitle') ? 1 : 0);
|
||||
$section->setHideAuthor($this->getData('hideAuthor') ? 1 : 0);
|
||||
$section->setPolicy($this->getData('policy'), null); // Localized
|
||||
$section->setAbstractWordCount((int) $this->getData('wordCount'));
|
||||
|
||||
// Insert or update the section in the DB
|
||||
if ($this->getSectionId()) {
|
||||
Repo::section()->edit($section, []);
|
||||
} else {
|
||||
$section->setSequence(REALLY_BIG_NUMBER);
|
||||
$sectionId = Repo::section()->add($section);
|
||||
$this->setSectionId($sectionId);
|
||||
Repo::section()->resequence($journal->getId());
|
||||
}
|
||||
|
||||
return parent::execute(...$functionArgs);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/submissions/ExportPublishedSubmissionsListGridCellProvider.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 ExportPublishedSubmissionsListGridCellProvider
|
||||
*
|
||||
* @ingroup controllers_grid_submissions
|
||||
*
|
||||
* @brief Class for a cell provider that can retrieve labels from submissions
|
||||
*/
|
||||
|
||||
namespace APP\controllers\grid\submissions;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\facades\Repo;
|
||||
use APP\submission\Submission;
|
||||
use PKP\controllers\grid\DataObjectGridCellProvider;
|
||||
use PKP\controllers\grid\GridHandler;
|
||||
use PKP\core\PKPApplication;
|
||||
use PKP\linkAction\LinkAction;
|
||||
use PKP\linkAction\request\AjaxModal;
|
||||
use PKP\linkAction\request\RedirectAction;
|
||||
use PKP\plugins\ImportExportPlugin;
|
||||
|
||||
class ExportPublishedSubmissionsListGridCellProvider extends DataObjectGridCellProvider
|
||||
{
|
||||
/** @var ImportExportPlugin */
|
||||
public $_plugin;
|
||||
|
||||
public $_authorizedRoles;
|
||||
|
||||
public $_titleColumn;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param null|mixed $authorizedRoles
|
||||
*/
|
||||
public function __construct($plugin, $authorizedRoles = null)
|
||||
{
|
||||
$this->_plugin = $plugin;
|
||||
if ($authorizedRoles) {
|
||||
$this->_authorizedRoles = $authorizedRoles;
|
||||
}
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
//
|
||||
// Template methods from GridCellProvider
|
||||
//
|
||||
/**
|
||||
* Get cell actions associated with this row/column combination
|
||||
*
|
||||
* @copydoc GridCellProvider::getCellActions()
|
||||
*/
|
||||
public function getCellActions($request, $row, $column, $position = GridHandler::GRID_ACTION_POSITION_DEFAULT)
|
||||
{
|
||||
$submission = $row->getData();
|
||||
$columnId = $column->getId();
|
||||
assert($submission instanceof Submission && !empty($columnId));
|
||||
|
||||
switch ($columnId) {
|
||||
case 'title':
|
||||
$this->_titleColumn = $column;
|
||||
$title = $submission->getCurrentPublication()->getLocalizedTitle(null, 'html');
|
||||
if (empty($title)) {
|
||||
$title = __('common.untitled');
|
||||
}
|
||||
$authorsInTitle = $submission->getCurrentPublication()->getShortAuthorString();
|
||||
$title = $authorsInTitle . '; ' . $title;
|
||||
return [
|
||||
new LinkAction(
|
||||
'itemWorkflow',
|
||||
new RedirectAction(
|
||||
Repo::submission()->getWorkflowUrlByUserRoles($submission)
|
||||
),
|
||||
htmlspecialchars($title)
|
||||
)
|
||||
];
|
||||
case 'issue':
|
||||
$contextId = $submission->getContextId();
|
||||
$issueId = $submission->getCurrentPublication()->getData('issueId');
|
||||
$issue = Repo::issue()->get($issueId);
|
||||
$issue = $issue->getJournalId() == $contextId ? $issue : null;
|
||||
if ($issue) {
|
||||
// Link to the issue edit modal
|
||||
$application = Application::get();
|
||||
$dispatcher = $application->getDispatcher();
|
||||
return [
|
||||
new LinkAction(
|
||||
'edit',
|
||||
new AjaxModal(
|
||||
$dispatcher->url($request, PKPApplication::ROUTE_COMPONENT, null, 'grid.issues.BackIssueGridHandler', 'editIssue', null, ['issueId' => $issue->getId()]),
|
||||
__('plugins.importexport.common.settings.DOIPluginSettings')
|
||||
),
|
||||
$issue->getIssueIdentification(),
|
||||
null
|
||||
)
|
||||
];
|
||||
}
|
||||
break;
|
||||
case 'status':
|
||||
$status = $submission->getData($this->_plugin->getDepositStatusSettingName());
|
||||
$statusNames = $this->_plugin->getStatusNames();
|
||||
$statusActions = $this->_plugin->getStatusActions($submission);
|
||||
if ($status && array_key_exists($status, $statusActions)) {
|
||||
assert(array_key_exists($status, $statusNames));
|
||||
return [$statusActions[$status]];
|
||||
}
|
||||
break;
|
||||
}
|
||||
return parent::getCellActions($request, $row, $column, $position);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts variables for a given column from a data element
|
||||
* so that they may be assigned to template before rendering.
|
||||
*
|
||||
* @copydoc DataObjectGridCellProvider::getTemplateVarsFromRowColumn()
|
||||
*/
|
||||
public function getTemplateVarsFromRowColumn($row, $column)
|
||||
{
|
||||
$submission = $row->getData();
|
||||
$columnId = $column->getId();
|
||||
assert($submission instanceof Submission && !empty($columnId));
|
||||
|
||||
switch ($columnId) {
|
||||
case 'id':
|
||||
return ['label' => $submission->getId()];
|
||||
case 'title':
|
||||
return ['label' => ''];
|
||||
case 'issue':
|
||||
return ['label' => ''];
|
||||
case 'status':
|
||||
$status = $submission->getData($this->_plugin->getDepositStatusSettingName());
|
||||
$statusNames = $this->_plugin->getStatusNames();
|
||||
$statusActions = $this->_plugin->getStatusActions($submission);
|
||||
if ($status) {
|
||||
if (array_key_exists($status, $statusActions)) {
|
||||
$label = '';
|
||||
} else {
|
||||
assert(array_key_exists($status, $statusNames));
|
||||
$label = $statusNames[$status];
|
||||
}
|
||||
} else {
|
||||
$label = $statusNames[EXPORT_STATUS_NOT_DEPOSITED];
|
||||
}
|
||||
return ['label' => $label];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,321 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/submissions/ExportPublishedSubmissionsListGridHandler.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 ExportPublishedSubmissionsListGridHandler
|
||||
*
|
||||
* @ingroup controllers_grid_submissions
|
||||
*
|
||||
* @brief Handle exportable published submissions list grid requests.
|
||||
*/
|
||||
|
||||
namespace APP\controllers\grid\submissions;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\facades\Repo;
|
||||
use APP\issue\Collector;
|
||||
use PKP\controllers\grid\feature\PagingFeature;
|
||||
use PKP\controllers\grid\feature\selectableItems\SelectableItemsFeature;
|
||||
use PKP\controllers\grid\GridColumn;
|
||||
use PKP\controllers\grid\GridHandler;
|
||||
use PKP\plugins\ImportExportPlugin;
|
||||
use PKP\plugins\PluginRegistry;
|
||||
use PKP\security\authorization\PolicySet;
|
||||
use PKP\security\authorization\RoleBasedHandlerOperationPolicy;
|
||||
use PKP\security\Role;
|
||||
|
||||
class ExportPublishedSubmissionsListGridHandler extends GridHandler
|
||||
{
|
||||
/** @var ImportExportPlugin */
|
||||
public $_plugin;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->addRoleAssignment(
|
||||
[Role::ROLE_ID_MANAGER, Role::ROLE_ID_SITE_ADMIN],
|
||||
['fetchGrid', 'fetchRow']
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// Implement template methods from PKPHandler
|
||||
//
|
||||
/**
|
||||
* @copydoc PKPHandler::authorize()
|
||||
*/
|
||||
public function authorize($request, &$args, $roleAssignments)
|
||||
{
|
||||
$rolePolicy = new PolicySet(PolicySet::COMBINING_PERMIT_OVERRIDES);
|
||||
|
||||
foreach ($roleAssignments as $role => $operations) {
|
||||
$rolePolicy->addPolicy(new RoleBasedHandlerOperationPolicy($request, $role, $operations));
|
||||
}
|
||||
$this->addPolicy($rolePolicy);
|
||||
|
||||
return parent::authorize($request, $args, $roleAssignments);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::initialize()
|
||||
*
|
||||
* @param null|mixed $args
|
||||
*/
|
||||
public function initialize($request, $args = null)
|
||||
{
|
||||
parent::initialize($request, $args);
|
||||
$context = $request->getContext();
|
||||
|
||||
// Basic grid configuration.
|
||||
$this->setTitle('plugins.importexport.common.export.articles');
|
||||
|
||||
$pluginCategory = $request->getUserVar('category');
|
||||
$pluginPathName = $request->getUserVar('plugin');
|
||||
|
||||
// Allow for plugins that have already been loaded (e.g. by injection from a generic plugin)
|
||||
$this->_plugin = PluginRegistry::getPlugin($pluginCategory, $pluginPathName);
|
||||
|
||||
// Otherwise, load the plugin as specified
|
||||
$this->_plugin ??= PluginRegistry::loadPlugin($pluginCategory, $pluginPathName);
|
||||
|
||||
assert(isset($this->_plugin));
|
||||
|
||||
// Grid columns.
|
||||
$cellProvider = $this->getGridCellProvider();
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'id',
|
||||
null,
|
||||
__('common.id'),
|
||||
'controllers/grid/gridCell.tpl',
|
||||
$cellProvider,
|
||||
['alignment' => GridColumn::COLUMN_ALIGNMENT_LEFT,
|
||||
'width' => 10]
|
||||
)
|
||||
);
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'title',
|
||||
'grid.submission.itemTitle',
|
||||
null,
|
||||
null,
|
||||
$cellProvider,
|
||||
['html' => true,
|
||||
'alignment' => GridColumn::COLUMN_ALIGNMENT_LEFT]
|
||||
)
|
||||
);
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'issue',
|
||||
'issue.issue',
|
||||
null,
|
||||
null,
|
||||
$cellProvider,
|
||||
['alignment' => GridColumn::COLUMN_ALIGNMENT_LEFT,
|
||||
'width' => 20]
|
||||
)
|
||||
);
|
||||
if (method_exists($this, 'addAdditionalColumns')) {
|
||||
$this->addAdditionalColumns($cellProvider);
|
||||
}
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'status',
|
||||
'common.status',
|
||||
null,
|
||||
null,
|
||||
$cellProvider,
|
||||
['alignment' => GridColumn::COLUMN_ALIGNMENT_LEFT,
|
||||
'width' => 10]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Implemented methods from GridHandler.
|
||||
//
|
||||
/**
|
||||
* @copydoc GridHandler::initFeatures()
|
||||
*/
|
||||
public function initFeatures($request, $args)
|
||||
{
|
||||
return [new SelectableItemsFeature(), new PagingFeature()];
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::getRequestArgs()
|
||||
*/
|
||||
public function getRequestArgs()
|
||||
{
|
||||
return array_merge(parent::getRequestArgs(), ['category' => $this->_plugin->getCategory(), 'plugin' => basename($this->_plugin->getPluginPath())]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::isDataElementSelected()
|
||||
*/
|
||||
public function isDataElementSelected($gridDataElement)
|
||||
{
|
||||
return false; // Nothing is selected by default
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::getSelectName()
|
||||
*/
|
||||
public function getSelectName()
|
||||
{
|
||||
return 'selectedSubmissions';
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::getFilterForm()
|
||||
*/
|
||||
protected function getFilterForm()
|
||||
{
|
||||
return 'controllers/grid/submissions/exportPublishedSubmissionsGridFilter.tpl';
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::renderFilter()
|
||||
*/
|
||||
public function renderFilter($request, $filterData = [])
|
||||
{
|
||||
$context = $request->getContext();
|
||||
$issues = Repo::issue()->getCollector()
|
||||
->filterByContextIds([$context->getId()])
|
||||
->filterByPublished(true)
|
||||
->orderBy(Collector::ORDERBY_PUBLISHED_ISSUES)
|
||||
->getMany();
|
||||
foreach ($issues as $issue) {
|
||||
$issueOptions[$issue->getId()] = $issue->getIssueIdentification();
|
||||
}
|
||||
$issueOptions[0] = __('plugins.importexport.common.filter.issue');
|
||||
ksort($issueOptions);
|
||||
$statusNames = $this->_plugin->getStatusNames();
|
||||
$filterColumns = $this->getFilterColumns();
|
||||
$allFilterData = array_merge(
|
||||
$filterData,
|
||||
[
|
||||
'columns' => $filterColumns,
|
||||
'issues' => $issueOptions,
|
||||
'status' => $statusNames,
|
||||
'gridId' => $this->getId(),
|
||||
]
|
||||
);
|
||||
return parent::renderFilter($request, $allFilterData);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::getFilterSelectionData()
|
||||
*/
|
||||
public function getFilterSelectionData($request)
|
||||
{
|
||||
$search = (string) $request->getUserVar('search');
|
||||
$column = (string) $request->getUserVar('column');
|
||||
$issueId = (int) $request->getUserVar('issueId');
|
||||
$statusId = (string) $request->getUserVar('statusId');
|
||||
return [
|
||||
'search' => $search,
|
||||
'column' => $column,
|
||||
'issueId' => $issueId,
|
||||
'statusId' => $statusId,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::loadData()
|
||||
*/
|
||||
protected function loadData($request, $filter)
|
||||
{
|
||||
$context = $request->getContext();
|
||||
[$search, $column, $issueId, $statusId] = $this->getFilterValues($filter);
|
||||
$title = $author = null;
|
||||
if ($column == 'title') {
|
||||
$title = $search;
|
||||
} elseif ($column == 'author') {
|
||||
$author = $search;
|
||||
}
|
||||
$pubIdStatusSettingName = null;
|
||||
if ($statusId) {
|
||||
$pubIdStatusSettingName = $this->_plugin->getDepositStatusSettingName();
|
||||
}
|
||||
return Repo::submission()->dao->getExportable(
|
||||
$context->getId(),
|
||||
null,
|
||||
$title,
|
||||
$author,
|
||||
$issueId,
|
||||
$pubIdStatusSettingName,
|
||||
$statusId,
|
||||
$this->getGridRangeInfo($request, $this->getId())
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Own protected methods
|
||||
//
|
||||
/**
|
||||
* Get which columns can be used by users to filter data.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getFilterColumns()
|
||||
{
|
||||
return [
|
||||
'title' => __('submission.title'),
|
||||
'author' => __('submission.authors')
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Process filter values, assigning default ones if
|
||||
* none was set.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getFilterValues($filter)
|
||||
{
|
||||
if (isset($filter['search']) && $filter['search']) {
|
||||
$search = $filter['search'];
|
||||
} else {
|
||||
$search = null;
|
||||
}
|
||||
if (isset($filter['column']) && $filter['column']) {
|
||||
$column = $filter['column'];
|
||||
} else {
|
||||
$column = null;
|
||||
}
|
||||
if (isset($filter['issueId']) && $filter['issueId']) {
|
||||
$issueId = $filter['issueId'];
|
||||
} else {
|
||||
$issueId = null;
|
||||
}
|
||||
if (isset($filter['statusId']) && $filter['statusId'] != EXPORT_STATUS_ANY) {
|
||||
$statusId = $filter['statusId'];
|
||||
} else {
|
||||
$statusId = null;
|
||||
}
|
||||
return [$search, $column, $issueId, $statusId];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the grid cell provider instance
|
||||
*
|
||||
* @return ExportPublishedSubmissionsListGridCellProvider
|
||||
*/
|
||||
public function getGridCellProvider()
|
||||
{
|
||||
// Fetch the authorized roles.
|
||||
$authorizedRoles = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_USER_ROLES);
|
||||
return new ExportPublishedSubmissionsListGridCellProvider($this->_plugin, $authorizedRoles);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/subscriptions/IndividualSubscriptionForm.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 IndividualSubscriptionForm
|
||||
*
|
||||
* @ingroup subscription
|
||||
*
|
||||
* @brief Form class for individual subscription create/edits.
|
||||
*/
|
||||
|
||||
namespace APP\controllers\grid\subscriptions;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\core\Request;
|
||||
use APP\notification\NotificationManager;
|
||||
use APP\subscription\form\SubscriptionForm;
|
||||
use APP\subscription\IndividualSubscription;
|
||||
use APP\subscription\IndividualSubscriptionDAO;
|
||||
use APP\subscription\SubscriptionTypeDAO;
|
||||
use Exception;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use PKP\db\DAORegistry;
|
||||
use PKP\notification\PKPNotification;
|
||||
|
||||
class IndividualSubscriptionForm extends SubscriptionForm
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param Request $request
|
||||
* @param int $subscriptionId leave as default for new subscription
|
||||
*/
|
||||
public function __construct($request, $subscriptionId = null)
|
||||
{
|
||||
parent::__construct('payments/individualSubscriptionForm.tpl', $subscriptionId);
|
||||
|
||||
$subscriptionId = isset($subscriptionId) ? (int) $subscriptionId : null;
|
||||
$journal = $request->getJournal();
|
||||
$journalId = $journal->getId();
|
||||
|
||||
if (isset($subscriptionId)) {
|
||||
$subscriptionDao = DAORegistry::getDAO('IndividualSubscriptionDAO'); /** @var IndividualSubscriptionDAO $subscriptionDao */
|
||||
if ($subscriptionDao->subscriptionExists($subscriptionId)) {
|
||||
$this->subscription = $subscriptionDao->getById($subscriptionId);
|
||||
}
|
||||
}
|
||||
|
||||
$subscriptionTypeDao = DAORegistry::getDAO('SubscriptionTypeDAO'); /** @var SubscriptionTypeDAO $subscriptionTypeDao */
|
||||
$subscriptionTypeIterator = $subscriptionTypeDao->getByInstitutional($journalId, false);
|
||||
$this->subscriptionTypes = [];
|
||||
while ($subscriptionType = $subscriptionTypeIterator->next()) {
|
||||
$this->subscriptionTypes[$subscriptionType->getId()] = $subscriptionType->getSummaryString();
|
||||
}
|
||||
|
||||
if (count($this->subscriptionTypes) == 0) {
|
||||
$this->addError('typeId', __('manager.subscriptions.form.typeRequired'));
|
||||
$this->addErrorField('typeId');
|
||||
}
|
||||
|
||||
// Ensure subscription type is valid
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorCustom($this, 'typeId', 'required', 'manager.subscriptions.form.typeIdValid', function ($typeId) use ($journalId) {
|
||||
$subscriptionTypeDao = DAORegistry::getDAO('SubscriptionTypeDAO'); /** @var SubscriptionTypeDAO $subscriptionTypeDao */
|
||||
return $subscriptionTypeDao->subscriptionTypeExistsByTypeId($typeId, $journalId) && !$subscriptionTypeDao->getSubscriptionTypeInstitutional($typeId);
|
||||
}));
|
||||
|
||||
// Ensure that user does not already have a subscription for this journal
|
||||
if (!isset($subscriptionId)) {
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorCustom($this, 'userId', 'required', 'manager.subscriptions.form.subscriptionExists', [DAORegistry::getDAO('IndividualSubscriptionDAO'), 'subscriptionExistsByUserForJournal'], [$journalId], true));
|
||||
} else {
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorCustom($this, 'userId', 'required', 'manager.subscriptions.form.subscriptionExists', function ($userId) use ($journalId, $subscriptionId) {
|
||||
$subscriptionDao = DAORegistry::getDAO('IndividualSubscriptionDAO'); /** @var IndividualSubscriptionDAO $subscriptionDao */
|
||||
$checkSubscription = $subscriptionDao->getByUserIdForJournal($userId, $journalId);
|
||||
return (!$checkSubscription || $checkSubscription->getId() == $subscriptionId) ? true : false;
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::execute()
|
||||
*/
|
||||
public function execute(...$functionArgs)
|
||||
{
|
||||
$insert = false;
|
||||
if (!isset($this->subscription)) {
|
||||
$this->subscription = new IndividualSubscription();
|
||||
$insert = true;
|
||||
}
|
||||
|
||||
parent::execute(...$functionArgs);
|
||||
$individualSubscriptionDao = DAORegistry::getDAO('IndividualSubscriptionDAO'); /** @var IndividualSubscriptionDAO $individualSubscriptionDao */
|
||||
|
||||
if ($insert) {
|
||||
$individualSubscriptionDao->insertObject($this->subscription);
|
||||
} else {
|
||||
$individualSubscriptionDao->updateObject($this->subscription);
|
||||
}
|
||||
|
||||
// Send notification email
|
||||
if ($this->getData('notifyEmail')) {
|
||||
$mailable = $this->_prepareNotificationEmail();
|
||||
try {
|
||||
Mail::send($mailable);
|
||||
} catch (Exception $e) {
|
||||
$notificationMgr = new NotificationManager();
|
||||
$request = Application::get()->getRequest();
|
||||
$notificationMgr->createTrivialNotification($request->getUser()->getId(), PKPNotification::NOTIFICATION_TYPE_ERROR, ['contents' => __('email.compose.error')]);
|
||||
error_log($e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,228 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/subscriptions/IndividualSubscriptionsGridHandler.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 IndividualSubscriptionsGridHandler
|
||||
*
|
||||
* @ingroup controllers_grid_subscriptions
|
||||
*
|
||||
* @brief Handle subscription grid requests.
|
||||
*/
|
||||
|
||||
namespace APP\controllers\grid\subscriptions;
|
||||
|
||||
use APP\core\Request;
|
||||
use APP\facades\Repo;
|
||||
use APP\notification\NotificationManager;
|
||||
use APP\subscription\IndividualSubscriptionDAO;
|
||||
use APP\subscription\SubscriptionDAO;
|
||||
use PKP\controllers\grid\GridColumn;
|
||||
use PKP\core\JSONMessage;
|
||||
use PKP\db\DAO;
|
||||
use PKP\db\DAORegistry;
|
||||
use PKP\identity\Identity;
|
||||
use PKP\notification\PKPNotification;
|
||||
|
||||
class IndividualSubscriptionsGridHandler extends SubscriptionsGridHandler
|
||||
{
|
||||
/**
|
||||
* @copydoc SubscriptionsGridHandler::initialize()
|
||||
*
|
||||
* @param null|mixed $args
|
||||
*/
|
||||
public function initialize($request, $args = null)
|
||||
{
|
||||
parent::initialize($request, $args);
|
||||
|
||||
// Basic grid configuration.
|
||||
$this->setTitle('subscriptionManager.individualSubscriptions');
|
||||
|
||||
//
|
||||
// Grid columns.
|
||||
//
|
||||
$cellProvider = new SubscriptionsGridCellProvider();
|
||||
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'name',
|
||||
'common.name',
|
||||
null,
|
||||
null,
|
||||
$cellProvider
|
||||
)
|
||||
);
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'email',
|
||||
'user.email',
|
||||
null,
|
||||
null,
|
||||
$cellProvider
|
||||
)
|
||||
);
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'subscriptionType',
|
||||
'manager.subscriptions.subscriptionType',
|
||||
null,
|
||||
null,
|
||||
$cellProvider
|
||||
)
|
||||
);
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'status',
|
||||
'manager.subscriptions.form.status',
|
||||
null,
|
||||
null,
|
||||
$cellProvider
|
||||
)
|
||||
);
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'dateStart',
|
||||
'manager.subscriptions.dateStart',
|
||||
null,
|
||||
null,
|
||||
$cellProvider
|
||||
)
|
||||
);
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'dateEnd',
|
||||
'manager.subscriptions.dateEnd',
|
||||
null,
|
||||
null,
|
||||
$cellProvider
|
||||
)
|
||||
);
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'referenceNumber',
|
||||
'manager.subscriptions.referenceNumber',
|
||||
null,
|
||||
null,
|
||||
$cellProvider
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Implement methods from GridHandler.
|
||||
//
|
||||
/**
|
||||
* @copydoc GridHandler::renderFilter()
|
||||
*/
|
||||
public function renderFilter($request, $filterData = [])
|
||||
{
|
||||
$userDao = Repo::user()->dao;
|
||||
return parent::renderFilter($request, array_merge_recursive(
|
||||
$filterData,
|
||||
[
|
||||
'fieldOptions' => [
|
||||
Identity::IDENTITY_SETTING_GIVENNAME => 'user.givenName',
|
||||
Identity::IDENTITY_SETTING_FAMILYNAME => 'user.familyName',
|
||||
$userDao::USER_FIELD_USERNAME => 'user.username',
|
||||
$userDao::USER_FIELD_EMAIL => 'user.email',
|
||||
SubscriptionDAO::SUBSCRIPTION_MEMBERSHIP => 'user.subscriptions.form.membership',
|
||||
SubscriptionDAO::SUBSCRIPTION_REFERENCE_NUMBER => 'manager.subscriptions.form.referenceNumber',
|
||||
SubscriptionDAO::SUBSCRIPTION_NOTES => 'manager.subscriptions.form.notes',
|
||||
],
|
||||
'matchOptions' => [
|
||||
'contains' => 'form.contains',
|
||||
'is' => 'form.is'
|
||||
]
|
||||
]
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::loadData()
|
||||
*/
|
||||
protected function loadData($request, $filter)
|
||||
{
|
||||
// Get the context.
|
||||
$journal = $request->getContext();
|
||||
|
||||
$subscriptionDao = DAORegistry::getDAO('IndividualSubscriptionDAO'); /** @var IndividualSubscriptionDAO $subscriptionDao */
|
||||
$rangeInfo = $this->getGridRangeInfo($request, $this->getId());
|
||||
return $subscriptionDao->getByJournalId($journal->getId(), null, $filter['searchField'], $filter['searchMatch'], $filter['search'] ? $filter['search'] : null, null, null, null, $rangeInfo);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Public grid actions.
|
||||
//
|
||||
/**
|
||||
* Edit an existing subscription.
|
||||
*
|
||||
* @param array $args
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function editSubscription($args, $request)
|
||||
{
|
||||
// Form handling.
|
||||
$subscriptionForm = new IndividualSubscriptionForm($request, $request->getUserVar('rowId'));
|
||||
$subscriptionForm->initData();
|
||||
|
||||
return new JSONMessage(true, $subscriptionForm->fetch($request));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update an existing subscription.
|
||||
*
|
||||
* @param array $args
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function updateSubscription($args, $request)
|
||||
{
|
||||
$subscriptionId = $request->getUserVar('subscriptionId');
|
||||
// Form handling.
|
||||
$subscriptionForm = new IndividualSubscriptionForm($request, $subscriptionId);
|
||||
$subscriptionForm->readInputData();
|
||||
|
||||
if ($subscriptionForm->validate()) {
|
||||
$subscriptionForm->execute();
|
||||
$notificationManager = new NotificationManager();
|
||||
$notificationManager->createTrivialNotification($request->getUser()->getId(), PKPNotification::NOTIFICATION_TYPE_SUCCESS);
|
||||
// Prepare the grid row data.
|
||||
return DAO::getDataChangedEvent($subscriptionId);
|
||||
} else {
|
||||
return new JSONMessage(true, $subscriptionForm->fetch($request));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a subscription.
|
||||
*
|
||||
* @param array $args
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function deleteSubscription($args, $request)
|
||||
{
|
||||
if (!$request->checkCSRF()) {
|
||||
return new JSONMessage(false);
|
||||
}
|
||||
|
||||
$context = $request->getContext();
|
||||
$user = $request->getUser();
|
||||
|
||||
// Identify the subscription ID.
|
||||
$subscriptionId = $request->getUserVar('rowId');
|
||||
$subscriptionDao = DAORegistry::getDAO('IndividualSubscriptionDAO'); /** @var IndividualSubscriptionDAO $subscriptionDao */
|
||||
$subscriptionDao->deleteById($subscriptionId, $context->getId());
|
||||
return DAO::getDataChangedEvent();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,225 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/subscriptions/InstitutionalSubscriptionForm.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 InstitutionalSubscriptionForm
|
||||
*
|
||||
* @ingroup subscription
|
||||
*
|
||||
* @brief Form class for institutional subscription create/edits.
|
||||
*/
|
||||
|
||||
namespace APP\controllers\grid\subscriptions;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\core\Request;
|
||||
use APP\facades\Repo;
|
||||
use APP\notification\NotificationManager;
|
||||
use APP\subscription\form\SubscriptionForm;
|
||||
use APP\subscription\InstitutionalSubscription;
|
||||
use APP\subscription\InstitutionalSubscriptionDAO;
|
||||
use APP\subscription\SubscriptionType;
|
||||
use APP\subscription\SubscriptionTypeDAO;
|
||||
use APP\template\TemplateManager;
|
||||
use Exception;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use PKP\db\DAORegistry;
|
||||
use PKP\notification\PKPNotification;
|
||||
|
||||
class InstitutionalSubscriptionForm extends SubscriptionForm
|
||||
{
|
||||
/** @var array of the journal institutions [institutionId => name] */
|
||||
public array $institutions;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param Request $request
|
||||
* @param int $subscriptionId leave as default for new subscription
|
||||
*/
|
||||
public function __construct($request, $subscriptionId = null)
|
||||
{
|
||||
parent::__construct('payments/institutionalSubscriptionForm.tpl', $subscriptionId);
|
||||
|
||||
$subscriptionId = isset($subscriptionId) ? (int) $subscriptionId : null;
|
||||
|
||||
$journal = $request->getJournal();
|
||||
$journalId = $journal->getId();
|
||||
|
||||
$subscriptionInstitutionId = null;
|
||||
|
||||
if (isset($subscriptionId)) {
|
||||
/** @var InstitutionalSubscriptionDAO */
|
||||
$subscriptionDao = DAORegistry::getDAO('InstitutionalSubscriptionDAO');
|
||||
if ($subscriptionDao->subscriptionExists($subscriptionId)) {
|
||||
$this->subscription = $subscriptionDao->getById($subscriptionId);
|
||||
$subscriptionInstitutionId = $this->subscription->getInstitutionId();
|
||||
}
|
||||
}
|
||||
|
||||
$subscriptionTypeDao = DAORegistry::getDAO('SubscriptionTypeDAO'); /** @var SubscriptionTypeDAO $subscriptionTypeDao */
|
||||
$subscriptionTypeIterator = $subscriptionTypeDao->getByInstitutional($journalId, true);
|
||||
$this->subscriptionTypes = [];
|
||||
while ($subscriptionType = $subscriptionTypeIterator->next()) {
|
||||
$this->subscriptionTypes[$subscriptionType->getId()] = $subscriptionType->getSummaryString();
|
||||
}
|
||||
if (count($this->subscriptionTypes) == 0) {
|
||||
$this->addError('typeId', __('manager.subscriptions.form.typeRequired'));
|
||||
$this->addErrorField('typeId');
|
||||
}
|
||||
|
||||
$institutions = Repo::institution()->getCollector()
|
||||
->filterByContextIds([$journalId])
|
||||
->getMany();
|
||||
|
||||
$this->institutions = [];
|
||||
foreach ($institutions as $institution) {
|
||||
$this->institutions[$institution->getId()] = $institution->getLocalizedName();
|
||||
}
|
||||
if (isset($subscriptionInstitutionId) && !array_key_exists($subscriptionInstitutionId, $this->institutions)) {
|
||||
// The institution is soft deleted, add it to the institutions list
|
||||
$subscriptionInstitution = Repo::institution()->get($subscriptionInstitutionId);
|
||||
$this->institutions[$subscriptionInstitutionId] = $subscriptionInstitution->getLocalizedName();
|
||||
}
|
||||
if (!count($this->institutions)) {
|
||||
$this->addError('institutionId', __('manager.subscriptions.form.institutionRequired'));
|
||||
$this->addErrorField('institutionId');
|
||||
}
|
||||
|
||||
// Ensure subscription type is valid
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorCustom($this, 'typeId', 'required', 'manager.subscriptions.form.typeIdValid', function ($typeId) use ($journalId) {
|
||||
$subscriptionTypeDao = DAORegistry::getDAO('SubscriptionTypeDAO'); /** @var SubscriptionTypeDAO $subscriptionTypeDao */
|
||||
return $subscriptionTypeDao->subscriptionTypeExistsByTypeId($typeId, $journalId) && $subscriptionTypeDao->getSubscriptionTypeInstitutional($typeId);
|
||||
}));
|
||||
|
||||
// Ensure institution ID exists
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorCustom($this, 'institutionId', 'required', 'manager.subscriptions.form.institutionIdValid', function ($institutionId) use ($journalId, $subscriptionInstitutionId) {
|
||||
return ($institutionId == $subscriptionInstitutionId) || Repo::institution()->exists($institutionId, $journalId);
|
||||
}));
|
||||
|
||||
// If provided, domain is valid
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorRegExp($this, 'domain', 'optional', 'manager.subscriptions.form.domainValid', '/^' .
|
||||
'[A-Z0-9]+([\-_\.][A-Z0-9]+)*' .
|
||||
'\.' .
|
||||
'[A-Z]{2,4}' .
|
||||
'$/i'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::fetch
|
||||
*
|
||||
* @param null|string $template
|
||||
*/
|
||||
public function fetch($request, $template = null, $display = false)
|
||||
{
|
||||
$templateMgr = TemplateManager::getManager($request);
|
||||
$templateMgr->assign([
|
||||
'institutions' => $this->institutions,
|
||||
]);
|
||||
return parent::fetch($request, $template, $display);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize form data from current subscription.
|
||||
*/
|
||||
public function initData()
|
||||
{
|
||||
parent::initData();
|
||||
|
||||
if (isset($this->subscription)) {
|
||||
/** @var InstitutionalSubscription */
|
||||
$subscription = $this->subscription;
|
||||
$this->_data = array_merge(
|
||||
$this->_data,
|
||||
[
|
||||
'institutionMailingAddress' => $subscription->getInstitutionMailingAddress(),
|
||||
'domain' => $subscription->getDomain(),
|
||||
'institutionId' => $subscription->getInstitutionId(),
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign form data to user-submitted data.
|
||||
*/
|
||||
public function readInputData()
|
||||
{
|
||||
parent::readInputData();
|
||||
$this->readUserVars(['institutionMailingAddress', 'domain', 'institutionId']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::validate()
|
||||
*/
|
||||
public function validate($callHooks = true)
|
||||
{
|
||||
if (!parent::validate()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$subscriptionTypeDao = DAORegistry::getDAO('SubscriptionTypeDAO'); /** @var SubscriptionTypeDAO $subscriptionTypeDao */
|
||||
$subscriptionType = $subscriptionTypeDao->getById($this->getData('typeId'));
|
||||
|
||||
$institution = Repo::institution()->get($this->getData('institutionId'));
|
||||
$ipRanges = $institution->getIPRanges();
|
||||
|
||||
$domain = $this->getData('domain');
|
||||
// If online or print + online, domain or at least one IP range has to be provided
|
||||
if ($subscriptionType->getFormat() != SubscriptionType::SUBSCRIPTION_TYPE_FORMAT_PRINT) {
|
||||
if (empty($domain) && empty($ipRanges)) {
|
||||
$this->addError('domain', __('manager.subscriptions.form.domainIPRangeRequired'));
|
||||
$this->addErrorField('domain');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::execute()
|
||||
*/
|
||||
public function execute(...$functionArgs)
|
||||
{
|
||||
$insert = false;
|
||||
if (!isset($this->subscription)) {
|
||||
$this->subscription = new InstitutionalSubscription();
|
||||
$insert = true;
|
||||
}
|
||||
|
||||
/** @var InstitutionalSubscription */
|
||||
$subscription = $this->subscription;
|
||||
|
||||
parent::execute(...$functionArgs);
|
||||
|
||||
$subscription->setInstitutionId($this->getData('institutionId'));
|
||||
$subscription->setInstitutionMailingAddress($this->getData('institutionMailingAddress'));
|
||||
$subscription->setDomain($this->getData('domain'));
|
||||
|
||||
/** @var InstitutionalSubscriptionDAO $institutionalSubscriptionDao */
|
||||
$institutionalSubscriptionDao = DAORegistry::getDAO('InstitutionalSubscriptionDAO');
|
||||
if ($insert) {
|
||||
$institutionalSubscriptionDao->insertObject($this->subscription);
|
||||
} else {
|
||||
$institutionalSubscriptionDao->updateObject($this->subscription);
|
||||
}
|
||||
|
||||
// Send notification email
|
||||
if ($this->getData('notifyEmail')) {
|
||||
$mailable = $this->_prepareNotificationEmail();
|
||||
try {
|
||||
Mail::send($mailable);
|
||||
} catch (Exception $e) {
|
||||
$notificationMgr = new NotificationManager();
|
||||
$request = Application::get()->getRequest();
|
||||
$notificationMgr->createTrivialNotification($request->getUser()->getId(), PKPNotification::NOTIFICATION_TYPE_ERROR, ['contents' => __('email.compose.error')]);
|
||||
error_log($e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,221 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/subscriptions/InstitutionalSubscriptionsGridHandler.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 InstitutionalSubscriptionsGridHandler
|
||||
*
|
||||
* @ingroup controllers_grid_subscriptions
|
||||
*
|
||||
* @brief Handle subscription grid requests.
|
||||
*/
|
||||
|
||||
namespace APP\controllers\grid\subscriptions;
|
||||
|
||||
use APP\core\Request;
|
||||
use APP\facades\Repo;
|
||||
use APP\notification\NotificationManager;
|
||||
use APP\subscription\InstitutionalSubscriptionDAO;
|
||||
use APP\subscription\SubscriptionDAO;
|
||||
use PKP\controllers\grid\GridColumn;
|
||||
use PKP\core\JSONMessage;
|
||||
use PKP\db\DAO;
|
||||
use PKP\db\DAORegistry;
|
||||
use PKP\identity\Identity;
|
||||
use PKP\notification\PKPNotification;
|
||||
|
||||
class InstitutionalSubscriptionsGridHandler extends SubscriptionsGridHandler
|
||||
{
|
||||
/**
|
||||
* @copydoc SubscriptionsGridHandler::initialize()
|
||||
*
|
||||
* @param null|mixed $args
|
||||
*/
|
||||
public function initialize($request, $args = null)
|
||||
{
|
||||
parent::initialize($request, $args);
|
||||
|
||||
// Basic grid configuration.
|
||||
$this->setTitle('subscriptionManager.institutionalSubscriptions');
|
||||
|
||||
//
|
||||
// Grid columns.
|
||||
//
|
||||
$cellProvider = new SubscriptionsGridCellProvider();
|
||||
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'name',
|
||||
'common.name',
|
||||
null,
|
||||
null,
|
||||
$cellProvider
|
||||
)
|
||||
);
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'subscriptionType',
|
||||
'manager.subscriptions.subscriptionType',
|
||||
null,
|
||||
null,
|
||||
$cellProvider
|
||||
)
|
||||
);
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'status',
|
||||
'manager.subscriptions.form.status',
|
||||
null,
|
||||
null,
|
||||
$cellProvider
|
||||
)
|
||||
);
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'dateStart',
|
||||
'manager.subscriptions.dateStart',
|
||||
null,
|
||||
null,
|
||||
$cellProvider
|
||||
)
|
||||
);
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'dateEnd',
|
||||
'manager.subscriptions.dateEnd',
|
||||
null,
|
||||
null,
|
||||
$cellProvider
|
||||
)
|
||||
);
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'referenceNumber',
|
||||
'manager.subscriptions.referenceNumber',
|
||||
null,
|
||||
null,
|
||||
$cellProvider
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Implement methods from GridHandler.
|
||||
//
|
||||
/**
|
||||
* @copydoc GridHandler::renderFilter()
|
||||
*/
|
||||
public function renderFilter($request, $filterData = [])
|
||||
{
|
||||
$userDao = Repo::user()->dao;
|
||||
$filterData = array_merge($filterData, [
|
||||
'fieldOptions' => [
|
||||
Identity::IDENTITY_SETTING_GIVENNAME => 'user.givenName',
|
||||
Identity::IDENTITY_SETTING_FAMILYNAME => 'user.familyName',
|
||||
$userDao::USER_FIELD_USERNAME => 'user.username',
|
||||
$userDao::USER_FIELD_EMAIL => 'user.email',
|
||||
SubscriptionDAO::SUBSCRIPTION_MEMBERSHIP => 'user.subscriptions.form.membership',
|
||||
SubscriptionDAO::SUBSCRIPTION_REFERENCE_NUMBER => 'manager.subscriptions.form.referenceNumber',
|
||||
SubscriptionDAO::SUBSCRIPTION_NOTES => 'manager.subscriptions.form.notes',
|
||||
InstitutionalSubscriptionDAO::SUBSCRIPTION_INSTITUTION_NAME => 'manager.subscriptions.form.institutionName',
|
||||
InstitutionalSubscriptionDAO::SUBSCRIPTION_DOMAIN => 'manager.subscriptions.form.domain',
|
||||
InstitutionalSubscriptionDAO::SUBSCRIPTION_IP_RANGE => 'manager.subscriptions.form.ipRange',
|
||||
],
|
||||
'matchOptions' => [
|
||||
'contains' => 'form.contains',
|
||||
'is' => 'form.is'
|
||||
],
|
||||
]);
|
||||
|
||||
return parent::renderFilter($request, $filterData);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::loadData()
|
||||
*/
|
||||
protected function loadData($request, $filter)
|
||||
{
|
||||
// Get the context.
|
||||
$journal = $request->getContext();
|
||||
|
||||
$subscriptionDao = DAORegistry::getDAO('InstitutionalSubscriptionDAO'); /** @var InstitutionalSubscriptionDAO $subscriptionDao */
|
||||
$rangeInfo = $this->getGridRangeInfo($request, $this->getId());
|
||||
return $subscriptionDao->getByJournalId($journal->getId(), null, $filter['searchField'], $filter['searchMatch'], $filter['search'] ? $filter['search'] : null, null, null, null, $rangeInfo);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Public grid actions.
|
||||
//
|
||||
/**
|
||||
* Edit an existing subscription.
|
||||
*
|
||||
* @param array $args
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function editSubscription($args, $request)
|
||||
{
|
||||
// Form handling.
|
||||
$subscriptionForm = new InstitutionalSubscriptionForm($request, $request->getUserVar('rowId'));
|
||||
$subscriptionForm->initData();
|
||||
|
||||
return new JSONMessage(true, $subscriptionForm->fetch($request));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update an existing subscription.
|
||||
*
|
||||
* @param array $args
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function updateSubscription($args, $request)
|
||||
{
|
||||
$subscriptionId = (int) $request->getUserVar('subscriptionId');
|
||||
// Form handling.
|
||||
$subscriptionForm = new InstitutionalSubscriptionForm($request, $subscriptionId);
|
||||
$subscriptionForm->readInputData();
|
||||
|
||||
if ($subscriptionForm->validate()) {
|
||||
$subscriptionForm->execute();
|
||||
$notificationManager = new NotificationManager();
|
||||
$notificationManager->createTrivialNotification($request->getUser()->getId(), PKPNotification::NOTIFICATION_TYPE_SUCCESS);
|
||||
// Prepare the grid row data.
|
||||
return DAO::getDataChangedEvent($subscriptionId);
|
||||
} else {
|
||||
return new JSONMessage(true, $subscriptionForm->fetch($request));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a subscription.
|
||||
*
|
||||
* @param array $args
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function deleteSubscription($args, $request)
|
||||
{
|
||||
if (!$request->checkCSRF()) {
|
||||
return new JSONMessage(false);
|
||||
}
|
||||
|
||||
$context = $request->getContext();
|
||||
$user = $request->getUser();
|
||||
|
||||
// Identify the subscription ID.
|
||||
$subscriptionId = $request->getUserVar('rowId');
|
||||
$subscriptionDao = DAORegistry::getDAO('InstitutionalSubscriptionDAO'); /** @var InstitutionalSubscriptionDAO $subscriptionDao */
|
||||
$subscriptionDao->deleteById($subscriptionId, $context->getId());
|
||||
return DAO::getDataChangedEvent();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/subscriptions/PaymentsGridCellProvider.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 PaymentsGridCellProvider
|
||||
*
|
||||
* @ingroup controllers_grid_subscriptions
|
||||
*
|
||||
* @brief Class for a cell provider to display information about payments
|
||||
*/
|
||||
|
||||
namespace APP\controllers\grid\subscriptions;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\core\Request;
|
||||
use APP\facades\Repo;
|
||||
use PKP\controllers\grid\GridCellProvider;
|
||||
use PKP\controllers\grid\GridColumn;
|
||||
|
||||
class PaymentsGridCellProvider extends GridCellProvider
|
||||
{
|
||||
/** @var Request */
|
||||
public $_request;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param Request $request
|
||||
*/
|
||||
public function __construct($request)
|
||||
{
|
||||
$this->_request = $request;
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
//
|
||||
// Template methods from GridCellProvider
|
||||
//
|
||||
|
||||
/**
|
||||
* Extracts variables for a given column from a data element
|
||||
* so that they may be assigned to template before rendering.
|
||||
*
|
||||
* @param \PKP\controllers\grid\GridRow $row
|
||||
* @param GridColumn $column
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getTemplateVarsFromRowColumn($row, $column)
|
||||
{
|
||||
$payment = $row->getData();
|
||||
|
||||
switch ($column->getId()) {
|
||||
case 'name':
|
||||
$user = Repo::user()->get($payment->getUserId(), true);
|
||||
return ['label' => $user ? $user->getFullName() : __('common.user.nonexistent')]; // If no $user, returns "[Nonexistent user]" to avoid null user
|
||||
case 'type':
|
||||
$paymentManager = Application::getPaymentManager($this->_request->getJournal());
|
||||
return ['label' => $paymentManager->getPaymentName($payment)];
|
||||
case 'amount':
|
||||
return ['label' => $payment->getAmount() . ' ' . $payment->getCurrencyCode()];
|
||||
case 'timestamp':
|
||||
return ['label' => $payment->getTimestamp()];
|
||||
}
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/subscriptions/PaymentsGridHandler.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 PaymentsGridHandler
|
||||
*
|
||||
* @ingroup controllers_grid_subscriptions
|
||||
*
|
||||
* @brief Handle payment grid requests.
|
||||
*/
|
||||
|
||||
namespace APP\controllers\grid\subscriptions;
|
||||
|
||||
use APP\core\Request;
|
||||
use APP\payment\ojs\OJSCompletedPaymentDAO;
|
||||
use PKP\controllers\grid\feature\PagingFeature;
|
||||
use PKP\controllers\grid\GridColumn;
|
||||
use PKP\controllers\grid\GridHandler;
|
||||
use PKP\db\DAORegistry;
|
||||
use PKP\security\authorization\ContextAccessPolicy;
|
||||
use PKP\security\Role;
|
||||
|
||||
class PaymentsGridHandler extends GridHandler
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->addRoleAssignment(
|
||||
[Role::ROLE_ID_MANAGER, Role::ROLE_ID_SITE_ADMIN, Role::ROLE_ID_SUBSCRIPTION_MANAGER],
|
||||
['fetchGrid', 'fetchRow', 'viewPayment']
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Implement template methods from PKPHandler.
|
||||
//
|
||||
/**
|
||||
* @copydoc PKPHandler::authorize()
|
||||
*/
|
||||
public function authorize($request, &$args, $roleAssignments)
|
||||
{
|
||||
$this->addPolicy(new ContextAccessPolicy($request, $roleAssignments));
|
||||
return parent::authorize($request, $args, $roleAssignments);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::initialize()
|
||||
*
|
||||
* @param null|mixed $args
|
||||
*/
|
||||
public function initialize($request, $args = null)
|
||||
{
|
||||
parent::initialize($request, $args);
|
||||
|
||||
// Grid actions.
|
||||
$router = $request->getRouter();
|
||||
|
||||
//
|
||||
// Grid columns.
|
||||
//
|
||||
$cellProvider = new PaymentsGridCellProvider($request);
|
||||
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'name',
|
||||
'common.user',
|
||||
null,
|
||||
null,
|
||||
$cellProvider
|
||||
)
|
||||
);
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'type',
|
||||
'manager.payment.paymentType',
|
||||
null,
|
||||
null,
|
||||
$cellProvider
|
||||
)
|
||||
);
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'amount',
|
||||
'manager.payment.amount',
|
||||
null,
|
||||
null,
|
||||
$cellProvider
|
||||
)
|
||||
);
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'timestamp',
|
||||
'manager.payment.timestamp',
|
||||
null,
|
||||
null,
|
||||
$cellProvider
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::initFeatures()
|
||||
*/
|
||||
public function initFeatures($request, $args)
|
||||
{
|
||||
return [new PagingFeature()];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::loadData()
|
||||
*/
|
||||
protected function loadData($request, $filter)
|
||||
{
|
||||
$paymentDao = DAORegistry::getDAO('OJSCompletedPaymentDAO'); /** @var OJSCompletedPaymentDAO $paymentDao */
|
||||
$rangeInfo = $this->getGridRangeInfo($request, $this->getId());
|
||||
return $paymentDao->getByContextId($request->getContext()->getId(), $rangeInfo);
|
||||
}
|
||||
|
||||
//
|
||||
// Public grid actions.
|
||||
//
|
||||
/**
|
||||
* View a payment.
|
||||
*
|
||||
* @param array $args
|
||||
* @param Request $request
|
||||
*/
|
||||
public function viewPayment($args, $request)
|
||||
{
|
||||
// FIXME
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,195 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/subscriptions/SubscriptionTypeForm.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 SubscriptionTypeForm
|
||||
*
|
||||
* @ingroup manager_form
|
||||
*
|
||||
* @brief Form for journal managers to create/edit subscription types.
|
||||
*/
|
||||
|
||||
namespace APP\controllers\grid\subscriptions;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\subscription\SubscriptionType;
|
||||
use APP\subscription\SubscriptionTypeDAO;
|
||||
use APP\template\TemplateManager;
|
||||
use PKP\db\DAORegistry;
|
||||
use PKP\facades\Locale;
|
||||
use PKP\form\Form;
|
||||
|
||||
class SubscriptionTypeForm extends Form
|
||||
{
|
||||
/** @var int $typeId the ID of the subscription type being edited */
|
||||
public $typeId;
|
||||
|
||||
/** @var array $validFormats keys are valid subscription type formats */
|
||||
public $validFormats;
|
||||
|
||||
/** @var array $validCurrencies keys are valid subscription type currencies */
|
||||
public $validCurrencies;
|
||||
|
||||
/** @var int $journalId Journal ID */
|
||||
public $journalId;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param int $journalId Journal ID
|
||||
* @param int $typeId leave as default for new subscription type
|
||||
* @param null|mixed $typeId
|
||||
*/
|
||||
public function __construct($journalId, $typeId = null)
|
||||
{
|
||||
$this->journalId = $journalId;
|
||||
|
||||
$this->validFormats = [
|
||||
SubscriptionType::SUBSCRIPTION_TYPE_FORMAT_ONLINE => __('subscriptionTypes.format.online'),
|
||||
SubscriptionType::SUBSCRIPTION_TYPE_FORMAT_PRINT => __('subscriptionTypes.format.print'),
|
||||
SubscriptionType::SUBSCRIPTION_TYPE_FORMAT_PRINT_ONLINE => __('subscriptionTypes.format.printOnline')
|
||||
];
|
||||
|
||||
$this->validCurrencies = [];
|
||||
foreach (Locale::getCurrencies() as $currency) {
|
||||
$this->validCurrencies[$currency->getLetterCode()] = $currency->getLocalName() . ' (' . $currency->getLetterCode() . ')';
|
||||
}
|
||||
asort($this->validCurrencies);
|
||||
|
||||
$this->typeId = isset($typeId) ? (int) $typeId : null;
|
||||
|
||||
parent::__construct('payments/subscriptionTypeForm.tpl');
|
||||
|
||||
// Type name is provided
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorLocale($this, 'name', 'required', 'manager.subscriptionTypes.form.typeNameRequired'));
|
||||
|
||||
// Cost is provided and is numeric and positive
|
||||
$this->addCheck(new \PKP\form\validation\FormValidator($this, 'cost', 'required', 'manager.subscriptionTypes.form.costRequired'));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorCustom($this, 'cost', 'required', 'manager.subscriptionTypes.form.costNumeric', fn ($cost) => is_numeric($cost) && $cost >= 0));
|
||||
|
||||
// Currency is provided and is valid value
|
||||
$this->addCheck(new \PKP\form\validation\FormValidator($this, 'currency', 'required', 'manager.subscriptionTypes.form.currencyRequired'));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorInSet($this, 'currency', 'required', 'manager.subscriptionTypes.form.currencyValid', array_keys($this->validCurrencies)));
|
||||
|
||||
// Format is provided and is valid value
|
||||
$this->addCheck(new \PKP\form\validation\FormValidator($this, 'format', 'required', 'manager.subscriptionTypes.form.formatRequired'));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorInSet($this, 'format', 'required', 'manager.subscriptionTypes.form.formatValid', array_keys($this->validFormats)));
|
||||
|
||||
// Institutional flag is valid value
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorInSet($this, 'institutional', 'optional', 'manager.subscriptionTypes.form.institutionalValid', ['0', '1']));
|
||||
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorPost($this));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorCSRF($this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of localized field names for this form
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getLocaleFieldNames()
|
||||
{
|
||||
$subscriptionTypeDao = DAORegistry::getDAO('SubscriptionTypeDAO'); /** @var SubscriptionTypeDAO $subscriptionTypeDao */
|
||||
return $subscriptionTypeDao->getLocaleFieldNames();
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::fetch()
|
||||
*
|
||||
* @param null|mixed $template
|
||||
*/
|
||||
public function fetch($request, $template = null, $display = false)
|
||||
{
|
||||
$templateMgr = TemplateManager::getManager($request);
|
||||
$templateMgr->assign([
|
||||
'typeId' => $this->typeId,
|
||||
'validCurrencies' => $this->validCurrencies,
|
||||
'validFormats' => $this->validFormats,
|
||||
]);
|
||||
return parent::fetch($request, $template, $display);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize form data from current subscription type.
|
||||
*/
|
||||
public function initData()
|
||||
{
|
||||
if (isset($this->typeId)) {
|
||||
$subscriptionTypeDao = DAORegistry::getDAO('SubscriptionTypeDAO'); /** @var SubscriptionTypeDAO $subscriptionTypeDao */
|
||||
$subscriptionType = $subscriptionTypeDao->getById($this->typeId, $this->journalId);
|
||||
|
||||
if ($subscriptionType != null) {
|
||||
$this->_data = [
|
||||
'name' => $subscriptionType->getName(null), // Localized
|
||||
'description' => $subscriptionType->getDescription(null), // Localized
|
||||
'cost' => $subscriptionType->getCost(),
|
||||
'currency' => $subscriptionType->getCurrencyCodeAlpha(),
|
||||
'duration' => $subscriptionType->getDuration(),
|
||||
'format' => $subscriptionType->getFormat(),
|
||||
'institutional' => $subscriptionType->getInstitutional(),
|
||||
'membership' => $subscriptionType->getMembership(),
|
||||
'disable_public_display' => $subscriptionType->getDisablePublicDisplay()
|
||||
];
|
||||
} else {
|
||||
$this->typeId = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign form data to user-submitted data.
|
||||
*/
|
||||
public function readInputData()
|
||||
{
|
||||
$this->readUserVars(['name', 'description', 'cost', 'currency', 'duration', 'format', 'institutional', 'membership', 'disable_public_display']);
|
||||
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorCustom($this, 'duration', 'optional', 'manager.subscriptionTypes.form.durationNumeric', fn ($duration) => is_numeric($duration) && $duration >= 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::execute()
|
||||
*/
|
||||
public function execute(...$functionArgs)
|
||||
{
|
||||
$subscriptionTypeDao = DAORegistry::getDAO('SubscriptionTypeDAO'); /** @var SubscriptionTypeDAO $subscriptionTypeDao */
|
||||
|
||||
if (isset($this->typeId)) {
|
||||
$subscriptionType = $subscriptionTypeDao->getById($this->typeId, $this->journalId);
|
||||
}
|
||||
|
||||
if (!isset($subscriptionType)) {
|
||||
$subscriptionType = $subscriptionTypeDao->newDataObject();
|
||||
$subscriptionType->setInstitutional($this->getData('institutional') == null ? 0 : $this->getData('institutional'));
|
||||
}
|
||||
|
||||
$request = Application::get()->getRequest();
|
||||
$journal = $request->getJournal();
|
||||
$subscriptionType->setJournalId($journal->getId());
|
||||
$subscriptionType->setName($this->getData('name'), null); // Localized
|
||||
$subscriptionType->setDescription($this->getData('description'), null); // Localized
|
||||
$subscriptionType->setCost(round($this->getData('cost'), 2));
|
||||
$subscriptionType->setCurrencyCodeAlpha($this->getData('currency'));
|
||||
$subscriptionType->setDuration(($duration = $this->getData('duration')) ? (int) $duration : null);
|
||||
$subscriptionType->setFormat($this->getData('format'));
|
||||
$subscriptionType->setMembership((int) $this->getData('membership'));
|
||||
$subscriptionType->setDisablePublicDisplay((int) $this->getData('disable_public_display'));
|
||||
|
||||
parent::execute(...$functionArgs);
|
||||
|
||||
// Update or insert subscription type
|
||||
if ($subscriptionType->getId() != null) {
|
||||
$subscriptionTypeDao->updateObject($subscriptionType);
|
||||
} else {
|
||||
$subscriptionType->setSequence(REALLY_BIG_NUMBER);
|
||||
$subscriptionTypeDao->insertObject($subscriptionType);
|
||||
|
||||
// Re-order the subscription types so the new one is at the end of the list.
|
||||
$subscriptionTypeDao->resequenceSubscriptionTypes($subscriptionType->getJournalId());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/subscriptions/SubscriptionTypesGridCellProvider.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 SubscriptionTypesGridCellProvider
|
||||
*
|
||||
* @ingroup controllers_grid_subscriptions
|
||||
*
|
||||
* @brief Class for a cell provider to display information about individual subscriptions
|
||||
*/
|
||||
|
||||
namespace APP\controllers\grid\subscriptions;
|
||||
|
||||
use PKP\controllers\grid\GridCellProvider;
|
||||
use PKP\controllers\grid\GridColumn;
|
||||
|
||||
class SubscriptionTypesGridCellProvider extends GridCellProvider
|
||||
{
|
||||
//
|
||||
// Template methods from GridCellProvider
|
||||
//
|
||||
|
||||
/**
|
||||
* Extracts variables for a given column from a data element
|
||||
* so that they may be assigned to template before rendering.
|
||||
*
|
||||
* @param \PKP\controllers\grid\GridRow $row
|
||||
* @param GridColumn $column
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getTemplateVarsFromRowColumn($row, $column)
|
||||
{
|
||||
$subscriptionType = $row->getData();
|
||||
|
||||
switch ($column->getId()) {
|
||||
case 'name':
|
||||
return ['label' => $subscriptionType->getLocalizedName()];
|
||||
case 'type':
|
||||
return ['label' => __($subscriptionType->getInstitutional() ? 'manager.subscriptionTypes.institutional' : 'manager.subscriptionTypes.individual')];
|
||||
case 'duration':
|
||||
return ['label' => $subscriptionType->getDurationYearsMonths()];
|
||||
case 'cost':
|
||||
return ['label' => sprintf('%.2f', $subscriptionType->getCost()) . ' (' . $subscriptionType->getCurrencyStringShort() . ')'];
|
||||
}
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,250 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/subscriptions/SubscriptionTypesGridHandler.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 SubscriptionTypesGridHandler
|
||||
*
|
||||
* @ingroup controllers_grid_subscriptions
|
||||
*
|
||||
* @brief Handle subscription type grid requests.
|
||||
*/
|
||||
|
||||
namespace APP\controllers\grid\subscriptions;
|
||||
|
||||
use APP\core\Request;
|
||||
use APP\notification\NotificationManager;
|
||||
use APP\subscription\SubscriptionTypeDAO;
|
||||
use PKP\controllers\grid\feature\PagingFeature;
|
||||
use PKP\controllers\grid\GridColumn;
|
||||
use PKP\controllers\grid\GridHandler;
|
||||
use PKP\core\JSONMessage;
|
||||
use PKP\db\DAO;
|
||||
use PKP\db\DAORegistry;
|
||||
use PKP\linkAction\LinkAction;
|
||||
use PKP\linkAction\request\AjaxModal;
|
||||
use PKP\notification\PKPNotification;
|
||||
use PKP\security\authorization\ContextAccessPolicy;
|
||||
use PKP\security\Role;
|
||||
|
||||
class SubscriptionTypesGridHandler extends GridHandler
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->addRoleAssignment(
|
||||
[Role::ROLE_ID_MANAGER, Role::ROLE_ID_SITE_ADMIN, Role::ROLE_ID_SUBSCRIPTION_MANAGER],
|
||||
['fetchGrid', 'fetchRow', 'editSubscriptionType', 'updateSubscriptionType',
|
||||
'deleteSubscriptionType', 'addSubscriptionType']
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Implement template methods from PKPHandler.
|
||||
//
|
||||
/**
|
||||
* @copydoc PKPHandler::authorize()
|
||||
*/
|
||||
public function authorize($request, &$args, $roleAssignments)
|
||||
{
|
||||
$this->addPolicy(new ContextAccessPolicy($request, $roleAssignments));
|
||||
return parent::authorize($request, $args, $roleAssignments);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::initialize()
|
||||
*
|
||||
* @param null|mixed $args
|
||||
*/
|
||||
public function initialize($request, $args = null)
|
||||
{
|
||||
parent::initialize($request, $args);
|
||||
|
||||
// Basic grid configuration.
|
||||
$this->setTitle('subscriptionManager.subscriptionTypes');
|
||||
|
||||
// Grid actions.
|
||||
$router = $request->getRouter();
|
||||
|
||||
$this->addAction(
|
||||
new LinkAction(
|
||||
'addSubscriptionType',
|
||||
new AjaxModal(
|
||||
$router->url($request, null, null, 'addSubscriptionType', null, null),
|
||||
__('manager.subscriptionTypes.create'),
|
||||
'modal_add_subscription_type',
|
||||
true
|
||||
),
|
||||
__('manager.subscriptionTypes.create'),
|
||||
'add_subscription_type'
|
||||
)
|
||||
);
|
||||
|
||||
//
|
||||
// Grid columns.
|
||||
//
|
||||
$cellProvider = new SubscriptionTypesGridCellProvider();
|
||||
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'name',
|
||||
'common.name',
|
||||
null,
|
||||
null,
|
||||
$cellProvider
|
||||
)
|
||||
);
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'type',
|
||||
'manager.subscriptionTypes.subscriptions',
|
||||
null,
|
||||
null,
|
||||
$cellProvider
|
||||
)
|
||||
);
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'duration',
|
||||
'manager.subscriptionTypes.duration',
|
||||
null,
|
||||
null,
|
||||
$cellProvider
|
||||
)
|
||||
);
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'cost',
|
||||
'manager.subscriptionTypes.cost',
|
||||
null,
|
||||
null,
|
||||
$cellProvider
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Implement methods from GridHandler.
|
||||
//
|
||||
/**
|
||||
* @copydoc GridHandler::getRowInstance()
|
||||
*
|
||||
* @return SubscriptionTypesGridRow
|
||||
*/
|
||||
protected function getRowInstance()
|
||||
{
|
||||
return new SubscriptionTypesGridRow();
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::initFeatures()
|
||||
*/
|
||||
public function initFeatures($request, $args)
|
||||
{
|
||||
return [new PagingFeature()];
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::loadData()
|
||||
*/
|
||||
protected function loadData($request, $filter)
|
||||
{
|
||||
// Get the context.
|
||||
$journal = $request->getContext();
|
||||
|
||||
$subscriptionTypeDao = DAORegistry::getDAO('SubscriptionTypeDAO'); /** @var SubscriptionTypeDAO $subscriptionTypeDao */
|
||||
$rangeInfo = $this->getGridRangeInfo($request, $this->getId());
|
||||
return $subscriptionTypeDao->getByJournalId($journal->getId(), $rangeInfo);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Public grid actions.
|
||||
//
|
||||
/**
|
||||
* Add a new subscription type.
|
||||
*
|
||||
* @param array $args
|
||||
* @param Request $request
|
||||
*/
|
||||
public function addSubscriptionType($args, $request)
|
||||
{
|
||||
// Calling editSubscription with an empty row id will add a new subscription type.
|
||||
return $this->editSubscriptionType($args, $request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit an existing subscription type.
|
||||
*
|
||||
* @param array $args
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function editSubscriptionType($args, $request)
|
||||
{
|
||||
// Form handling.
|
||||
$subscriptionTypeForm = new SubscriptionTypeForm($request->getJournal()->getId(), $request->getUserVar('rowId'));
|
||||
$subscriptionTypeForm->initData();
|
||||
return new JSONMessage(true, $subscriptionTypeForm->fetch($request));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update an existing subscription type.
|
||||
*
|
||||
* @param array $args
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function updateSubscriptionType($args, $request)
|
||||
{
|
||||
$subscriptionTypeId = (int) $request->getUserVar('typeId');
|
||||
// Form handling.
|
||||
$subscriptionTypeForm = new SubscriptionTypeForm($request->getJournal()->getId(), $subscriptionTypeId);
|
||||
$subscriptionTypeForm->readInputData();
|
||||
|
||||
if ($subscriptionTypeForm->validate()) {
|
||||
$subscriptionTypeForm->execute();
|
||||
$notificationManager = new NotificationManager();
|
||||
$notificationManager->createTrivialNotification($request->getUser()->getId(), PKPNotification::NOTIFICATION_TYPE_SUCCESS);
|
||||
// Prepare the grid row data.
|
||||
return DAO::getDataChangedEvent($subscriptionTypeId);
|
||||
} else {
|
||||
return new JSONMessage(false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a subscription type.
|
||||
*
|
||||
* @param array $args
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function deleteSubscriptionType($args, $request)
|
||||
{
|
||||
if (!$request->checkCSRF()) {
|
||||
return new JSONMessage(false);
|
||||
}
|
||||
|
||||
$context = $request->getContext();
|
||||
$user = $request->getUser();
|
||||
|
||||
// Identify the subscription type ID.
|
||||
$subscriptionTypeId = $request->getUserVar('rowId');
|
||||
$subscriptionTypeDao = DAORegistry::getDAO('SubscriptionTypeDAO'); /** @var SubscriptionTypeDAO $subscriptionTypeDao */
|
||||
$subscriptionTypeDao->deleteById($subscriptionTypeId, $context->getId());
|
||||
return DAO::getDataChangedEvent($subscriptionTypeId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/subscriptions/SubscriptionTypesGridRow.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 SubscriptionTypesGridRow
|
||||
*
|
||||
* @ingroup controllers_grid_subscriptions
|
||||
*
|
||||
* @brief User grid row definition
|
||||
*/
|
||||
|
||||
namespace APP\controllers\grid\subscriptions;
|
||||
|
||||
use PKP\controllers\grid\GridRow;
|
||||
use PKP\linkAction\LinkAction;
|
||||
use PKP\linkAction\request\AjaxModal;
|
||||
use PKP\linkAction\request\RemoteActionConfirmationModal;
|
||||
|
||||
class SubscriptionTypesGridRow extends GridRow
|
||||
{
|
||||
//
|
||||
// Overridden methods from GridRow
|
||||
//
|
||||
/**
|
||||
* @copydoc GridRow::initialize()
|
||||
*
|
||||
* @param null|mixed $template
|
||||
*/
|
||||
public function initialize($request, $template = null)
|
||||
{
|
||||
parent::initialize($request, $template);
|
||||
|
||||
// Is this a new row or an existing row?
|
||||
$element = & $this->getData();
|
||||
assert(is_a($element, 'SubscriptionType'));
|
||||
|
||||
$rowId = $this->getId();
|
||||
if (!empty($rowId) && is_numeric($rowId)) {
|
||||
// Only add row actions if this is an existing row
|
||||
$router = $request->getRouter();
|
||||
$actionArgs = [
|
||||
'gridId' => $this->getGridId(),
|
||||
'rowId' => $rowId
|
||||
];
|
||||
|
||||
$actionArgs = array_merge($actionArgs, $this->getRequestArgs());
|
||||
|
||||
$this->addAction(
|
||||
new LinkAction(
|
||||
'edit',
|
||||
new AjaxModal(
|
||||
$router->url($request, null, null, 'editSubscriptionType', null, $actionArgs),
|
||||
__('manager.subscriptionTypes.edit'),
|
||||
'modal_edit',
|
||||
true
|
||||
),
|
||||
__('common.edit'),
|
||||
'edit'
|
||||
)
|
||||
);
|
||||
$this->addAction(
|
||||
new LinkAction(
|
||||
'delete',
|
||||
new RemoteActionConfirmationModal(
|
||||
$request->getSession(),
|
||||
__('manager.subscriptionTypes.confirmDelete'),
|
||||
__('common.delete'),
|
||||
$router->url($request, null, null, 'deleteSubscriptionType', null, $actionArgs),
|
||||
'modal_delete'
|
||||
),
|
||||
__('grid.action.delete'),
|
||||
'delete'
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/subscriptions/SubscriptionsGridCellProvider.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 SubscriptionsGridCellProvider
|
||||
*
|
||||
* @ingroup controllers_grid_subscriptions
|
||||
*
|
||||
* @brief Class for a cell provider to display information about subscriptions
|
||||
*/
|
||||
|
||||
namespace APP\controllers\grid\subscriptions;
|
||||
|
||||
use APP\facades\Repo;
|
||||
use PKP\controllers\grid\GridCellProvider;
|
||||
use PKP\controllers\grid\GridColumn;
|
||||
|
||||
class SubscriptionsGridCellProvider extends GridCellProvider
|
||||
{
|
||||
//
|
||||
// Template methods from GridCellProvider
|
||||
//
|
||||
|
||||
/**
|
||||
* Extracts variables for a given column from a data element
|
||||
* so that they may be assigned to template before rendering.
|
||||
*
|
||||
* @param \PKP\controllers\grid\GridRow $row
|
||||
* @param GridColumn $column
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getTemplateVarsFromRowColumn($row, $column)
|
||||
{
|
||||
$subscription = $row->getData();
|
||||
|
||||
switch ($column->getId()) {
|
||||
case 'name':
|
||||
switch (1) {
|
||||
case is_a($subscription, 'IndividualSubscription'):
|
||||
return ['label' => $subscription->getUserFullName()];
|
||||
case is_a($subscription, 'InstitutionalSubscription'):
|
||||
$institution = Repo::institution()->get($subscription->getInstitutionId());
|
||||
return ['label' => $institution->getLocalizedName()];
|
||||
}
|
||||
assert(false);
|
||||
break;
|
||||
case 'email':
|
||||
assert(is_a($subscription, 'IndividualSubscription'));
|
||||
return ['label' => $subscription->getUserEmail()];
|
||||
case 'subscriptionType':
|
||||
return ['label' => $subscription->getSubscriptionTypeName()];
|
||||
case 'status':
|
||||
return ['label' => $subscription->getStatusString()];
|
||||
case 'dateStart':
|
||||
return ['label' => $subscription->getDateStart()];
|
||||
case 'dateEnd':
|
||||
return ['label' => $subscription->getDateEnd()];
|
||||
case 'referenceNumber':
|
||||
return ['label' => $subscription->getReferenceNumber()];
|
||||
}
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/subscriptions/SubscriptionsGridHandler.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 SubscriptionsGridHandler
|
||||
*
|
||||
* @ingroup controllers_grid_subscriptions
|
||||
*
|
||||
* @brief Handle subscription grid requests.
|
||||
*/
|
||||
|
||||
namespace APP\controllers\grid\subscriptions;
|
||||
|
||||
use APP\core\Request;
|
||||
use APP\subscription\IndividualSubscriptionDAO;
|
||||
use APP\subscription\InstitutionalSubscriptionDAO;
|
||||
use PKP\controllers\grid\feature\PagingFeature;
|
||||
use PKP\controllers\grid\GridHandler;
|
||||
use PKP\db\DAO;
|
||||
use PKP\db\DAORegistry;
|
||||
use PKP\linkAction\LinkAction;
|
||||
use PKP\linkAction\request\AjaxModal;
|
||||
use PKP\security\authorization\ContextAccessPolicy;
|
||||
use PKP\security\Role;
|
||||
|
||||
abstract class SubscriptionsGridHandler extends GridHandler
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->addRoleAssignment(
|
||||
[Role::ROLE_ID_MANAGER, Role::ROLE_ID_SITE_ADMIN, Role::ROLE_ID_SUBSCRIPTION_MANAGER],
|
||||
['fetchGrid', 'fetchRow', 'editSubscription', 'updateSubscription',
|
||||
'deleteSubscription', 'addSubscription', 'renewSubscription']
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Implement template methods from PKPHandler.
|
||||
//
|
||||
/**
|
||||
* @copydoc PKPHandler::authorize()
|
||||
*/
|
||||
public function authorize($request, &$args, $roleAssignments)
|
||||
{
|
||||
$this->addPolicy(new ContextAccessPolicy($request, $roleAssignments));
|
||||
return parent::authorize($request, $args, $roleAssignments);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::initialize()
|
||||
*
|
||||
* @param null|mixed $args
|
||||
*/
|
||||
public function initialize($request, $args = null)
|
||||
{
|
||||
parent::initialize($request, $args);
|
||||
|
||||
// Grid actions.
|
||||
$router = $request->getRouter();
|
||||
|
||||
$this->addAction(
|
||||
new LinkAction(
|
||||
'addSubscription',
|
||||
new AjaxModal(
|
||||
$router->url($request, null, null, 'addSubscription', null, null),
|
||||
__('manager.subscriptions.create'),
|
||||
'modal_add_subscription',
|
||||
true
|
||||
),
|
||||
__('manager.subscriptions.create'),
|
||||
'add_subscription'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::initFeatures()
|
||||
*/
|
||||
public function initFeatures($request, $args)
|
||||
{
|
||||
return [new PagingFeature()];
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::getRowInstance()
|
||||
*
|
||||
* @return SubscriptionsGridRow
|
||||
*/
|
||||
protected function getRowInstance()
|
||||
{
|
||||
return new SubscriptionsGridRow();
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::getFilterSelectionData()
|
||||
*
|
||||
* @return array Filter selection data.
|
||||
*/
|
||||
public function getFilterSelectionData($request)
|
||||
{
|
||||
// Get the search terms.
|
||||
$searchField = $request->getUserVar('searchField');
|
||||
$searchMatch = $request->getUserVar('searchMatch');
|
||||
$search = $request->getUserVar('search');
|
||||
|
||||
return $filterSelectionData = [
|
||||
'searchField' => $searchField,
|
||||
'searchMatch' => $searchMatch,
|
||||
'search' => $search ? $search : ''
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::getFilterForm()
|
||||
*
|
||||
* @return string Filter template.
|
||||
*/
|
||||
protected function getFilterForm()
|
||||
{
|
||||
return 'controllers/grid/subscriptions/subscriptionsGridFilter.tpl';
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Public grid actions.
|
||||
//
|
||||
/**
|
||||
* Add a new subscription.
|
||||
*
|
||||
* @param array $args
|
||||
* @param Request $request
|
||||
*/
|
||||
public function addSubscription($args, $request)
|
||||
{
|
||||
// Calling editSubscription with an empty row id will add a new subscription.
|
||||
return $this->editSubscription($args, $request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renew a subscription.
|
||||
*
|
||||
* @param array $args first parameter is the ID of the subscription to renew
|
||||
* @param Request $request
|
||||
*/
|
||||
public function renewSubscription($args, $request)
|
||||
{
|
||||
/** @var InstitutionalSubscriptionDAO|IndividualSubscriptionDAO */
|
||||
$subscriptionDao = DAORegistry::getDAO($request->getUserVar('institutional') ? 'InstitutionalSubscriptionDAO' : 'IndividualSubscriptionDAO');
|
||||
$subscriptionId = $request->getUserVar('rowId');
|
||||
if ($subscription = $subscriptionDao->getById($subscriptionId, $request->getJournal()->getId())) {
|
||||
$subscriptionDao->renewSubscription($subscription);
|
||||
}
|
||||
return DAO::getDataChangedEvent($subscriptionId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/subscriptions/SubscriptionsGridRow.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 SubscriptionsGridRow
|
||||
*
|
||||
* @ingroup controllers_grid_subscriptions
|
||||
*
|
||||
* @brief Subscriptions grid row definition
|
||||
*/
|
||||
|
||||
namespace APP\controllers\grid\subscriptions;
|
||||
|
||||
use PKP\controllers\grid\GridRow;
|
||||
use PKP\linkAction\LinkAction;
|
||||
use PKP\linkAction\request\AjaxModal;
|
||||
use PKP\linkAction\request\RemoteActionConfirmationModal;
|
||||
|
||||
class SubscriptionsGridRow extends GridRow
|
||||
{
|
||||
//
|
||||
// Overridden methods from GridRow
|
||||
//
|
||||
/**
|
||||
* @copydoc GridRow::initialize()
|
||||
*
|
||||
* @param null|mixed $template
|
||||
*/
|
||||
public function initialize($request, $template = null)
|
||||
{
|
||||
parent::initialize($request, $template);
|
||||
|
||||
// Is this a new row or an existing row?
|
||||
$element = & $this->getData();
|
||||
assert(is_a($element, 'IndividualSubscription') || is_a($element, 'InstitutionalSubscription'));
|
||||
|
||||
$rowId = $this->getId();
|
||||
|
||||
if (!empty($rowId) && is_numeric($rowId)) {
|
||||
// Only add row actions if this is an existing row
|
||||
$router = $request->getRouter();
|
||||
$actionArgs = [
|
||||
'gridId' => $this->getGridId(),
|
||||
'rowId' => $rowId
|
||||
];
|
||||
|
||||
$actionArgs = array_merge($actionArgs, $this->getRequestArgs());
|
||||
|
||||
$this->addAction(new LinkAction(
|
||||
'edit',
|
||||
new AjaxModal(
|
||||
$router->url($request, null, null, 'editSubscription', null, $actionArgs),
|
||||
__('manager.subscriptions.edit'),
|
||||
'modal_edit',
|
||||
true
|
||||
),
|
||||
__('common.edit'),
|
||||
'edit'
|
||||
));
|
||||
if (!$element->isNonExpiring()) {
|
||||
$this->addAction(new LinkAction(
|
||||
'renew',
|
||||
new RemoteActionConfirmationModal(
|
||||
$request->getSession(),
|
||||
__('manager.subscriptions.confirmRenew'),
|
||||
__('manager.subscriptions.renew'),
|
||||
$router->url(
|
||||
$request,
|
||||
null,
|
||||
null,
|
||||
'renewSubscription',
|
||||
null,
|
||||
array_merge($actionArgs, [
|
||||
'institutional' => is_a($element, 'InstitutionalSubscription') ? 1 : 0
|
||||
])
|
||||
),
|
||||
'modal_delete'
|
||||
),
|
||||
__('manager.subscriptions.renew'),
|
||||
'renew'
|
||||
));
|
||||
}
|
||||
$this->addAction(new LinkAction(
|
||||
'delete',
|
||||
new RemoteActionConfirmationModal(
|
||||
$request->getSession(),
|
||||
__('subscriptionManager.subscription.confirmRemove'),
|
||||
__('common.delete'),
|
||||
$router->url($request, null, null, 'deleteSubscription', null, $actionArgs),
|
||||
'modal_delete'
|
||||
),
|
||||
__('grid.action.delete'),
|
||||
'delete'
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/toc/TocGridCategoryRow.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 TocGridCategoryRow
|
||||
*
|
||||
* @ingroup controllers_grid_admin_systemInfo
|
||||
*
|
||||
* @brief System Info grid category row definition
|
||||
*/
|
||||
|
||||
namespace APP\controllers\grid\toc;
|
||||
|
||||
use PKP\controllers\grid\GridCategoryRow;
|
||||
|
||||
class TocGridCategoryRow extends GridCategoryRow
|
||||
{
|
||||
//
|
||||
// Overridden methods from GridCategoryRow
|
||||
//
|
||||
/**
|
||||
* Use a label if the actions in the grid are disabled.
|
||||
* return string
|
||||
*/
|
||||
public function getCategoryLabel()
|
||||
{
|
||||
$section = $this->getData();
|
||||
return $section->getLocalizedTitle();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/toc/TocGridCellProvider.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 TocGridCellProvider
|
||||
*
|
||||
* @ingroup controllers_grid_toc
|
||||
*
|
||||
* @brief Grid cell provider for the TOC (Table of Contents) category grid
|
||||
*/
|
||||
|
||||
namespace APP\controllers\grid\toc;
|
||||
|
||||
use APP\submission\Submission;
|
||||
use PKP\controllers\grid\GridCellProvider;
|
||||
use PKP\controllers\grid\GridColumn;
|
||||
use PKP\controllers\grid\GridHandler;
|
||||
use PKP\linkAction\LinkAction;
|
||||
use PKP\linkAction\request\AjaxAction;
|
||||
|
||||
class TocGridCellProvider 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(!empty($columnId));
|
||||
switch ($columnId) {
|
||||
case 'title':
|
||||
return ['label' => $element->getLocalizedTitle()];
|
||||
case 'access':
|
||||
return ['selected' => $element->getCurrentPublication()->getData('accessStatus') == Submission::ARTICLE_ACCESS_OPEN];
|
||||
default: assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridCellProvider::getCellActions()
|
||||
*/
|
||||
public function getCellActions($request, $row, $column, $position = GridHandler::GRID_ACTION_POSITION_DEFAULT)
|
||||
{
|
||||
switch ($column->getId()) {
|
||||
case 'access':
|
||||
$article = $row->getData(); /** @var Submission $article */
|
||||
return [new LinkAction(
|
||||
'disable',
|
||||
new AjaxAction(
|
||||
$request->url(
|
||||
null,
|
||||
null,
|
||||
'setAccessStatus',
|
||||
null,
|
||||
array_merge(
|
||||
[
|
||||
'articleId' => $article->getId(),
|
||||
'status' => ($article->getCurrentPublication()->getData('accessStatus') == Submission::ARTICLE_ACCESS_OPEN) ? Submission::ARTICLE_ACCESS_ISSUE_DEFAULT : Submission::ARTICLE_ACCESS_OPEN,
|
||||
'csrfToken' => $request->getSession()->getCSRFToken(),
|
||||
],
|
||||
$row->getRequestArgs()
|
||||
)
|
||||
)
|
||||
),
|
||||
__('manager.plugins.disable'),
|
||||
null
|
||||
)];
|
||||
}
|
||||
return parent::getCellActions($request, $row, $column, $position);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,300 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/toc/TocGridHandler.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 TocGridHandler
|
||||
*
|
||||
* @ingroup controllers_grid_toc
|
||||
*
|
||||
* @brief Handle TOC (table of contents) grid requests.
|
||||
*/
|
||||
|
||||
namespace APP\controllers\grid\toc;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\core\Request;
|
||||
use APP\facades\Repo;
|
||||
use APP\section\Section;
|
||||
use APP\security\authorization\OjsIssueRequiredPolicy;
|
||||
use APP\submission\Submission;
|
||||
use PKP\controllers\grid\CategoryGridHandler;
|
||||
use PKP\controllers\grid\feature\OrderCategoryGridItemsFeature;
|
||||
use PKP\controllers\grid\GridColumn;
|
||||
use PKP\core\JSONMessage;
|
||||
use PKP\db\DAO;
|
||||
use PKP\security\authorization\ContextAccessPolicy;
|
||||
use PKP\security\Role;
|
||||
use PKP\submission\PKPSubmission;
|
||||
|
||||
class TocGridHandler extends CategoryGridHandler
|
||||
{
|
||||
public $submissionsBySectionId = [];
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->addRoleAssignment(
|
||||
[Role::ROLE_ID_MANAGER, Role::ROLE_ID_SITE_ADMIN],
|
||||
['fetchGrid', 'fetchCategory', 'fetchRow', 'saveSequence', 'removeArticle', 'setAccessStatus']
|
||||
);
|
||||
$this->submissionsBySectionId = [];
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Implement template methods from PKPHandler.
|
||||
//
|
||||
/**
|
||||
* @copydoc PKPHandler::authorize()
|
||||
*/
|
||||
public function authorize($request, &$args, $roleAssignments)
|
||||
{
|
||||
$this->addPolicy(new ContextAccessPolicy($request, $roleAssignments));
|
||||
|
||||
$this->addPolicy(new OjsIssueRequiredPolicy($request, $args));
|
||||
|
||||
return parent::authorize($request, $args, $roleAssignments);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc CategoryGridHandler::initialize()
|
||||
*
|
||||
* @param null|mixed $args
|
||||
*/
|
||||
public function initialize($request, $args = null)
|
||||
{
|
||||
parent::initialize($request, $args);
|
||||
|
||||
//
|
||||
// Grid columns.
|
||||
//
|
||||
$tocGridCellProvider = new TocGridCellProvider();
|
||||
|
||||
// Article title
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'title',
|
||||
'article.title',
|
||||
null,
|
||||
null,
|
||||
$tocGridCellProvider
|
||||
)
|
||||
);
|
||||
|
||||
$issue = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_ISSUE);
|
||||
if ($request->getJournal()->getData('publishingMode') == \APP\journal\Journal::PUBLISHING_MODE_SUBSCRIPTION && $issue->getAccessStatus() == \APP\issue\Issue::ISSUE_ACCESS_SUBSCRIPTION) {
|
||||
// Article access status
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'access',
|
||||
'reader.openAccess',
|
||||
null,
|
||||
'controllers/grid/common/cell/selectStatusCell.tpl',
|
||||
$tocGridCellProvider,
|
||||
['width' => 20, 'alignment' => GridColumn::COLUMN_ALIGNMENT_CENTER]
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::initFeatures()
|
||||
*/
|
||||
public function initFeatures($request, $args)
|
||||
{
|
||||
return [new OrderCategoryGridItemsFeature(OrderCategoryGridItemsFeature::ORDER_CATEGORY_GRID_CATEGORIES_AND_ROWS, true, $this)];
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc CategoryGridHandler::getCategoryRowIdParameterName()
|
||||
*/
|
||||
public function getCategoryRowIdParameterName()
|
||||
{
|
||||
return 'sectionId';
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridDataProvider::getRequestArgs()
|
||||
*/
|
||||
public function getRequestArgs()
|
||||
{
|
||||
$issue = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_ISSUE);
|
||||
return array_merge(
|
||||
parent::getRequestArgs(),
|
||||
['issueId' => $issue->getId()]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the row handler - override the default row handler
|
||||
*
|
||||
* @return TocGridRow
|
||||
*/
|
||||
protected function getRowInstance()
|
||||
{
|
||||
$issue = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_ISSUE);
|
||||
return new TocGridRow($issue->getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc CategoryGridHandler::getCategoryRowInstance()
|
||||
*/
|
||||
protected function getCategoryRowInstance()
|
||||
{
|
||||
return new TocGridCategoryRow();
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc CategoryGridHandler::loadCategoryData()
|
||||
*
|
||||
* @param null|mixed $filter
|
||||
*/
|
||||
public function loadCategoryData($request, &$section, $filter = null)
|
||||
{
|
||||
return $this->submissionsBySectionId[$section->getId()];
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::loadData()
|
||||
*/
|
||||
protected function loadData($request, $filter)
|
||||
{
|
||||
$issue = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_ISSUE);
|
||||
$submissionsInSections = Repo::submission()->getInSections($issue->getId(), $request->getContext()->getId());
|
||||
foreach ($submissionsInSections as $sectionId => $articles) {
|
||||
foreach ($articles['articles'] as $article) {
|
||||
$this->submissionsBySectionId[$sectionId][$article->getId()] = $article;
|
||||
}
|
||||
}
|
||||
|
||||
$sections = Repo::section()->getByIssueId($issue->getId());
|
||||
|
||||
$arrayKeySections = [];
|
||||
foreach ($sections as $section) {
|
||||
$arrayKeySections[$section->getId()] = $section;
|
||||
}
|
||||
return $arrayKeySections;
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::getDataElementSequence()
|
||||
*
|
||||
* @param Section|Submission $object
|
||||
*/
|
||||
public function getDataElementSequence($object)
|
||||
{
|
||||
if ($object instanceof Submission) {
|
||||
return $object->getCurrentPublication()->getData('seq');
|
||||
} else { // section
|
||||
$issue = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_ISSUE);
|
||||
$customOrdering = Repo::section()->getCustomSectionOrder($issue->getId(), $object->getId());
|
||||
if ($customOrdering === null) { // No custom ordering specified; use default section ordering
|
||||
return $object->getSequence();
|
||||
} else { // Custom ordering specified.
|
||||
return $customOrdering;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::setDataElementSequence()
|
||||
*/
|
||||
public function setDataElementSequence($request, $sectionId, $gridDataElement, $newSequence)
|
||||
{
|
||||
$issue = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_ISSUE);
|
||||
Repo::section()->upsertCustomSectionOrder($issue->getId(), $sectionId, $newSequence);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc CategoryGridHandler::getDataElementInCategorySequence()
|
||||
*/
|
||||
public function getDataElementInCategorySequence($categoryId, &$submission)
|
||||
{
|
||||
return $submission->getCurrentPublication()->getData('seq');
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::setDataElementSequence()
|
||||
*/
|
||||
public function setDataElementInCategorySequence($sectionId, &$submission, $newSequence)
|
||||
{
|
||||
$publication = $submission->getCurrentPublication();
|
||||
$params = ['seq' => $newSequence];
|
||||
if ($sectionId != $publication->getData('sectionId')) {
|
||||
$params['sectionId'] = $sectionId;
|
||||
}
|
||||
Repo::publication()->edit($publication, $params);
|
||||
}
|
||||
|
||||
//
|
||||
// Public handler functions
|
||||
//
|
||||
/**
|
||||
* Remove an article from the issue.
|
||||
*
|
||||
* @param array $args
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function removeArticle($args, $request)
|
||||
{
|
||||
$journal = $request->getJournal();
|
||||
$submission = Repo::submission()->get((int) $request->getUserVar('articleId'));
|
||||
$issue = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_ISSUE);
|
||||
if ($submission && $request->checkCSRF()) {
|
||||
foreach ($submission->getData('publications') as $publication) {
|
||||
if ($publication->getData('issueId') === (int) $issue->getId()
|
||||
&& in_array($publication->getData('status'), [PKPSubmission::STATUS_SCHEDULED, PKPSubmission::STATUS_PUBLISHED])) {
|
||||
Repo::publication()->unpublish($publication);
|
||||
$publication = Repo::publication()->get($publication->getId());
|
||||
Repo::publication()->edit(
|
||||
$publication,
|
||||
['seq' => '']
|
||||
);
|
||||
}
|
||||
}
|
||||
// If the article is the only one in the section, delete the section from custom issue ordering
|
||||
$sectionId = $submission->getCurrentPublication()->getData('sectionId');
|
||||
$submissionsInSections = Repo::submission()->getInSections($issue->getId(), $issue->getJournalId());
|
||||
if (!empty($submissionsInSections[$sectionId]) && count($submissionsInSections[$sectionId]) === 1) {
|
||||
Repo::section()->deleteCustomSectionOrder($issue->getId(), $sectionId);
|
||||
}
|
||||
return DAO::getDataChangedEvent();
|
||||
}
|
||||
|
||||
// If we've fallen through, it must be a badly-specified article
|
||||
return new JSONMessage(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set access status on an article.
|
||||
*
|
||||
* @param array $args
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function setAccessStatus($args, $request)
|
||||
{
|
||||
$articleId = (int) $request->getUserVar('articleId');
|
||||
$issue = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_ISSUE);
|
||||
$submission = Repo::submission()->get($articleId);
|
||||
$publication = $submission ? $submission->getCurrentPublication() : null;
|
||||
if ($publication && $publication->getData('issueId') == $issue->getId() && $request->checkCSRF()) {
|
||||
Repo::publication()->edit($publication, ['accessStatus' => $request->getUserVar('status')]);
|
||||
return DAO::getDataChangedEvent();
|
||||
}
|
||||
|
||||
// If we've fallen through, it must be a badly-specified article
|
||||
return new JSONMessage(false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/toc/TocGridRow.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 TocGridRow
|
||||
*
|
||||
* @ingroup controllers_grid_settings_issue
|
||||
*
|
||||
* @brief Handle issue grid row requests.
|
||||
*/
|
||||
|
||||
namespace APP\controllers\grid\toc;
|
||||
|
||||
use PKP\controllers\grid\GridRow;
|
||||
use PKP\core\PKPApplication;
|
||||
use PKP\linkAction\LinkAction;
|
||||
use PKP\linkAction\request\RedirectAction;
|
||||
use PKP\linkAction\request\RemoteActionConfirmationModal;
|
||||
|
||||
class TocGridRow extends GridRow
|
||||
{
|
||||
/** @var int */
|
||||
public $issueId;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param int $issueId
|
||||
*/
|
||||
public function __construct($issueId)
|
||||
{
|
||||
parent::__construct();
|
||||
$this->issueId = $issueId;
|
||||
}
|
||||
|
||||
//
|
||||
// Overridden template methods
|
||||
//
|
||||
/**
|
||||
* @copydoc GridRow::initialize
|
||||
*
|
||||
* @param null|mixed $template
|
||||
*/
|
||||
public function initialize($request, $template = null)
|
||||
{
|
||||
parent::initialize($request, $template);
|
||||
|
||||
$dispatcher = $request->getDispatcher();
|
||||
$this->addAction(
|
||||
new LinkAction(
|
||||
'workflow',
|
||||
new RedirectAction(
|
||||
$dispatcher->url($request, PKPApplication::ROUTE_PAGE, null, 'workflow', 'access', [$this->getId()])
|
||||
),
|
||||
__('submission.submission'),
|
||||
'information'
|
||||
)
|
||||
);
|
||||
|
||||
$router = $request->getRouter();
|
||||
$this->addAction(
|
||||
new LinkAction(
|
||||
'removeArticle',
|
||||
new RemoteActionConfirmationModal(
|
||||
$request->getSession(),
|
||||
__('editor.article.remove.confirm'),
|
||||
__('grid.action.removeArticle'),
|
||||
$router->url($request, null, null, 'removeArticle', null, ['articleId' => $this->getId(), 'issueId' => $this->issueId]),
|
||||
'modal_delete'
|
||||
),
|
||||
__('editor.article.remove'),
|
||||
'delete'
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/users/reviewer/ReviewerGridHandler.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 ReviewerGridHandler
|
||||
*
|
||||
* @ingroup controllers_grid_users_reviewer
|
||||
*
|
||||
* @brief Handle reviewer grid requests.
|
||||
*/
|
||||
|
||||
namespace APP\controllers\grid\users\reviewer;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\facades\Repo;
|
||||
use PKP\controllers\grid\users\reviewer\PKPReviewerGridHandler;
|
||||
use PKP\core\Core;
|
||||
use PKP\core\PKPApplication;
|
||||
use PKP\security\Validation;
|
||||
|
||||
class ReviewerGridHandler extends PKPReviewerGridHandler
|
||||
{
|
||||
/**
|
||||
* @copydoc PKPReviewerGridHandler::reviewRead()
|
||||
*/
|
||||
public function reviewRead($args, $request)
|
||||
{
|
||||
// Retrieve review assignment.
|
||||
$reviewAssignment = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_REVIEW_ASSIGNMENT); /** @var \PKP\submission\reviewAssignment\ReviewAssignment $reviewAssignment */
|
||||
|
||||
// Recommendation
|
||||
$newRecommendation = $request->getUserVar('recommendation');
|
||||
// If editor set or changed the recommendation
|
||||
if ($newRecommendation && $reviewAssignment->getRecommendation() != $newRecommendation) {
|
||||
$reviewAssignment->setRecommendation($newRecommendation);
|
||||
|
||||
// Add log entry
|
||||
$submission = $this->getSubmission();
|
||||
$reviewer = Repo::user()->get($reviewAssignment->getReviewerId(), true);
|
||||
$user = $request->getUser();
|
||||
|
||||
class_exists(\APP\log\event\SubmissionEventLogEntry::class); // Force definition of SUBMISSION_LOG_REVIEW_RECOMMENDATION_BY_PROXY
|
||||
$eventLog = Repo::eventLog()->newDataObject([
|
||||
'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
|
||||
'assocId' => $submission->getId(),
|
||||
'eventType' => \SUBMISSION_LOG_REVIEW_RECOMMENDATION_BY_PROXY,
|
||||
'userId' => Validation::loggedInAs() ?? $user->getId(),
|
||||
'message' => 'log.review.reviewRecommendationSetByProxy',
|
||||
'isTranslated' => false,
|
||||
'dateLogged' => Core::getCurrentDate(),
|
||||
'round' => $reviewAssignment->getRound(),
|
||||
'submissionId' => $submission->getId(),
|
||||
'editorName' => $user->getFullName(),
|
||||
'reviewAssignmentId' => $reviewAssignment->getId(),
|
||||
'reviewerName' => $reviewer->getFullName(),
|
||||
]);
|
||||
Repo::eventLog()->add($eventLog);
|
||||
}
|
||||
return parent::reviewRead($args, $request);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,233 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/users/subscriberSelect/SubscriberSelectGridHandler.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 SubscriberSelectGridHandler
|
||||
*
|
||||
* @ingroup controllers_grid_users_subscriberSelect
|
||||
*
|
||||
* @brief Handle subscriber selector grid requests.
|
||||
*/
|
||||
|
||||
namespace APP\controllers\grid\users\subscriberSelect;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\facades\Repo;
|
||||
use PKP\controllers\grid\feature\CollapsibleGridFeature;
|
||||
use PKP\controllers\grid\feature\InfiniteScrollingFeature;
|
||||
use PKP\controllers\grid\GridColumn;
|
||||
use PKP\controllers\grid\GridHandler;
|
||||
use PKP\controllers\grid\users\userSelect\UserSelectGridCellProvider;
|
||||
use PKP\security\authorization\ContextAccessPolicy;
|
||||
use PKP\security\Role;
|
||||
|
||||
class SubscriberSelectGridHandler extends GridHandler
|
||||
{
|
||||
/** @var array (user group ID => user group name) */
|
||||
public $_userGroupOptions;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->addRoleAssignment(
|
||||
[Role::ROLE_ID_MANAGER, Role::ROLE_ID_SITE_ADMIN, Role::ROLE_ID_SUBSCRIPTION_MANAGER],
|
||||
['fetchGrid', 'fetchRows']
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// Implement template methods from PKPHandler
|
||||
//
|
||||
/**
|
||||
* @copydoc PKPHandler::authorize()
|
||||
*/
|
||||
public function authorize($request, &$args, $roleAssignments)
|
||||
{
|
||||
$this->addPolicy(new ContextAccessPolicy($request, $roleAssignments));
|
||||
return parent::authorize($request, $args, $roleAssignments);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::initialize()
|
||||
*
|
||||
* @param null|mixed $args
|
||||
*/
|
||||
public function initialize($request, $args = null)
|
||||
{
|
||||
parent::initialize($request, $args);
|
||||
|
||||
$stageId = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_WORKFLOW_STAGE);
|
||||
$userGroups = Repo::userGroup()->getUserGroupsByStage(
|
||||
$request->getContext()->getId(),
|
||||
$stageId
|
||||
);
|
||||
$this->_userGroupOptions = [];
|
||||
foreach ($userGroups as $userGroup) {
|
||||
$this->_userGroupOptions[$userGroup->getId()] = $userGroup->getLocalizedName();
|
||||
}
|
||||
|
||||
$this->setTitle('editor.submission.findAndSelectUser');
|
||||
|
||||
// Columns
|
||||
$cellProvider = new UserSelectGridCellProvider($request->getUserVar('userId'));
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'select',
|
||||
'',
|
||||
null,
|
||||
'controllers/grid/users/userSelect/userSelectRadioButton.tpl',
|
||||
$cellProvider,
|
||||
['width' => 5]
|
||||
)
|
||||
);
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'name',
|
||||
'common.name',
|
||||
null,
|
||||
null,
|
||||
$cellProvider,
|
||||
['alignment' => GridColumn::COLUMN_ALIGNMENT_LEFT,
|
||||
'width' => 30
|
||||
]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Overridden methods from GridHandler
|
||||
//
|
||||
/**
|
||||
* @copydoc GridHandler::initFeatures()
|
||||
*/
|
||||
public function initFeatures($request, $args)
|
||||
{
|
||||
return [new InfiniteScrollingFeature('infiniteScrolling', $this->getItemsNumber()), new CollapsibleGridFeature()];
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::loadData()
|
||||
*/
|
||||
protected function loadData($request, $filter)
|
||||
{
|
||||
// Get the context.
|
||||
$context = $request->getContext();
|
||||
|
||||
// Get all users for this context that match search criteria.
|
||||
$rangeInfo = $this->getGridRangeInfo($request, $this->getId());
|
||||
|
||||
// The user interface uses filter['userGroup'] and $filter['search']
|
||||
$userGroupSearchTerm = $filter['userGroup'] ? [$filter['userGroup']] : null;
|
||||
|
||||
$userCollector = Repo::user()->getCollector()
|
||||
->filterByContextIds([$context->getId()])
|
||||
->searchPhrase($filter['search'])
|
||||
->filterByUserGroupIds($userGroupSearchTerm)
|
||||
->limit($rangeInfo->getCount())
|
||||
->offset($rangeInfo->getOffset() + max(0, $rangeInfo->getPage() - 1) * $rangeInfo->getCount());
|
||||
|
||||
$users = $userCollector->getMany();
|
||||
|
||||
$totalCount = $userCollector->limit(null)->offset(null)->getCount();
|
||||
return new \PKP\core\VirtualArrayIterator(iterator_to_array($users, true), $totalCount, $rangeInfo->getPage(), $rangeInfo->getCount());
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::renderFilter()
|
||||
*/
|
||||
public function renderFilter($request, $filterData = [])
|
||||
{
|
||||
$context = $request->getContext();
|
||||
$userGroups = Repo::userGroup()->getCollector()
|
||||
->filterByContextIds([$context->getId()])
|
||||
->getMany();
|
||||
|
||||
$userGroupOptions = ['' => __('grid.user.allRoles')];
|
||||
foreach ($userGroups as $userGroup) {
|
||||
$userGroupOptions[$userGroup->getId()] = $userGroup->getLocalizedName();
|
||||
}
|
||||
|
||||
return parent::renderFilter(
|
||||
$request,
|
||||
[
|
||||
'userGroupOptions' => $userGroupOptions,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::getFilterSelectionData()
|
||||
*
|
||||
* @return array Filter selection data.
|
||||
*/
|
||||
public function getFilterSelectionData($request)
|
||||
{
|
||||
// If we're editing an existing subscription, use the filter form to ensure that
|
||||
// the already-selected user is chosen.
|
||||
if (($userId = (int) $request->getUserVar('userId')) && !$request->getUserVar('clientSubmit')) {
|
||||
return [
|
||||
'userGroup' => null,
|
||||
'searchField' => Repo::user()->dao::USER_FIELD_USERNAME,
|
||||
'searchMatch' => 'is',
|
||||
'search' => Repo::user()->get($userId)->getUsername(),
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
'userGroup' => $request->getUserVar('userGroup') ? (int) $request->getUserVar('userGroup') : null,
|
||||
'searchField' => $request->getUserVar('searchField'),
|
||||
'searchMatch' => $request->getUserVar('searchMatch'),
|
||||
'search' => (string) $request->getUserVar('search'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::getFilterForm()
|
||||
*
|
||||
* @return string Filter template.
|
||||
*/
|
||||
protected function getFilterForm()
|
||||
{
|
||||
return 'controllers/grid/users/exportableUsers/userGridFilter.tpl';
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether a filter form should be collapsible.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function isFilterFormCollapsible()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define how many items this grid will start loading.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
protected function getItemsNumber()
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::getRequestArgs()
|
||||
*/
|
||||
public function getRequestArgs()
|
||||
{
|
||||
$request = Application::get()->getRequest();
|
||||
return array_merge(parent::getRequestArgs(), [
|
||||
'userId' => $request->getUserVar('userId'),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/modals/publish/AssignToIssueHandler.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 AssignToIssueHandler
|
||||
*
|
||||
* @ingroup controllers_modals_publish
|
||||
*
|
||||
* @brief A handler to assign a publication to an issue before scheduling for
|
||||
* publication
|
||||
*/
|
||||
|
||||
namespace APP\controllers\modals\publish;
|
||||
|
||||
use APP\components\forms\publication\AssignToIssueForm;
|
||||
use APP\core\Application;
|
||||
use APP\core\Request;
|
||||
use APP\core\Services;
|
||||
use APP\handler\Handler;
|
||||
use APP\publication\Publication;
|
||||
use APP\submission\Submission;
|
||||
use APP\template\TemplateManager;
|
||||
use PKP\core\JSONMessage;
|
||||
use PKP\core\PKPApplication;
|
||||
use PKP\security\authorization\PublicationAccessPolicy;
|
||||
use PKP\security\authorization\SubmissionAccessPolicy;
|
||||
use PKP\security\Role;
|
||||
|
||||
class AssignToIssueHandler extends Handler
|
||||
{
|
||||
/** @var Submission */
|
||||
public $submission;
|
||||
|
||||
/** @var Publication */
|
||||
public $publication;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->addRoleAssignment(
|
||||
[Role::ROLE_ID_SUB_EDITOR, Role::ROLE_ID_MANAGER, Role::ROLE_ID_SITE_ADMIN, Role::ROLE_ID_ASSISTANT],
|
||||
['assign']
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Overridden methods from Handler
|
||||
//
|
||||
/**
|
||||
* @copydoc PKPHandler::initialize()
|
||||
*/
|
||||
public function initialize($request)
|
||||
{
|
||||
parent::initialize($request);
|
||||
$this->submission = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_SUBMISSION);
|
||||
$this->publication = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_PUBLICATION);
|
||||
$this->setupTemplate($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc PKPHandler::authorize()
|
||||
*/
|
||||
public function authorize($request, &$args, $roleAssignments)
|
||||
{
|
||||
$this->addPolicy(new SubmissionAccessPolicy($request, $args, $roleAssignments));
|
||||
$this->addPolicy(new PublicationAccessPolicy($request, $args, $roleAssignments));
|
||||
return parent::authorize($request, $args, $roleAssignments);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Public handler methods
|
||||
//
|
||||
/**
|
||||
* Display a form to assign an issue to a publication
|
||||
*
|
||||
* @param array $args
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function assign($args, $request)
|
||||
{
|
||||
$templateMgr = TemplateManager::getManager($request);
|
||||
|
||||
$submissionContext = $request->getContext();
|
||||
if (!$submissionContext || $submissionContext->getId() !== $this->submission->getData('contextId')) {
|
||||
$submissionContext = Services::get('context')->get($this->submission->getData('contextId'));
|
||||
}
|
||||
|
||||
$publicationApiUrl = $request->getDispatcher()->url($request, PKPApplication::ROUTE_API, $submissionContext->getPath(), 'submissions/' . $this->submission->getId() . '/publications/' . $this->publication->getId());
|
||||
$assignToIssueForm = new AssignToIssueForm($publicationApiUrl, $this->publication, $submissionContext);
|
||||
$settingsData = [
|
||||
'components' => [
|
||||
FORM_ASSIGN_TO_ISSUE => $assignToIssueForm->getConfig(),
|
||||
],
|
||||
];
|
||||
|
||||
$templateMgr->assign('assignData', $settingsData);
|
||||
|
||||
return $templateMgr->fetchJson('controllers/modals/publish/assignToIssue.tpl');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/tab/pubIds/form/PublicIdentifiersForm.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 PublicIdentifiersForm
|
||||
*
|
||||
* @ingroup controllers_tab_pubIds_form
|
||||
*
|
||||
* @brief Displays a pub ids form.
|
||||
*/
|
||||
|
||||
namespace APP\controllers\tab\pubIds\form;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\facades\Repo;
|
||||
use APP\issue\Issue;
|
||||
use APP\issue\IssueGalley;
|
||||
use APP\template\TemplateManager;
|
||||
use PKP\controllers\tab\pubIds\form\PKPPublicIdentifiersForm;
|
||||
use PKP\galley\Galley;
|
||||
use PKP\plugins\PluginRegistry;
|
||||
|
||||
class PublicIdentifiersForm extends PKPPublicIdentifiersForm
|
||||
{
|
||||
/**
|
||||
* @copydoc Form::fetch()
|
||||
*
|
||||
* @param null|mixed $template
|
||||
*/
|
||||
public function fetch($request, $template = null, $display = false)
|
||||
{
|
||||
$templateMgr = TemplateManager::getManager($request);
|
||||
$enablePublisherId = (array) $request->getContext()->getData('enablePublisherId');
|
||||
$templateMgr->assign([
|
||||
'enablePublisherId' => ($this->getPubObject() instanceof Galley && in_array('galley', $enablePublisherId)) ||
|
||||
($this->getPubObject() instanceof Issue && in_array('issue', $enablePublisherId)) ||
|
||||
($this->getPubObject() instanceof IssueGalley && in_array('issueGalley', $enablePublisherId)),
|
||||
]);
|
||||
|
||||
return parent::fetch($request, $template, $display);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::execute()
|
||||
*/
|
||||
public function execute(...$functionArgs)
|
||||
{
|
||||
parent::execute(...$functionArgs);
|
||||
$pubObject = $this->getPubObject();
|
||||
if ($pubObject instanceof Issue) {
|
||||
Repo::issue()->edit($pubObject, []);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear issue objects pub ids.
|
||||
*
|
||||
* @param string $pubIdPlugInClassName
|
||||
*/
|
||||
public function clearIssueObjectsPubIds($pubIdPlugInClassName)
|
||||
{
|
||||
$pubIdPlugins = PluginRegistry::loadCategory('pubIds', true);
|
||||
foreach ($pubIdPlugins as $pubIdPlugin) {
|
||||
$classNameParts = explode('\\', get_class($pubIdPlugin)); // Separate namespace info from class name
|
||||
if (end($classNameParts) == $pubIdPlugInClassName) {
|
||||
$pubIdPlugin->clearIssueObjectsPubIds($this->getPubObject());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc PKPPublicIdentifiersForm::getAssocType()
|
||||
*/
|
||||
public function getAssocType($pubObject)
|
||||
{
|
||||
if ($pubObject instanceof Issue) {
|
||||
return Application::ASSOC_TYPE_ISSUE;
|
||||
}
|
||||
return parent::getAssocType($pubObject);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/tab/workflow/ReviewRoundTabHandler.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 ReviewRoundTabHandler
|
||||
*
|
||||
* @ingroup controllers_tab_workflow
|
||||
*
|
||||
* @brief Handle AJAX operations for review round tabs on review stages workflow pages.
|
||||
*/
|
||||
|
||||
namespace APP\controllers\tab\workflow;
|
||||
|
||||
use PKP\controllers\tab\workflow\PKPReviewRoundTabHandler;
|
||||
use PKP\security\authorization\WorkflowStageAccessPolicy;
|
||||
use PKP\security\Role;
|
||||
|
||||
class ReviewRoundTabHandler extends PKPReviewRoundTabHandler
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->addRoleAssignment(
|
||||
[Role::ROLE_ID_SUB_EDITOR, Role::ROLE_ID_MANAGER, Role::ROLE_ID_SITE_ADMIN, Role::ROLE_ID_ASSISTANT],
|
||||
['externalReviewRound']
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Extended methods from Handler
|
||||
//
|
||||
/**
|
||||
* @copydoc PKPHandler::authorize()
|
||||
*/
|
||||
public function authorize($request, &$args, $roleAssignments)
|
||||
{
|
||||
$stageId = (int) $request->getUserVar('stageId'); // This is validated in WorkflowStageAccessPolicy.
|
||||
|
||||
$this->addPolicy(new WorkflowStageAccessPolicy($request, $args, $roleAssignments, 'submissionId', $stageId));
|
||||
|
||||
return parent::authorize($request, $args, $roleAssignments);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/tab/workflow/WorkflowTabHandler.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 WorkflowTabHandler
|
||||
*
|
||||
* @ingroup controllers_tab_workflow
|
||||
*
|
||||
* @brief Handle AJAX operations for workflow tabs.
|
||||
*/
|
||||
|
||||
namespace APP\controllers\tab\workflow;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\notification\Notification;
|
||||
use APP\template\TemplateManager;
|
||||
use PKP\controllers\tab\workflow\PKPWorkflowTabHandler;
|
||||
use PKP\core\PKPApplication;
|
||||
use PKP\decision\DecisionType;
|
||||
use PKP\decision\types\NewExternalReviewRound;
|
||||
use PKP\linkAction\LinkAction;
|
||||
use PKP\linkAction\request\AjaxModal;
|
||||
use PKP\notification\PKPNotification;
|
||||
|
||||
class WorkflowTabHandler extends PKPWorkflowTabHandler
|
||||
{
|
||||
/**
|
||||
* @copydoc PKPWorkflowTabHandler::fetchTab
|
||||
*/
|
||||
public function fetchTab($args, $request)
|
||||
{
|
||||
$this->setupTemplate($request);
|
||||
$templateMgr = TemplateManager::getManager($request);
|
||||
$stageId = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_WORKFLOW_STAGE);
|
||||
$submission = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_SUBMISSION);
|
||||
switch ($stageId) {
|
||||
case WORKFLOW_STAGE_ID_PRODUCTION:
|
||||
$dispatcher = $request->getDispatcher();
|
||||
$schedulePublicationLinkAction = new LinkAction(
|
||||
'schedulePublication',
|
||||
new AjaxModal(
|
||||
$dispatcher->url(
|
||||
$request,
|
||||
PKPApplication::ROUTE_COMPONENT,
|
||||
null,
|
||||
'tab.issueEntry.IssueEntryTabHandler',
|
||||
'publicationMetadata',
|
||||
null,
|
||||
['submissionId' => $submission->getId(), 'stageId' => $stageId]
|
||||
),
|
||||
__('submission.publication')
|
||||
),
|
||||
__('editor.submission.schedulePublication')
|
||||
);
|
||||
$templateMgr->assign('schedulePublicationLinkAction', $schedulePublicationLinkAction);
|
||||
break;
|
||||
}
|
||||
return parent::fetchTab($args, $request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all production notification options to be used in the production stage tab.
|
||||
*
|
||||
* @param int $submissionId
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getProductionNotificationOptions($submissionId)
|
||||
{
|
||||
return [
|
||||
Notification::NOTIFICATION_LEVEL_NORMAL => [
|
||||
PKPNotification::NOTIFICATION_TYPE_VISIT_CATALOG => [Application::ASSOC_TYPE_SUBMISSION, $submissionId],
|
||||
PKPNotification::NOTIFICATION_TYPE_ASSIGN_PRODUCTIONUSER => [Application::ASSOC_TYPE_SUBMISSION, $submissionId],
|
||||
PKPNotification::NOTIFICATION_TYPE_AWAITING_REPRESENTATIONS => [Application::ASSOC_TYPE_SUBMISSION, $submissionId],
|
||||
],
|
||||
Notification::NOTIFICATION_LEVEL_TRIVIAL => []
|
||||
];
|
||||
}
|
||||
|
||||
protected function getNewReviewRoundDecisionType(int $stageId): DecisionType
|
||||
{
|
||||
// OJS only supports the external review stage
|
||||
return new NewExternalReviewRound();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user