first commit
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/settings/SetupGridHandler.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 SetupGridHandler
|
||||
*
|
||||
* @ingroup controllers_grid_settings
|
||||
*
|
||||
* @brief Base class for setup grid handlers
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\settings;
|
||||
|
||||
use PKP\controllers\grid\GridHandler;
|
||||
use PKP\core\JSONMessage;
|
||||
use PKP\core\PKPRequest;
|
||||
use PKP\file\TemporaryFileManager;
|
||||
use PKP\security\authorization\ContextAccessPolicy;
|
||||
use PKP\security\Role;
|
||||
|
||||
class SetupGridHandler extends GridHandler
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->addRoleAssignment(
|
||||
[Role::ROLE_ID_MANAGER, Role::ROLE_ID_SITE_ADMIN],
|
||||
['uploadImage']
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc PKPHandler::authorize()
|
||||
*
|
||||
* @param bool $contextRequired
|
||||
*/
|
||||
public function authorize($request, &$args, $roleAssignments, $contextRequired = true)
|
||||
{
|
||||
if ($contextRequired) {
|
||||
$this->addPolicy(new ContextAccessPolicy($request, $roleAssignments));
|
||||
}
|
||||
return parent::authorize($request, $args, $roleAssignments);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle file uploads for cover/image art for things like Series and Categories.
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*/
|
||||
public function uploadImage($args, $request)
|
||||
{
|
||||
$router = $request->getRouter();
|
||||
$context = $request->getContext();
|
||||
$user = $request->getUser();
|
||||
|
||||
$temporaryFileManager = new TemporaryFileManager();
|
||||
$temporaryFile = $temporaryFileManager->handleUpload('uploadedFile', $user->getId());
|
||||
if ($temporaryFile) {
|
||||
$json = new JSONMessage(true);
|
||||
$json->setAdditionalAttributes([
|
||||
'temporaryFileId' => $temporaryFile->getId()
|
||||
]);
|
||||
return $json;
|
||||
} else {
|
||||
return new JSONMessage(false, __('common.uploadFailed'));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,344 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/settings/category/CategoryCategoryGridHandler.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 CategoryCategoryGridHandler
|
||||
*
|
||||
* @ingroup controllers_grid_settings_category
|
||||
*
|
||||
* @brief Handle operations for category management operations.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\settings\category;
|
||||
|
||||
use APP\core\Request;
|
||||
use APP\facades\Repo;
|
||||
use PKP\controllers\grid\CategoryGridHandler;
|
||||
use PKP\controllers\grid\DataObjectGridCellProvider;
|
||||
use PKP\controllers\grid\feature\OrderCategoryGridItemsFeature;
|
||||
use PKP\controllers\grid\GridColumn;
|
||||
use PKP\controllers\grid\settings\category\form\CategoryForm;
|
||||
use PKP\core\JSONMessage;
|
||||
use PKP\core\PKPRequest;
|
||||
use PKP\facades\Locale;
|
||||
use PKP\file\TemporaryFileManager;
|
||||
use PKP\linkAction\LinkAction;
|
||||
use PKP\linkAction\request\AjaxModal;
|
||||
use PKP\security\authorization\ContextAccessPolicy;
|
||||
use PKP\security\Role;
|
||||
|
||||
class CategoryCategoryGridHandler extends CategoryGridHandler
|
||||
{
|
||||
public $_contextId;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->addRoleAssignment(
|
||||
[Role::ROLE_ID_MANAGER, Role::ROLE_ID_SITE_ADMIN],
|
||||
[
|
||||
'fetchGrid',
|
||||
'fetchCategory',
|
||||
'fetchRow',
|
||||
'addCategory',
|
||||
'editCategory',
|
||||
'updateCategory',
|
||||
'deleteCategory',
|
||||
'uploadImage',
|
||||
'saveSequence',
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// Overridden 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 CategoryGridHandler::initialize()
|
||||
*
|
||||
* @param null|mixed $args
|
||||
*/
|
||||
public function initialize($request, $args = null)
|
||||
{
|
||||
parent::initialize($request, $args);
|
||||
|
||||
$context = $request->getContext();
|
||||
$this->_contextId = $context->getId();
|
||||
|
||||
// Set the grid title.
|
||||
$this->setTitle('grid.category.categories');
|
||||
|
||||
// Add grid-level actions.
|
||||
$router = $request->getRouter();
|
||||
$this->addAction(
|
||||
new LinkAction(
|
||||
'addCategory',
|
||||
new AjaxModal(
|
||||
$router->url($request, null, null, 'addCategory'),
|
||||
__('grid.category.add'),
|
||||
'modal_manage'
|
||||
),
|
||||
__('grid.category.add'),
|
||||
'add_category'
|
||||
)
|
||||
);
|
||||
|
||||
// Add grid columns.
|
||||
$cellProvider = new DataObjectGridCellProvider();
|
||||
$cellProvider->setLocale(Locale::getLocale());
|
||||
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'title',
|
||||
'grid.category.name',
|
||||
null,
|
||||
null,
|
||||
$cellProvider
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::loadData
|
||||
*/
|
||||
public function loadData($request, $filter)
|
||||
{
|
||||
// For top-level rows, only list categories without parents.
|
||||
return Repo::category()->getCollector()
|
||||
->filterByContextIds([$this->_getContextId()])
|
||||
->filterByParentIds([null])
|
||||
->getMany()
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::initFeatures()
|
||||
*/
|
||||
public function initFeatures($request, $args)
|
||||
{
|
||||
return array_merge(
|
||||
parent::initFeatures($request, $args),
|
||||
[new OrderCategoryGridItemsFeature(OrderCategoryGridItemsFeature::ORDER_CATEGORY_GRID_CATEGORIES_AND_ROWS, true, $this)]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc CategoryGridHandler::getDataElementInCategorySequence()
|
||||
*/
|
||||
public function getDataElementInCategorySequence($categoryId, &$category)
|
||||
{
|
||||
return $category->getSequence();
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc CategoryGridHandler::setDataElementInCategorySequence()
|
||||
*/
|
||||
public function setDataElementInCategorySequence($parentCategoryId, &$category, $newSequence)
|
||||
{
|
||||
$category->setSequence($newSequence);
|
||||
Repo::category()->edit($category, []);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::getDataElementSequence()
|
||||
*/
|
||||
public function getDataElementSequence($gridDataElement)
|
||||
{
|
||||
return $gridDataElement->getSequence();
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::setDataElementSequence()
|
||||
*/
|
||||
public function setDataElementSequence($request, $categoryId, $category, $newSequence)
|
||||
{
|
||||
$category->setSequence($newSequence);
|
||||
Repo::category()->edit($category, []);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc CategoryGridHandler::getCategoryRowIdParameterName()
|
||||
*/
|
||||
public function getCategoryRowIdParameterName()
|
||||
{
|
||||
return 'parentCategoryId';
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::getRowInstance()
|
||||
*/
|
||||
public function getRowInstance()
|
||||
{
|
||||
return new \PKP\controllers\grid\settings\category\CategoryGridRow();
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc CategoryGridHandler::getCategoryRowInstance()
|
||||
*/
|
||||
public function getCategoryRowInstance()
|
||||
{
|
||||
return new \PKP\controllers\grid\settings\category\CategoryGridCategoryRow();
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc CategoryGridHandler::loadCategoryData()
|
||||
*
|
||||
* @param null|mixed $filter
|
||||
*/
|
||||
public function loadCategoryData($request, &$category, $filter = null)
|
||||
{
|
||||
$categoryId = $category->getId();
|
||||
return Repo::category()->getCollector()
|
||||
->filterByContextIds([$this->_getContextId()])
|
||||
->filterByParentIds([$categoryId])
|
||||
->getMany()
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the add category operation.
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*/
|
||||
public function addCategory($args, $request)
|
||||
{
|
||||
return $this->editCategory($args, $request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the edit category operation.
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function editCategory($args, $request)
|
||||
{
|
||||
$categoryForm = $this->_getCategoryForm($request);
|
||||
|
||||
$categoryForm->initData();
|
||||
|
||||
return new JSONMessage(true, $categoryForm->fetch($request));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update category data in database and grid.
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function updateCategory($args, $request)
|
||||
{
|
||||
$categoryForm = $this->_getCategoryForm($request);
|
||||
|
||||
$categoryForm->readInputData();
|
||||
if ($categoryForm->validate()) {
|
||||
$categoryForm->execute();
|
||||
return \PKP\db\DAO::getDataChangedEvent();
|
||||
} else {
|
||||
return new JSONMessage(true, $categoryForm->fetch($request));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a category
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function deleteCategory($args, $request)
|
||||
{
|
||||
if (!$request->checkCSRF()) {
|
||||
return new JSONMessage(false);
|
||||
}
|
||||
|
||||
$context = $request->getContext();
|
||||
$category = Repo::category()->get((int) $request->getUserVar('categoryId'));
|
||||
if ($category && $category->getContextId() == $context->getId()) {
|
||||
Repo::category()->delete($category);
|
||||
}
|
||||
|
||||
// FIXME delete dependent objects?
|
||||
|
||||
return \PKP\db\DAO::getDataChangedEvent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle file uploads for cover/image art for things like Series and Categories.
|
||||
*
|
||||
* @param PKPRequest $request
|
||||
* @param array $args
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function uploadImage($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'));
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Private helper methods.
|
||||
//
|
||||
/**
|
||||
* Get a CategoryForm instance.
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return CategoryForm
|
||||
*/
|
||||
public function _getCategoryForm($request)
|
||||
{
|
||||
// Get the category ID.
|
||||
$categoryId = (int) $request->getUserVar('categoryId');
|
||||
|
||||
// Instantiate the files form.
|
||||
$contextId = $this->_getContextId();
|
||||
return new CategoryForm($contextId, $categoryId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get context id.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function _getContextId()
|
||||
{
|
||||
return $this->_contextId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/settings/category/CategoryGridCategoryRow.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 CategoryGridCategoryRow
|
||||
*
|
||||
* @ingroup controllers_grid_settings_category
|
||||
*
|
||||
* @brief Category grid category row definition
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\settings\category;
|
||||
|
||||
use APP\facades\Repo;
|
||||
use PKP\controllers\grid\GridCategoryRow;
|
||||
use PKP\controllers\grid\GridRow;
|
||||
use PKP\linkAction\LinkAction;
|
||||
use PKP\linkAction\request\AjaxModal;
|
||||
use PKP\linkAction\request\RemoteActionConfirmationModal;
|
||||
|
||||
class CategoryGridCategoryRow extends GridCategoryRow
|
||||
{
|
||||
//
|
||||
// Overridden methods from GridCategoryRow
|
||||
//
|
||||
/**
|
||||
* @copydoc GridCategoryRow::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?
|
||||
$categoryId = $this->getId();
|
||||
if (!empty($categoryId) && is_numeric($categoryId)) {
|
||||
// Only add row actions if this is an existing row
|
||||
$category = $this->getData();
|
||||
$router = $request->getRouter();
|
||||
|
||||
$childCategoryCount = Repo::category()->getCollector()
|
||||
->filterByParentIds([$categoryId])
|
||||
->getCount();
|
||||
|
||||
if ($childCategoryCount == 0) {
|
||||
$this->addAction(
|
||||
new LinkAction(
|
||||
'deleteCategory',
|
||||
new RemoteActionConfirmationModal(
|
||||
$request->getSession(),
|
||||
__('common.confirmDelete'),
|
||||
__('common.delete'),
|
||||
$router->url($request, null, null, 'deleteCategory', null, ['categoryId' => $categoryId]),
|
||||
'modal_delete'
|
||||
),
|
||||
__('grid.action.remove'),
|
||||
'delete'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$this->addAction(new LinkAction(
|
||||
'editCategory',
|
||||
new AjaxModal(
|
||||
$router->url($request, null, null, 'editCategory', null, ['categoryId' => $categoryId]),
|
||||
__('grid.category.edit'),
|
||||
'modal_edit'
|
||||
),
|
||||
$category->getLocalizedTitle()
|
||||
), GridRow::GRID_ACTION_POSITION_ROW_CLICK);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Category rows only have one cell and one label. This is it.
|
||||
* return string
|
||||
*/
|
||||
public function getCategoryLabel()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/settings/category/CategoryGridRow.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 CategoryGridRow
|
||||
*
|
||||
* @ingroup controllers_grid_settings_category
|
||||
*
|
||||
* @brief Category grid row definition
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\settings\category;
|
||||
|
||||
use PKP\controllers\grid\GridRow;
|
||||
use PKP\linkAction\LinkAction;
|
||||
use PKP\linkAction\request\AjaxModal;
|
||||
use PKP\linkAction\request\RemoteActionConfirmationModal;
|
||||
|
||||
class CategoryGridRow extends GridRow
|
||||
{
|
||||
//
|
||||
// Overridden methods from GridRow
|
||||
//
|
||||
/**
|
||||
* @copydoc GridRow::initialize()
|
||||
*
|
||||
* @param null|mixed $template
|
||||
*/
|
||||
public function initialize($request, $template = null)
|
||||
{
|
||||
parent::initialize($request, $template);
|
||||
|
||||
$rowData = $this->getData(); // a Category object
|
||||
assert($rowData != null);
|
||||
|
||||
$rowId = $this->getId();
|
||||
|
||||
// Only add row actions if this is an existing row.
|
||||
if (!empty($rowId) && is_numeric($rowId)) {
|
||||
$actionArgs = array_merge(
|
||||
$this->getRequestArgs(),
|
||||
['categoryId' => $rowData->getId()]
|
||||
);
|
||||
$router = $request->getRouter();
|
||||
|
||||
$this->addAction(new LinkAction(
|
||||
'editCategory',
|
||||
new AjaxModal(
|
||||
$router->url($request, null, null, 'editCategory', null, $actionArgs),
|
||||
__('grid.category.edit')
|
||||
),
|
||||
__('grid.action.edit'),
|
||||
'edit'
|
||||
));
|
||||
|
||||
$this->addAction(new LinkAction(
|
||||
'removeCategory',
|
||||
new RemoteActionConfirmationModal(
|
||||
$request->getSession(),
|
||||
__('grid.category.removeText'),
|
||||
null,
|
||||
$router->url($request, null, null, 'deleteCategory', null, $actionArgs)
|
||||
),
|
||||
__('grid.action.remove'),
|
||||
'delete'
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,427 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file lib/pkp/controllers/grid/settings/category/form/CategoryForm.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 CategoryForm
|
||||
*
|
||||
* @ingroup controllers_grid_settings_category_form
|
||||
*
|
||||
* @brief Form to add/edit category.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\settings\category\form;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\facades\Repo;
|
||||
use APP\template\TemplateManager;
|
||||
use PKP\context\SubEditorsDAO;
|
||||
use PKP\core\Core;
|
||||
use PKP\db\DAORegistry;
|
||||
use PKP\file\ContextFileManager;
|
||||
use PKP\file\TemporaryFileDAO;
|
||||
use PKP\file\TemporaryFileManager;
|
||||
use PKP\form\Form;
|
||||
use PKP\security\Role;
|
||||
use PKP\userGroup\UserGroup;
|
||||
|
||||
class CategoryForm extends Form
|
||||
{
|
||||
/** @var int Id of the category being edited */
|
||||
public $_categoryId;
|
||||
|
||||
/** @var int The context ID of the category being edited */
|
||||
public $_contextId;
|
||||
|
||||
/** @var int $_userId The current user ID */
|
||||
public $_userId;
|
||||
|
||||
/** @var string $_imageExtension Cover image extension */
|
||||
public $_imageExtension;
|
||||
|
||||
/** @var array $_sizeArray Cover image information from getimagesize */
|
||||
public $_sizeArray;
|
||||
|
||||
/** @var array Roles that can be assigned to this category */
|
||||
public $assignableRoles = [Role::ROLE_ID_MANAGER, Role::ROLE_ID_SUB_EDITOR, Role::ROLE_ID_ASSISTANT];
|
||||
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param int $contextId Context id.
|
||||
* @param int $categoryId Category id.
|
||||
*/
|
||||
public function __construct($contextId, $categoryId = null)
|
||||
{
|
||||
parent::__construct('controllers/grid/settings/category/form/categoryForm.tpl');
|
||||
$this->_contextId = $contextId;
|
||||
$this->_categoryId = $categoryId;
|
||||
|
||||
$request = Application::get()->getRequest();
|
||||
$user = $request->getUser();
|
||||
$this->_userId = $user->getId();
|
||||
|
||||
// Validation checks for this form
|
||||
$form = $this;
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorLocale($this, 'name', 'required', 'grid.category.nameRequired'));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorRegExp($this, 'path', 'required', 'grid.category.pathAlphaNumeric', '/^[a-zA-Z0-9\/._-]+$/'));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorCustom(
|
||||
$this,
|
||||
'path',
|
||||
'required',
|
||||
'grid.category.pathExists',
|
||||
function ($path) use ($form, $contextId) {
|
||||
$category = Repo::category()->getCollector()
|
||||
->filterByContextIds([$contextId])
|
||||
->filterByPaths([$path])
|
||||
->getMany()
|
||||
->first();
|
||||
|
||||
return !$category || $category->getPath() == $form->getData('oldPath');
|
||||
}
|
||||
));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorPost($this));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorCSRF($this));
|
||||
}
|
||||
|
||||
//
|
||||
// Getters and Setters
|
||||
//
|
||||
/**
|
||||
* Get the category id.
|
||||
*
|
||||
* @return int categoryId
|
||||
*/
|
||||
public function getCategoryId()
|
||||
{
|
||||
return $this->_categoryId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the category ID for this section.
|
||||
*
|
||||
* @param int $categoryId
|
||||
*/
|
||||
public function setCategoryId($categoryId)
|
||||
{
|
||||
$this->_categoryId = $categoryId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the context id.
|
||||
*
|
||||
* @return int contextId
|
||||
*/
|
||||
public function getContextId()
|
||||
{
|
||||
return $this->_contextId;
|
||||
}
|
||||
|
||||
//
|
||||
// Implement template methods from Form.
|
||||
//
|
||||
/**
|
||||
* Get all locale field names
|
||||
*/
|
||||
public function getLocaleFieldNames()
|
||||
{
|
||||
return ['name', 'description'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Form::initData()
|
||||
*/
|
||||
public function initData()
|
||||
{
|
||||
$category = Repo::category()->get($this->getCategoryId());
|
||||
|
||||
$this->setData('assignedSubeditors', []);
|
||||
|
||||
if ($category) {
|
||||
if ($category->getContextId() != $this->getContextId()) {
|
||||
throw new \Exception('Wrong context ID for category!');
|
||||
}
|
||||
|
||||
$this->setData('name', $category->getTitle(null)); // Localized
|
||||
$this->setData('description', $category->getDescription(null)); // Localized
|
||||
$this->setData('parentId', $category->getParentId());
|
||||
$this->setData('path', $category->getPath());
|
||||
$this->setData('image', $category->getImage());
|
||||
|
||||
$sortOption = $category->getSortOption() ? $category->getSortOption() : Repo::submission()->getDefaultSortOption();
|
||||
$this->setData('sortOption', $sortOption);
|
||||
|
||||
$subeditorUserGroups = [];
|
||||
$assignedSubeditors = Repo::user()
|
||||
->getCollector()
|
||||
->filterByContextIds([Application::get()->getRequest()->getContext()->getId()])
|
||||
->filterByRoleIds($this->assignableRoles)
|
||||
->assignedToCategoryIds([$this->getCategoryId()])
|
||||
->getIds()
|
||||
->toArray();
|
||||
|
||||
if (!empty($assignedSubeditors)) {
|
||||
$subEditorsDao = DAORegistry::getDAO('SubEditorsDAO'); /** @var SubEditorsDAO $subEditorsDao */
|
||||
$subeditorUserGroups = $subEditorsDao->getAssignedUserGroupIds(
|
||||
Application::get()->getRequest()->getContext()->getId(),
|
||||
Application::ASSOC_TYPE_CATEGORY,
|
||||
$this->getCategoryId(),
|
||||
$assignedSubeditors
|
||||
)->toArray();
|
||||
}
|
||||
|
||||
$this->setData('subeditorUserGroups', $subeditorUserGroups);
|
||||
}
|
||||
|
||||
return parent::initData();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Form::validate()
|
||||
*/
|
||||
public function validate($callHooks = true)
|
||||
{
|
||||
if ($temporaryFileId = $this->getData('temporaryFileId')) {
|
||||
$temporaryFileManager = new TemporaryFileManager();
|
||||
$temporaryFileDao = DAORegistry::getDAO('TemporaryFileDAO'); /** @var TemporaryFileDAO $temporaryFileDao */
|
||||
$temporaryFile = $temporaryFileDao->getTemporaryFile($temporaryFileId, $this->_userId);
|
||||
if (!$temporaryFile ||
|
||||
!($this->_imageExtension = $temporaryFileManager->getImageExtension($temporaryFile->getFileType())) ||
|
||||
!($this->_sizeArray = getimagesize($temporaryFile->getFilePath())) ||
|
||||
$this->_sizeArray[0] <= 0 || $this->_sizeArray[1] <= 0
|
||||
) {
|
||||
$this->addError('temporaryFileId', __('form.invalidImage'));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return parent::validate($callHooks);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Form::readInputData()
|
||||
*/
|
||||
public function readInputData()
|
||||
{
|
||||
$this->readUserVars(['name', 'parentId', 'path', 'description', 'temporaryFileId', 'sortOption', 'subEditors']);
|
||||
|
||||
// For path duplicate checking; excuse the current path.
|
||||
if ($categoryId = $this->getCategoryId()) {
|
||||
$category = Repo::category()->get($categoryId);
|
||||
if ($category->getContextId() != $this->getContextId()) {
|
||||
throw new \Exception('Wrong context ID for category!');
|
||||
}
|
||||
$this->setData('oldPath', $category->getPath());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::fetch()
|
||||
*
|
||||
* @param null|mixed $template
|
||||
*/
|
||||
public function fetch($request, $template = null, $display = false)
|
||||
{
|
||||
$context = $request->getContext();
|
||||
$templateMgr = TemplateManager::getManager($request);
|
||||
$templateMgr->assign('categoryId', $this->getCategoryId());
|
||||
|
||||
// Provide a list of root categories to the template
|
||||
$rootCategoriesCollection = Repo::category()->getCollector()
|
||||
->filterByParentIds([null])
|
||||
->filterByContextIds([$context->getId()])
|
||||
->getMany();
|
||||
|
||||
$rootCategories = [null => __('common.none')];
|
||||
foreach ($rootCategoriesCollection as $category) {
|
||||
$categoryId = $category->getId();
|
||||
if ($categoryId != $this->getCategoryId()) {
|
||||
// Don't permit time travel paradox
|
||||
$rootCategories[$categoryId] = $category->getLocalizedTitle();
|
||||
}
|
||||
}
|
||||
$templateMgr->assign('rootCategories', $rootCategories);
|
||||
|
||||
// Determine if this category has children of its own;
|
||||
// if so, prevent the user from giving it a parent.
|
||||
// (Forced two-level maximum tree depth.)
|
||||
if ($this->getCategoryId()) {
|
||||
$childCount = Repo::category()->getCollector()
|
||||
->filterByParentIds([$this->getCategoryId()])
|
||||
->filterByContextIds([$context->getId()])
|
||||
->getCount();
|
||||
|
||||
$templateMgr->assign('cannotSelectChild', $childCount > 0);
|
||||
}
|
||||
// Sort options.
|
||||
$templateMgr->assign('sortOptions', Repo::submission()->getSortSelectOptions());
|
||||
|
||||
$assignableUserGroups = Repo::userGroup()
|
||||
->getCollector()
|
||||
->filterByContextIds([$request->getContext()->getId()])
|
||||
->filterByRoleIds($this->assignableRoles)
|
||||
->filterByStageIds([WORKFLOW_STAGE_ID_SUBMISSION])
|
||||
->getMany()
|
||||
->map(function (UserGroup $userGroup) use ($request) {
|
||||
return [
|
||||
'userGroup' => $userGroup,
|
||||
'users' => Repo::user()
|
||||
->getCollector()
|
||||
->filterByUserGroupIds([$userGroup->getId()])
|
||||
->filterByContextIds([$request->getContext()->getId()])
|
||||
->getMany()
|
||||
->mapWithKeys(fn ($user, $key) => [$user->getId() => $user->getFullName()])
|
||||
->toArray()
|
||||
];
|
||||
});
|
||||
|
||||
$templateMgr = TemplateManager::getManager($request);
|
||||
$templateMgr->assign([
|
||||
'assignableUserGroups' => $assignableUserGroups->toArray(),
|
||||
]);
|
||||
|
||||
return parent::fetch($request, $template, $display);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::execute()
|
||||
*/
|
||||
public function execute(...$functionArgs)
|
||||
{
|
||||
$categoryId = $this->getCategoryId();
|
||||
$context = Application::get()->getRequest()->getContext();
|
||||
|
||||
// Get a category object to edit or create
|
||||
if ($categoryId == null) {
|
||||
$category = Repo::category()->dao->newDataObject();
|
||||
$category->setContextId($this->getContextId());
|
||||
} else {
|
||||
$category = Repo::category()->get($categoryId);
|
||||
if ($category->getContextId() != $this->getContextId()) {
|
||||
throw new \Exception('Wrong context ID for category!');
|
||||
}
|
||||
}
|
||||
|
||||
// Set the editable properties of the category object
|
||||
$category->setTitle($this->getData('name'), null); // Localized
|
||||
$category->setDescription($this->getData('description'), null); // Localized
|
||||
$category->setParentId(((int) $this->getData('parentId')) ?: null);
|
||||
$category->setPath($this->getData('path'));
|
||||
$category->setSortOption($this->getData('sortOption'));
|
||||
|
||||
// Update or insert the category object
|
||||
if ($categoryId == null) {
|
||||
$this->setCategoryId(Repo::category()->add($category));
|
||||
$category->setSequence(REALLY_BIG_NUMBER);
|
||||
Repo::category()->dao->resequenceCategories($this->getContextId());
|
||||
} else {
|
||||
Repo::category()->edit($category, []);
|
||||
}
|
||||
|
||||
// Update category editors
|
||||
$subEditorsDao = DAORegistry::getDAO('SubEditorsDAO'); /** @var SubEditorsDAO $subEditorsDao */
|
||||
$subEditorsDao->deleteBySubmissionGroupId($category->getId(), Application::ASSOC_TYPE_CATEGORY, $category->getContextId());
|
||||
$subEditors = $this->getData('subEditors');
|
||||
if (!empty($subEditors)) {
|
||||
$allowedEditors = Repo::user()
|
||||
->getCollector()
|
||||
->filterByRoleIds($this->assignableRoles)
|
||||
->filterByContextIds([$context->getId()])
|
||||
->getIds();
|
||||
foreach ($subEditors as $userGroupId => $userIds) {
|
||||
foreach ($userIds as $userId) {
|
||||
if (!$allowedEditors->contains($userId)) {
|
||||
continue;
|
||||
}
|
||||
$subEditorsDao->insertEditor($context->getId(), $this->getCategoryId(), $userId, Application::ASSOC_TYPE_CATEGORY, (int) $userGroupId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Handle the image upload if there was one.
|
||||
if ($temporaryFileId = $this->getData('temporaryFileId')) {
|
||||
// Fetch the temporary file storing the uploaded library file
|
||||
$temporaryFileDao = DAORegistry::getDAO('TemporaryFileDAO'); /** @var TemporaryFileDAO $temporaryFileDao */
|
||||
|
||||
$temporaryFile = $temporaryFileDao->getTemporaryFile($temporaryFileId, $this->_userId);
|
||||
$temporaryFilePath = $temporaryFile->getFilePath();
|
||||
$contextFileManager = new ContextFileManager($this->getContextId());
|
||||
$basePath = $contextFileManager->getBasePath() . '/categories/';
|
||||
|
||||
// Delete the old file if it exists
|
||||
$oldSetting = $category->getImage();
|
||||
if ($oldSetting) {
|
||||
$contextFileManager->deleteByPath($basePath . $oldSetting['thumbnailName']);
|
||||
$contextFileManager->deleteByPath($basePath . $oldSetting['name']);
|
||||
}
|
||||
|
||||
// The following variables were fetched in validation
|
||||
assert($this->_sizeArray && $this->_imageExtension);
|
||||
|
||||
// Generate the surrogate images.
|
||||
switch ($this->_imageExtension) {
|
||||
case '.jpg': $image = imagecreatefromjpeg($temporaryFilePath);
|
||||
break;
|
||||
case '.png': $image = imagecreatefrompng($temporaryFilePath);
|
||||
break;
|
||||
case '.gif': $image = imagecreatefromgif($temporaryFilePath);
|
||||
break;
|
||||
default: $image = null; // Suppress warning
|
||||
}
|
||||
assert($image);
|
||||
|
||||
$context = Application::get()->getRequest()->getContext();
|
||||
$coverThumbnailsMaxWidth = $context->getSetting('coverThumbnailsMaxWidth');
|
||||
$coverThumbnailsMaxHeight = $context->getSetting('coverThumbnailsMaxHeight');
|
||||
$thumbnailFilename = $category->getId() . '-category-thumbnail' . $this->_imageExtension;
|
||||
$xRatio = min(1, ($coverThumbnailsMaxWidth ? $coverThumbnailsMaxWidth : 100) / $this->_sizeArray[0]);
|
||||
$yRatio = min(1, ($coverThumbnailsMaxHeight ? $coverThumbnailsMaxHeight : 100) / $this->_sizeArray[1]);
|
||||
|
||||
$ratio = min($xRatio, $yRatio);
|
||||
|
||||
$thumbnailWidth = round($ratio * $this->_sizeArray[0]);
|
||||
$thumbnailHeight = round($ratio * $this->_sizeArray[1]);
|
||||
$thumbnail = imagecreatetruecolor($thumbnailWidth, $thumbnailHeight);
|
||||
imagecopyresampled($thumbnail, $image, 0, 0, 0, 0, $thumbnailWidth, $thumbnailHeight, $this->_sizeArray[0], $this->_sizeArray[1]);
|
||||
|
||||
// Copy the new file over
|
||||
$filename = $category->getId() . '-category' . $this->_imageExtension;
|
||||
$contextFileManager->copyFile($temporaryFile->getFilePath(), $basePath . $filename);
|
||||
|
||||
switch ($this->_imageExtension) {
|
||||
case '.jpg': imagejpeg($thumbnail, $basePath . $thumbnailFilename);
|
||||
break;
|
||||
case '.png': imagepng($thumbnail, $basePath . $thumbnailFilename);
|
||||
break;
|
||||
case '.gif': imagegif($thumbnail, $basePath . $thumbnailFilename);
|
||||
break;
|
||||
}
|
||||
imagedestroy($thumbnail);
|
||||
imagedestroy($image);
|
||||
|
||||
$category->setImage([
|
||||
'name' => $filename,
|
||||
'width' => $this->_sizeArray[0],
|
||||
'height' => $this->_sizeArray[1],
|
||||
'thumbnailName' => $thumbnailFilename,
|
||||
'thumbnailWidth' => $thumbnailWidth,
|
||||
'thumbnailHeight' => $thumbnailHeight,
|
||||
'uploadName' => $temporaryFile->getOriginalFileName(),
|
||||
'dateUploaded' => Core::getCurrentDate(),
|
||||
]);
|
||||
|
||||
// Clean up the temporary file
|
||||
$temporaryFileManager = new TemporaryFileManager();
|
||||
$temporaryFileManager->deleteById($temporaryFileId, $this->_userId);
|
||||
}
|
||||
|
||||
// Update category object to store image information.
|
||||
Repo::category()->edit($category, []);
|
||||
parent::execute(...$functionArgs);
|
||||
return $category;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,285 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/settings/genre/GenreGridHandler.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 GenreGridHandler
|
||||
*
|
||||
* @ingroup controllers_grid_settings_genre
|
||||
*
|
||||
* @brief Handle Genre grid requests.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\settings\genre;
|
||||
|
||||
use APP\facades\Repo;
|
||||
use PKP\controllers\grid\DataObjectGridCellProvider;
|
||||
use PKP\controllers\grid\feature\OrderGridItemsFeature;
|
||||
use PKP\controllers\grid\GridColumn;
|
||||
use PKP\controllers\grid\settings\genre\form\GenreForm;
|
||||
use PKP\controllers\grid\settings\SetupGridHandler;
|
||||
use PKP\core\JSONMessage;
|
||||
use PKP\core\PKPRequest;
|
||||
use PKP\db\DAO;
|
||||
use PKP\db\DAORegistry;
|
||||
use PKP\facades\Locale;
|
||||
use PKP\linkAction\LinkAction;
|
||||
use PKP\linkAction\request\AjaxModal;
|
||||
use PKP\linkAction\request\RemoteActionConfirmationModal;
|
||||
use PKP\security\Role;
|
||||
use PKP\submission\GenreDAO;
|
||||
|
||||
class GenreGridHandler extends SetupGridHandler
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->addRoleAssignment([Role::ROLE_ID_MANAGER, Role::ROLE_ID_SITE_ADMIN], [
|
||||
'fetchGrid', 'fetchRow',
|
||||
'addGenre', 'editGenre', 'updateGenre',
|
||||
'deleteGenre', 'restoreGenres', 'saveSequence'
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Overridden template methods
|
||||
//
|
||||
/**
|
||||
* Configure the grid
|
||||
*
|
||||
* @see SetupGridHandler::initialize
|
||||
*
|
||||
* @param null|mixed $args
|
||||
*/
|
||||
public function initialize($request, $args = null)
|
||||
{
|
||||
parent::initialize($request, $args);
|
||||
|
||||
// Set the grid title.
|
||||
$this->setTitle('grid.genres.title');
|
||||
|
||||
// Add grid-level actions
|
||||
$router = $request->getRouter();
|
||||
$actionArgs = ['gridId' => $this->getId()];
|
||||
|
||||
$this->addAction(
|
||||
new LinkAction(
|
||||
'addGenre',
|
||||
new AjaxModal(
|
||||
$router->url($request, null, null, 'addGenre', null, $actionArgs),
|
||||
__('grid.action.addGenre'),
|
||||
'modal_add_item',
|
||||
true
|
||||
),
|
||||
__('grid.action.addGenre'),
|
||||
'add_item'
|
||||
)
|
||||
);
|
||||
|
||||
$this->addAction(
|
||||
new LinkAction(
|
||||
'restoreGenres',
|
||||
new RemoteActionConfirmationModal(
|
||||
$request->getSession(),
|
||||
__('grid.action.restoreDefaults.confirm'),
|
||||
null,
|
||||
$router->url($request, null, null, 'restoreGenres', null, $actionArgs),
|
||||
'modal_delete'
|
||||
),
|
||||
__('grid.action.restoreDefaults'),
|
||||
'reset_default'
|
||||
)
|
||||
);
|
||||
|
||||
// Columns
|
||||
$cellProvider = new DataObjectGridCellProvider();
|
||||
$cellProvider->setLocale(Locale::getLocale());
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'name',
|
||||
'common.name',
|
||||
null,
|
||||
null,
|
||||
$cellProvider
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::loadData()
|
||||
*/
|
||||
protected function loadData($request, $filter)
|
||||
{
|
||||
// Elements to be displayed in the grid
|
||||
$context = $request->getContext();
|
||||
$genreDao = DAORegistry::getDAO('GenreDAO'); /** @var GenreDAO $genreDao */
|
||||
return $genreDao->getEnabledByContextId($context->getId(), self::getRangeInfo($request, $this->getId()));
|
||||
}
|
||||
|
||||
//
|
||||
// Overridden methods from GridHandler
|
||||
//
|
||||
/**
|
||||
* @copydoc GridHandler::initFeatures()
|
||||
*/
|
||||
public function initFeatures($request, $args)
|
||||
{
|
||||
return [new OrderGridItemsFeature()];
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::getRowInstance()
|
||||
*
|
||||
* @return GenreGridRow
|
||||
*/
|
||||
protected function getRowInstance()
|
||||
{
|
||||
return new GenreGridRow();
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::getDataElementSequence()
|
||||
*/
|
||||
public function getDataElementSequence($row)
|
||||
{
|
||||
return $row->getSequence();
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::setDataElementSequence()
|
||||
*/
|
||||
public function setDataElementSequence($request, $rowId, $gridDataElement, $newSequence)
|
||||
{
|
||||
$genreDao = DAORegistry::getDAO('GenreDAO'); /** @var GenreDAO $genreDao */
|
||||
$context = $request->getContext();
|
||||
$genre = $genreDao->getById($rowId, $context->getId());
|
||||
$genre->setSequence($newSequence);
|
||||
$genreDao->updateObject($genre);
|
||||
}
|
||||
|
||||
//
|
||||
// Public Genre Grid Actions
|
||||
//
|
||||
/**
|
||||
* An action to add a new Genre
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*/
|
||||
public function addGenre($args, $request)
|
||||
{
|
||||
// Calling editGenre with an empty row id will add a new Genre.
|
||||
return $this->editGenre($args, $request);
|
||||
}
|
||||
|
||||
/**
|
||||
* An action to edit a Genre
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function editGenre($args, $request)
|
||||
{
|
||||
$genreId = isset($args['genreId']) ? (int) $args['genreId'] : null;
|
||||
|
||||
$this->setupTemplate($request);
|
||||
|
||||
$genreForm = new GenreForm($genreId);
|
||||
|
||||
$genreForm->initData($args);
|
||||
|
||||
return new JSONMessage(true, $genreForm->fetch($request));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a Genre
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function updateGenre($args, $request)
|
||||
{
|
||||
$genreId = isset($args['genreId']) ? (int) $args['genreId'] : null;
|
||||
|
||||
$genreForm = new GenreForm($genreId);
|
||||
$genreForm->readInputData();
|
||||
|
||||
if ($genreForm->validate()) {
|
||||
$genreForm->execute();
|
||||
return DAO::getDataChangedEvent($genreForm->getGenreId());
|
||||
}
|
||||
|
||||
return new JSONMessage(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a Genre.
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function deleteGenre($args, $request)
|
||||
{
|
||||
$genreId = isset($args['genreId']) ? (int) $args['genreId'] : null;
|
||||
$context = $request->getContext();
|
||||
$genreDao = DAORegistry::getDAO('GenreDAO'); /** @var GenreDAO $genreDao */
|
||||
$genre = $genreDao->getById($genreId, $context->getId());
|
||||
|
||||
if (!$request->checkCSRF()) {
|
||||
return new JSONMessage(false, __('form.csrfInvalid'));
|
||||
}
|
||||
|
||||
if (!$genre) {
|
||||
return new JSONMessage(false, __('manager.setup.errorDeletingItem'));
|
||||
}
|
||||
|
||||
$submissionsByGenre = Repo::submissionFile()
|
||||
->getCollector()
|
||||
->filterByGenreIds([$genreId])
|
||||
->getCount();
|
||||
|
||||
// Block the removal of genres that have at least one assigned submission file
|
||||
if ($submissionsByGenre) {
|
||||
return new JSONMessage(false, __('manager.genres.alertDelete'));
|
||||
}
|
||||
|
||||
$genreDao->deleteObject($genre);
|
||||
return DAO::getDataChangedEvent($genre->getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore the default Genre settings for the context.
|
||||
* All default settings that were available when the context instance was created will be restored.
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function restoreGenres($args, $request)
|
||||
{
|
||||
if (!$request->checkCSRF()) {
|
||||
return new JSONMessage(false);
|
||||
}
|
||||
|
||||
// Restore all the genres in this context form the registry XML file
|
||||
$context = $request->getContext();
|
||||
$genreDao = DAORegistry::getDAO('GenreDAO'); /** @var GenreDAO $genreDao */
|
||||
$genreDao->installDefaults($context->getId(), $context->getSupportedFormLocales());
|
||||
return DAO::getDataChangedEvent();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/settings/genre/GenreGridRow.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 GenreGridRow
|
||||
*
|
||||
* @ingroup controllers_grid_settings_genre
|
||||
*
|
||||
* @brief Handle Genre grid row requests.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\settings\genre;
|
||||
|
||||
use PKP\controllers\grid\GridRow;
|
||||
use PKP\linkAction\LinkAction;
|
||||
use PKP\linkAction\request\AjaxModal;
|
||||
use PKP\linkAction\request\RemoteActionConfirmationModal;
|
||||
|
||||
class GenreGridRow 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?
|
||||
$rowId = $this->getId();
|
||||
if (!empty($rowId) && is_numeric($rowId)) {
|
||||
$router = $request->getRouter();
|
||||
$actionArgs = [
|
||||
'gridId' => $this->getGridId(),
|
||||
'genreId' => $rowId
|
||||
];
|
||||
|
||||
$this->addAction(
|
||||
new LinkAction(
|
||||
'editGenre',
|
||||
new AjaxModal(
|
||||
$router->url($request, null, null, 'editGenre', null, $actionArgs),
|
||||
__('grid.action.edit'),
|
||||
'modal_edit',
|
||||
true
|
||||
),
|
||||
__('grid.action.edit'),
|
||||
'edit'
|
||||
)
|
||||
);
|
||||
|
||||
$this->addAction(
|
||||
new LinkAction(
|
||||
'deleteGenre',
|
||||
new RemoteActionConfirmationModal(
|
||||
$request->getSession(),
|
||||
__('common.confirmDelete'),
|
||||
__('grid.action.delete'),
|
||||
$router->url($request, null, null, 'deleteGenre', null, $actionArgs),
|
||||
'modal_delete'
|
||||
),
|
||||
__('grid.action.delete'),
|
||||
'delete'
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/settings/genre/form/GenreForm.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 GenreForm
|
||||
*
|
||||
* @ingroup controllers_grid_settings_genre_form
|
||||
*
|
||||
* @brief Form for adding/editing a Submission File Genre.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\settings\genre\form;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\template\TemplateManager;
|
||||
use PKP\db\DAORegistry;
|
||||
use PKP\form\Form;
|
||||
use PKP\security\Validation;
|
||||
use PKP\submission\Genre;
|
||||
use PKP\submission\GenreDAO;
|
||||
|
||||
class GenreForm extends Form
|
||||
{
|
||||
/** @var int the id for the genre being edited */
|
||||
public $_genreId;
|
||||
|
||||
/**
|
||||
* Set the genre id
|
||||
*
|
||||
* @param int $genreId
|
||||
*/
|
||||
public function setGenreId($genreId)
|
||||
{
|
||||
$this->_genreId = $genreId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the genre id
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getGenreId()
|
||||
{
|
||||
return $this->_genreId;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param null|mixed $genreId
|
||||
*/
|
||||
public function __construct($genreId = null)
|
||||
{
|
||||
$this->setGenreId($genreId);
|
||||
parent::__construct('controllers/grid/settings/genre/form/genreForm.tpl');
|
||||
|
||||
$request = Application::get()->getRequest();
|
||||
$context = $request->getContext();
|
||||
|
||||
// Validation checks for this form
|
||||
$form = $this;
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorLocale($this, 'name', 'required', 'manager.setup.form.genre.nameRequired'));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorCustom($this, 'key', 'optional', 'manager.setup.genres.key.exists', function ($key) use ($context, $form) {
|
||||
$genreDao = DAORegistry::getDAO('GenreDAO'); /** @var GenreDAO $genreDao */
|
||||
return $key == '' || !$genreDao->keyExists($key, $context->getId(), $form->getGenreId());
|
||||
}));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorRegExp($this, 'key', 'optional', 'manager.setup.genres.key.alphaNumeric', '/^[a-z0-9]+([\-_][a-z0-9]+)*$/i'));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorPost($this));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorCSRF($this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize form data from current settings.
|
||||
*
|
||||
* @param array $args
|
||||
*/
|
||||
public function initData($args = [])
|
||||
{
|
||||
$request = Application::get()->getRequest();
|
||||
$context = $request->getContext();
|
||||
|
||||
$genreDao = DAORegistry::getDAO('GenreDAO'); /** @var GenreDAO $genreDao */
|
||||
|
||||
if ($this->getGenreId()) {
|
||||
$genre = $genreDao->getById($this->getGenreId(), $context->getId());
|
||||
}
|
||||
|
||||
if (isset($genre)) {
|
||||
$this->_data = [
|
||||
'genreId' => $this->getGenreId(),
|
||||
'name' => $genre->getName(null),
|
||||
'category' => $genre->getCategory(),
|
||||
'dependent' => $genre->getDependent(),
|
||||
'supplementary' => $genre->getSupplementary(),
|
||||
'required' => $genre->getRequired(),
|
||||
'key' => $genre->getKey(),
|
||||
'keyReadOnly' => $genre->isDefault(),
|
||||
];
|
||||
} else {
|
||||
$this->_data = [
|
||||
'name' => [],
|
||||
];
|
||||
}
|
||||
|
||||
// grid related data
|
||||
$this->_data['gridId'] = $args['gridId'];
|
||||
$this->_data['rowId'] = $args['rowId'] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::fetch()
|
||||
*
|
||||
* @param null|mixed $template
|
||||
*/
|
||||
public function fetch($request, $template = null, $display = false)
|
||||
{
|
||||
$templateMgr = TemplateManager::getManager($request);
|
||||
$templateMgr->assign('submissionFileCategories', [
|
||||
Genre::GENRE_CATEGORY_DOCUMENT => __('submission.document'),
|
||||
Genre::GENRE_CATEGORY_ARTWORK => __('submission.art'),
|
||||
Genre::GENRE_CATEGORY_SUPPLEMENTARY => __('submission.supplementary'),
|
||||
]);
|
||||
return parent::fetch($request, $template, $display);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign form data to user-submitted data.
|
||||
*
|
||||
* @see Form::readInputData()
|
||||
*/
|
||||
public function readInputData()
|
||||
{
|
||||
$this->readUserVars(['genreId', 'name', 'category', 'dependent', 'supplementary', 'required', 'gridId', 'rowId', 'key']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::execute()
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function execute(...$functionArgs)
|
||||
{
|
||||
$genreDao = DAORegistry::getDAO('GenreDAO'); /** @var GenreDAO $genreDao */
|
||||
$request = Application::get()->getRequest();
|
||||
$context = $request->getContext();
|
||||
|
||||
// Update or insert genre
|
||||
if (!$this->getGenreId()) {
|
||||
$genre = $genreDao->newDataObject();
|
||||
$genre->setContextId($context->getId());
|
||||
} else {
|
||||
$genre = $genreDao->getById($this->getGenreId(), $context->getId());
|
||||
}
|
||||
|
||||
$genre->setData('name', $this->getData('name'), null); // Localized
|
||||
$genre->setCategory($this->getData('category'));
|
||||
$genre->setDependent($this->getData('dependent'));
|
||||
$genre->setSupplementary($this->getData('supplementary'));
|
||||
$genre->setRequired((bool) $this->getData('required'));
|
||||
|
||||
if (!$genre->isDefault()) {
|
||||
$genre->setKey($this->getData('key'));
|
||||
}
|
||||
|
||||
if (!$this->getGenreId()) {
|
||||
$this->setGenreId($genreDao->insertObject($genre));
|
||||
} else {
|
||||
$genreDao->updateObject($genre);
|
||||
}
|
||||
parent::execute(...$functionArgs);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/settings/languages/ManageLanguageGridHandler.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 ManageLanguageGridHandler
|
||||
*
|
||||
* @ingroup controllers_grid_settings_languages
|
||||
*
|
||||
* @brief Handle language management grid requests only.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\settings\languages;
|
||||
|
||||
use APP\core\Request;
|
||||
use APP\core\Services;
|
||||
use APP\notification\NotificationManager;
|
||||
use PKP\controllers\grid\languages\LanguageGridHandler;
|
||||
use PKP\core\JSONMessage;
|
||||
use PKP\facades\Locale;
|
||||
use PKP\notification\PKPNotification;
|
||||
use PKP\security\authorization\ContextAccessPolicy;
|
||||
use PKP\security\Role;
|
||||
|
||||
class ManageLanguageGridHandler extends LanguageGridHandler
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->addRoleAssignment(
|
||||
[Role::ROLE_ID_MANAGER, Role::ROLE_ID_SITE_ADMIN],
|
||||
['saveLanguageSetting', 'setContextPrimaryLocale', 'reloadLocale', 'fetchGrid', 'fetchRow']
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Implement methods from GridHandler.
|
||||
//
|
||||
/**
|
||||
* @copydoc GridHandler::authorize()
|
||||
*/
|
||||
public function authorize($request, &$args, $roleAssignments)
|
||||
{
|
||||
$this->addPolicy(new ContextAccessPolicy($request, $roleAssignments));
|
||||
return parent::authorize($request, $args, $roleAssignments);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::loadData()
|
||||
*/
|
||||
protected function loadData($request, $filter)
|
||||
{
|
||||
$site = $request->getSite();
|
||||
$context = $request->getContext();
|
||||
$allLocales = Locale::getLocales();
|
||||
|
||||
$supportedLocales = $site->getSupportedLocales();
|
||||
$contextPrimaryLocale = $context->getPrimaryLocale();
|
||||
$data = [];
|
||||
|
||||
foreach ($supportedLocales as $locale) {
|
||||
$formattedLocale = Locale::getFormattedDisplayNames([$locale], $allLocales);
|
||||
$data[$locale] = [];
|
||||
$data[$locale]['code'] = $locale;
|
||||
$data[$locale]['name'] = array_shift($formattedLocale);
|
||||
$data[$locale]['supported'] = true;
|
||||
$data[$locale]['primary'] = ($locale == $contextPrimaryLocale);
|
||||
}
|
||||
|
||||
$data = $this->addManagementData($request, $data);
|
||||
return $data;
|
||||
}
|
||||
|
||||
//
|
||||
// Extended methods from LanguageGridHandler.
|
||||
//
|
||||
/**
|
||||
* @copydoc LanguageGridHandler::initialize()
|
||||
*
|
||||
* @param null|mixed $args
|
||||
*/
|
||||
public function initialize($request, $args = null)
|
||||
{
|
||||
parent::initialize($request, $args);
|
||||
$this->addNameColumn();
|
||||
$this->addLocaleCodeColumn();
|
||||
$this->addPrimaryColumn('contextPrimary');
|
||||
$this->addManagementColumns();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reload locale.
|
||||
*
|
||||
* @param array $args
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function reloadLocale($args, $request)
|
||||
{
|
||||
$context = $request->getContext();
|
||||
$locale = $request->getUserVar('rowId');
|
||||
$gridData = $this->getGridDataElements($request);
|
||||
|
||||
if (empty($context) || !$request->checkCSRF() || !array_key_exists($locale, $gridData)) {
|
||||
return new JSONMessage(false);
|
||||
}
|
||||
|
||||
$context = Services::get('context')->restoreLocaleDefaults($context, $request, $locale);
|
||||
|
||||
$notificationManager = new NotificationManager();
|
||||
$notificationManager->createTrivialNotification(
|
||||
$request->getUser()->getId(),
|
||||
PKPNotification::NOTIFICATION_TYPE_SUCCESS,
|
||||
['contents' => __('notification.localeReloaded', ['locale' => $gridData[$locale]['name'], 'contextName' => $context->getLocalizedName()])]
|
||||
);
|
||||
|
||||
return \PKP\db\DAO::getDataChangedEvent($locale);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/settings/library/LibraryFileAdminGridDataProvider.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 LibraryFileAdminGridDataProvider
|
||||
*
|
||||
* @ingroup controllers_grid_settings_library
|
||||
*
|
||||
* @brief The data provider for the admin library files grid.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\settings\library;
|
||||
|
||||
use PKP\context\Context;
|
||||
use PKP\context\LibraryFileDAO;
|
||||
use PKP\controllers\grid\CategoryGridDataProvider;
|
||||
use PKP\db\DAORegistry;
|
||||
use PKP\security\authorization\ContextAccessPolicy;
|
||||
|
||||
class LibraryFileAdminGridDataProvider extends CategoryGridDataProvider
|
||||
{
|
||||
/** @var Context the context for this library */
|
||||
public $_context;
|
||||
|
||||
/** @var bool Whether or not this grid is editable */
|
||||
public $_canEdit;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct($canEdit)
|
||||
{
|
||||
$this->_canEdit = $canEdit;
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Getters and Setters
|
||||
//
|
||||
|
||||
/**
|
||||
* @copydoc GridDataProvider::getAuthorizationPolicy()
|
||||
*/
|
||||
public function getAuthorizationPolicy($request, $args, $roleAssignments)
|
||||
{
|
||||
$this->_context = $request->getContext();
|
||||
return new ContextAccessPolicy($request, $roleAssignments);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridDataProvider::getRequestArgs()
|
||||
*/
|
||||
public function getRequestArgs()
|
||||
{
|
||||
return ['canEdit' => $this->canEdit()];
|
||||
}
|
||||
|
||||
/**
|
||||
* get the current context
|
||||
*
|
||||
* @return $context Context
|
||||
*/
|
||||
public function &getContext()
|
||||
{
|
||||
return $this->_context;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* get whether or not this grid is editable (has actions).
|
||||
*
|
||||
* @return bool $canEdit
|
||||
*/
|
||||
public function canEdit()
|
||||
{
|
||||
return $this->_canEdit;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @copydoc CategoryGridHandler::loadCategoryData()
|
||||
*
|
||||
* @param null|mixed $filter
|
||||
*/
|
||||
public function loadCategoryData($request, $fileType, $filter = null)
|
||||
{
|
||||
// Elements to be displayed in the grid
|
||||
$libraryFileDao = DAORegistry::getDAO('LibraryFileDAO'); /** @var LibraryFileDAO $libraryFileDao */
|
||||
$context = $this->getContext();
|
||||
$libraryFiles = $libraryFileDao->getByContextId($context->getId(), $fileType);
|
||||
|
||||
return $libraryFiles->toAssociativeArray();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/settings/library/LibraryFileAdminGridHandler.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 LibraryFileAdminGridHandler
|
||||
*
|
||||
* @ingroup controllers_grid_settings_library
|
||||
*
|
||||
* @brief Handle library file grid requests.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\settings\library;
|
||||
|
||||
use PKP\context\Context;
|
||||
use PKP\controllers\grid\files\LibraryFileGridHandler;
|
||||
use PKP\controllers\grid\settings\library\form\EditLibraryFileForm;
|
||||
use PKP\controllers\grid\settings\library\form\NewLibraryFileForm;
|
||||
use PKP\security\Role;
|
||||
|
||||
class LibraryFileAdminGridHandler extends LibraryFileGridHandler
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(new LibraryFileAdminGridDataProvider(true));
|
||||
$this->addRoleAssignment(
|
||||
[Role::ROLE_ID_MANAGER, Role::ROLE_ID_SITE_ADMIN],
|
||||
[
|
||||
'fetchGrid', 'addFile', 'uploadFile', 'saveFile', // Adding new library files
|
||||
'editFile', 'updateFile', // Editing existing library files
|
||||
'deleteFile'
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// Overridden template methods
|
||||
//
|
||||
|
||||
/**
|
||||
* Configure the grid
|
||||
*
|
||||
* @see LibraryGridHandler::initialize
|
||||
*
|
||||
* @param null|mixed $args
|
||||
*/
|
||||
public function initialize($request, $args = null)
|
||||
{
|
||||
// determine if this grid is read only.
|
||||
$this->setCanEdit((bool) $request->getUserVar('canEdit'));
|
||||
|
||||
parent::initialize($request, $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a specific instance of the new form for this grid.
|
||||
*
|
||||
* @param Context $context
|
||||
*
|
||||
* @return NewLibraryFileForm
|
||||
*/
|
||||
public function _getNewFileForm($context)
|
||||
{
|
||||
return new NewLibraryFileForm($context->getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a specific instance of the edit form for this grid.
|
||||
*
|
||||
* @param Context $context
|
||||
* @param int $fileId
|
||||
*
|
||||
* @return EditLibraryFileForm
|
||||
*/
|
||||
public function _getEditFileForm($context, $fileId)
|
||||
{
|
||||
return new EditLibraryFileForm($context->getId(), $fileId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/settings/library/form/EditLibraryFileForm.php
|
||||
*
|
||||
* Copyright (c) 2014-2021 Simon Fraser University
|
||||
* Copyright (c) 2003-2021 John Willinsky
|
||||
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
|
||||
*
|
||||
* @class EditLibraryFileForm
|
||||
*
|
||||
* @ingroup controllers_grid_file_form
|
||||
*
|
||||
* @brief Form for editing a library file
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\settings\library\form;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\file\LibraryFileManager;
|
||||
use PKP\context\LibraryFile;
|
||||
use PKP\context\LibraryFileDAO;
|
||||
use PKP\controllers\grid\files\form\LibraryFileForm;
|
||||
use PKP\db\DAORegistry;
|
||||
use PKP\file\TemporaryFileManager;
|
||||
|
||||
class EditLibraryFileForm extends LibraryFileForm
|
||||
{
|
||||
/** @var LibraryFile the file being edited, or null for new */
|
||||
public $libraryFile;
|
||||
|
||||
/** @var int the id of the context this library file is attached to */
|
||||
public $contextId;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param int $contextId
|
||||
* @param int $fileId optional
|
||||
*/
|
||||
public function __construct($contextId, $fileId)
|
||||
{
|
||||
parent::__construct('controllers/grid/settings/library/form/editFileForm.tpl', $contextId);
|
||||
$libraryFileDao = DAORegistry::getDAO('LibraryFileDAO'); /** @var LibraryFileDAO $libraryFileDao */
|
||||
$this->libraryFile = $libraryFileDao->getById($fileId);
|
||||
|
||||
if (!$this->libraryFile || $this->libraryFile->getContextId() != $this->contextId) {
|
||||
fatalError('Invalid library file!');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign form data to user-submitted data.
|
||||
* @see Form::readInputData()
|
||||
*/
|
||||
function readInputData() {
|
||||
$this->readUserVars(array('temporaryFileId'));
|
||||
return parent::readInputData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize form data from current settings.
|
||||
*/
|
||||
public function initData()
|
||||
{
|
||||
$this->_data = [
|
||||
'libraryFileName' => $this->libraryFile->getName(null), // Localized
|
||||
'libraryFile' => $this->libraryFile, // For read-only info
|
||||
'publicAccess' => $this->libraryFile->getPublicAccess() ? true : false,
|
||||
'temporaryFileId' => null,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::execute()
|
||||
*/
|
||||
public function execute(...$functionArgs)
|
||||
{
|
||||
$userId = Application::get()->getRequest()->getUser()->getId();
|
||||
|
||||
// Fetch the temporary file storing the uploaded library file
|
||||
$temporaryFileDao = DAORegistry::getDAO('TemporaryFileDAO'); /* @var $temporaryFileDao TemporaryFileDAO */
|
||||
$temporaryFile = $temporaryFileDao->getTemporaryFile(
|
||||
$this->getData('temporaryFileId'),
|
||||
$userId
|
||||
);
|
||||
if ($temporaryFile) {
|
||||
$libraryFileDao = DAORegistry::getDAO('LibraryFileDAO'); /* @var $libraryFileDao LibraryFileDAO */
|
||||
$libraryFileManager = new LibraryFileManager($this->contextId);
|
||||
|
||||
// Convert the temporary file to a library file and store
|
||||
$this->libraryFile = $libraryFileManager->replaceFromTemporaryFile($temporaryFile, $this->getData('fileType'), $this->libraryFile);
|
||||
// Clean up the temporary file
|
||||
$temporaryFileManager = new TemporaryFileManager();
|
||||
$temporaryFileManager->deleteById($this->getData('temporaryFileId'), $userId);
|
||||
}
|
||||
$this->libraryFile->setName($this->getData('libraryFileName'), null); // Localized
|
||||
$this->libraryFile->setType($this->getData('fileType'));
|
||||
$this->libraryFile->setPublicAccess($this->getData('publicAccess'));
|
||||
|
||||
$libraryFileDao = DAORegistry::getDAO('LibraryFileDAO'); /** @var LibraryFileDAO $libraryFileDao */
|
||||
$libraryFileDao->updateObject($this->libraryFile);
|
||||
parent::execute(...$functionArgs);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/settings/library/form/NewLibraryFileForm.php
|
||||
*
|
||||
* Copyright (c) 2014-2021 Simon Fraser University
|
||||
* Copyright (c) 2003-2021 John Willinsky
|
||||
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
|
||||
*
|
||||
* @class NewLibraryFileForm
|
||||
*
|
||||
* @ingroup controllers_grid_file_form
|
||||
*
|
||||
* @brief Form for adding/editing a file
|
||||
* stores/retrieves from an associative array
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\settings\library\form;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\file\LibraryFileManager;
|
||||
use PKP\context\LibraryFileDAO;
|
||||
use PKP\controllers\grid\files\form\LibraryFileForm;
|
||||
use PKP\db\DAORegistry;
|
||||
use PKP\file\TemporaryFileDAO;
|
||||
use PKP\file\TemporaryFileManager;
|
||||
|
||||
class NewLibraryFileForm extends LibraryFileForm
|
||||
{
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param int $contextId
|
||||
*/
|
||||
public function __construct($contextId)
|
||||
{
|
||||
parent::__construct('controllers/grid/settings/library/form/newFileForm.tpl', $contextId);
|
||||
$this->addCheck(new \PKP\form\validation\FormValidator($this, 'temporaryFileId', 'required', 'settings.libraryFiles.fileRequired'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign form data to user-submitted data.
|
||||
*
|
||||
* @see Form::readInputData()
|
||||
*/
|
||||
public function readInputData()
|
||||
{
|
||||
$this->readUserVars(['temporaryFileId']);
|
||||
return parent::readInputData();
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::execute()
|
||||
*
|
||||
* @return $fileId int The new library file id.
|
||||
*/
|
||||
public function execute(...$functionArgs)
|
||||
{
|
||||
$userId = Application::get()->getRequest()->getUser()->getId();
|
||||
|
||||
// Fetch the temporary file storing the uploaded library file
|
||||
$temporaryFileDao = DAORegistry::getDAO('TemporaryFileDAO'); /** @var TemporaryFileDAO $temporaryFileDao */
|
||||
$temporaryFile = $temporaryFileDao->getTemporaryFile(
|
||||
$this->getData('temporaryFileId'),
|
||||
$userId
|
||||
);
|
||||
$libraryFileDao = DAORegistry::getDAO('LibraryFileDAO'); /** @var LibraryFileDAO $libraryFileDao */
|
||||
$libraryFileManager = new LibraryFileManager($this->contextId);
|
||||
|
||||
// Convert the temporary file to a library file and store
|
||||
$libraryFile = $libraryFileManager->copyFromTemporaryFile($temporaryFile, $this->getData('fileType'));
|
||||
assert(isset($libraryFile));
|
||||
$libraryFile->setContextId($this->contextId);
|
||||
$libraryFile->setName($this->getData('libraryFileName'), null); // Localized
|
||||
$libraryFile->setType($this->getData('fileType'));
|
||||
$libraryFile->setPublicAccess($this->getData('publicAccess'));
|
||||
|
||||
$fileId = $libraryFileDao->insertObject($libraryFile);
|
||||
|
||||
// Clean up the temporary file
|
||||
$temporaryFileManager = new TemporaryFileManager();
|
||||
$temporaryFileManager->deleteById($this->getData('temporaryFileId'), $userId);
|
||||
parent::execute(...$functionArgs);
|
||||
return $fileId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
/**
|
||||
* @file controllers/grid/settings/reviewForms/ReviewFormElementGridCellProvider.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 ReviewFormElementGridCellProvider
|
||||
*
|
||||
* @ingroup controllers_grid_settings_reviewForms
|
||||
*
|
||||
* @brief Subclass for review form element column's cell provider
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\settings\reviewForms;
|
||||
|
||||
use PKP\controllers\grid\GridCellProvider;
|
||||
use PKP\controllers\grid\GridColumn;
|
||||
|
||||
class ReviewFormElementGridCellProvider extends GridCellProvider
|
||||
{
|
||||
/**
|
||||
* Extracts variables for a given column from a data element
|
||||
* so that they may be assigned to template before rendering.
|
||||
*
|
||||
* @param \PKP\controllers\grid\GridRow $row
|
||||
* @param GridColumn $column
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getTemplateVarsFromRowColumn($row, $column)
|
||||
{
|
||||
$element = $row->getData();
|
||||
$columnId = $column->getId();
|
||||
assert($element instanceof \PKP\reviewForm\ReviewFormElement && !empty($columnId));
|
||||
switch ($columnId) {
|
||||
case 'question':
|
||||
$label = $element->getLocalizedQuestion();
|
||||
return ['label' => $label];
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/settings/reviewForms/ReviewFormElementGridRow.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 ReviewFormElementGridRow
|
||||
*
|
||||
* @ingroup controllers_grid_settings_reviewForms
|
||||
*
|
||||
* @brief ReviewFormElements grid row definition
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\settings\reviewForms;
|
||||
|
||||
use PKP\controllers\grid\GridRow;
|
||||
use PKP\linkAction\LinkAction;
|
||||
use PKP\linkAction\request\AjaxModal;
|
||||
use PKP\linkAction\request\RemoteActionConfirmationModal;
|
||||
|
||||
class ReviewFormElementGridRow extends GridRow
|
||||
{
|
||||
//
|
||||
// Overridden methods from GridRow
|
||||
//
|
||||
/**
|
||||
* @copydoc GridRow::initialize()
|
||||
*
|
||||
* @param null|mixed $template
|
||||
*/
|
||||
public function initialize($request, $template = null)
|
||||
{
|
||||
parent::initialize($request, $template);
|
||||
// add grid row actions: edit, delete
|
||||
|
||||
$element = parent::getData();
|
||||
assert($element instanceof \PKP\reviewForm\ReviewFormElement);
|
||||
$rowId = $this->getId();
|
||||
|
||||
$router = $request->getRouter();
|
||||
if (!empty($rowId) && is_numeric($rowId)) {
|
||||
// add 'edit' grid row action
|
||||
$this->addAction(
|
||||
new LinkAction(
|
||||
'edit',
|
||||
new AjaxModal(
|
||||
$router->url($request, null, null, 'editReviewFormElement', null, ['rowId' => $rowId, 'reviewFormId' => $element->getReviewFormId()]),
|
||||
__('grid.action.edit'),
|
||||
'modal_edit',
|
||||
true
|
||||
),
|
||||
__('grid.action.edit'),
|
||||
'edit'
|
||||
)
|
||||
);
|
||||
// add 'delete' grid row action
|
||||
$this->addAction(
|
||||
new LinkAction(
|
||||
'delete',
|
||||
new RemoteActionConfirmationModal(
|
||||
$request->getSession(),
|
||||
__('manager.reviewFormElements.confirmDelete'),
|
||||
null,
|
||||
$router->url($request, null, null, 'deleteReviewFormElement', null, ['rowId' => $rowId, 'reviewFormId' => $element->getReviewFormId()])
|
||||
),
|
||||
__('grid.action.delete'),
|
||||
'delete'
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,291 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/settings/reviewForms/ReviewFormElementsGridHandler.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 ReviewFormElementsGridHandler
|
||||
*
|
||||
* @ingroup controllers_grid_settings_reviewForms
|
||||
*
|
||||
* @brief Handle review form element grid requests.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\settings\reviewForms;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\notification\NotificationManager;
|
||||
use PKP\controllers\grid\feature\OrderGridItemsFeature;
|
||||
use PKP\controllers\grid\GridColumn;
|
||||
use PKP\controllers\grid\GridHandler;
|
||||
use PKP\controllers\grid\settings\reviewForms\form\ReviewFormElementForm;
|
||||
use PKP\core\JSONMessage;
|
||||
use PKP\core\PKPRequest;
|
||||
use PKP\db\DAORegistry;
|
||||
use PKP\linkAction\LinkAction;
|
||||
use PKP\linkAction\request\AjaxModal;
|
||||
use PKP\reviewForm\ReviewFormDAO;
|
||||
use PKP\reviewForm\ReviewFormElementDAO;
|
||||
use PKP\security\authorization\PolicySet;
|
||||
use PKP\security\authorization\RoleBasedHandlerOperationPolicy;
|
||||
use PKP\security\Role;
|
||||
|
||||
class ReviewFormElementsGridHandler extends GridHandler
|
||||
{
|
||||
/** @var int Review form ID */
|
||||
public $reviewFormId;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->addRoleAssignment(
|
||||
[Role::ROLE_ID_MANAGER, Role::ROLE_ID_SITE_ADMIN],
|
||||
['fetchGrid', 'fetchRow', 'saveSequence',
|
||||
'createReviewFormElement', 'editReviewFormElement', 'deleteReviewFormElement', 'updateReviewFormElement']
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// Implement template methods from PKPHandler.
|
||||
//
|
||||
/**
|
||||
* @see 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);
|
||||
|
||||
$this->reviewFormId = (int) $request->getUserVar('reviewFormId');
|
||||
$reviewFormDao = DAORegistry::getDAO('ReviewFormDAO'); /** @var ReviewFormDAO $reviewFormDao */
|
||||
if (!$reviewFormDao->reviewFormExists($this->reviewFormId, Application::getContextAssocType(), $request->getContext()->getId())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return parent::authorize($request, $args, $roleAssignments);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::initialize()
|
||||
*
|
||||
* @param null|mixed $args
|
||||
*/
|
||||
public function initialize($request, $args = null)
|
||||
{
|
||||
parent::initialize($request, $args);
|
||||
|
||||
// Grid actions.
|
||||
$router = $request->getRouter();
|
||||
|
||||
|
||||
// Create Review Form Element link
|
||||
$this->addAction(
|
||||
new LinkAction(
|
||||
'createReviewFormElement',
|
||||
new AjaxModal(
|
||||
$router->url($request, null, null, 'createReviewFormElement', null, ['reviewFormId' => $this->reviewFormId]),
|
||||
__('manager.reviewFormElements.create'),
|
||||
'modal_add_item',
|
||||
true
|
||||
),
|
||||
__('manager.reviewFormElements.create'),
|
||||
'add_item'
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
//
|
||||
// Grid columns.
|
||||
//
|
||||
$reviewFormElementGridCellProvider = new ReviewFormElementGridCellProvider();
|
||||
|
||||
// Review form element name.
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'question',
|
||||
'manager.reviewFormElements.question',
|
||||
null,
|
||||
null,
|
||||
$reviewFormElementGridCellProvider,
|
||||
['html' => true, 'maxLength' => 220]
|
||||
)
|
||||
);
|
||||
|
||||
// Basic grid configuration.
|
||||
$this->setTitle('manager.reviewFormElements');
|
||||
}
|
||||
|
||||
//
|
||||
// Implement methods from GridHandler.
|
||||
//
|
||||
/**
|
||||
* @see GridHandler::addFeatures()
|
||||
*/
|
||||
public function initFeatures($request, $args)
|
||||
{
|
||||
return [new OrderGridItemsFeature()];
|
||||
}
|
||||
|
||||
/**
|
||||
* @see GridHandler::getRowInstance()
|
||||
*
|
||||
* @return ReviewFormElementGridRow
|
||||
*/
|
||||
protected function getRowInstance()
|
||||
{
|
||||
return new ReviewFormElementGridRow();
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::loadData()
|
||||
*
|
||||
* @param null|mixed $filter
|
||||
*/
|
||||
protected function loadData($request, $filter = null)
|
||||
{
|
||||
// Get review form elements.
|
||||
//$rangeInfo = $this->getRangeInfo('reviewFormElements');
|
||||
$reviewFormElementDao = DAORegistry::getDAO('ReviewFormElementDAO'); /** @var ReviewFormElementDAO $reviewFormElementDao */
|
||||
$reviewFormElements = $reviewFormElementDao->getByReviewFormId($this->reviewFormId, null); //FIXME add range info?
|
||||
|
||||
return $reviewFormElements->toAssociativeArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc CategoryGridHandler::getRequestArgs()
|
||||
*/
|
||||
public function getRequestArgs()
|
||||
{
|
||||
return array_merge(['reviewFormId' => $this->reviewFormId], parent::getRequestArgs());
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::getDataElementSequence()
|
||||
*/
|
||||
public function getDataElementSequence($gridDataElement)
|
||||
{
|
||||
return $gridDataElement->getSequence();
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::setDataElementSequence()
|
||||
*/
|
||||
public function setDataElementSequence($request, $rowId, $gridDataElement, $newSequence)
|
||||
{
|
||||
$reviewFormElementDao = DAORegistry::getDAO('ReviewFormElementDAO'); /** @var ReviewFormElementDAO $reviewFormElementDao */
|
||||
$gridDataElement->setSequence($newSequence);
|
||||
$reviewFormElementDao->updateObject($gridDataElement);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Public grid actions.
|
||||
//
|
||||
/**
|
||||
* Add a new review form element.
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function createReviewFormElement($args, $request)
|
||||
{
|
||||
// Form handling
|
||||
$reviewFormElementForm = new ReviewFormElementForm($this->reviewFormId);
|
||||
$reviewFormElementForm->initData();
|
||||
return new JSONMessage(true, $reviewFormElementForm->fetch($request));
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit an existing review form element.
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function editReviewFormElement($args, $request)
|
||||
{
|
||||
// Identify the review form element Id
|
||||
$reviewFormElementId = (int) $request->getUserVar('rowId');
|
||||
|
||||
// Display form
|
||||
$reviewFormElementForm = new ReviewFormElementForm($this->reviewFormId, $reviewFormElementId);
|
||||
$reviewFormElementForm->initData();
|
||||
return new JSONMessage(true, $reviewFormElementForm->fetch($request));
|
||||
}
|
||||
|
||||
/**
|
||||
* Save changes to a review form element.
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function updateReviewFormElement($args, $request)
|
||||
{
|
||||
$reviewFormElementId = (int) $request->getUserVar('reviewFormElementId');
|
||||
|
||||
$context = $request->getContext();
|
||||
$reviewFormDao = DAORegistry::getDAO('ReviewFormDAO'); /** @var ReviewFormDAO $reviewFormDao */
|
||||
$reviewFormElementDao = DAORegistry::getDAO('ReviewFormElementDAO'); /** @var ReviewFormElementDAO $reviewFormElementDao */
|
||||
|
||||
$reviewForm = $reviewFormDao->getById($this->reviewFormId, Application::getContextAssocType(), $context->getId());
|
||||
|
||||
if (!$reviewFormDao->unusedReviewFormExists($this->reviewFormId, Application::getContextAssocType(), $context->getId()) || ($reviewFormElementId && !$reviewFormElementDao->reviewFormElementExists($reviewFormElementId, $this->reviewFormId))) {
|
||||
fatalError('Invalid review form information!');
|
||||
}
|
||||
|
||||
$reviewFormElementForm = new ReviewFormElementForm($this->reviewFormId, $reviewFormElementId);
|
||||
$reviewFormElementForm->readInputData();
|
||||
|
||||
if ($reviewFormElementForm->validate()) {
|
||||
$reviewFormElementId = $reviewFormElementForm->execute();
|
||||
|
||||
// Create the notification.
|
||||
$notificationMgr = new NotificationManager();
|
||||
$user = $request->getUser();
|
||||
$notificationMgr->createTrivialNotification($user->getId());
|
||||
|
||||
return \PKP\db\DAO::getDataChangedEvent($reviewFormElementId);
|
||||
}
|
||||
|
||||
return new JSONMessage(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a review form element.
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function deleteReviewFormElement($args, $request)
|
||||
{
|
||||
$reviewFormElementId = (int) $request->getUserVar('rowId');
|
||||
|
||||
$context = $request->getContext();
|
||||
$reviewFormDao = DAORegistry::getDAO('ReviewFormDAO'); /** @var ReviewFormDAO $reviewFormDao */
|
||||
|
||||
if ($request->checkCSRF() && $reviewFormDao->unusedReviewFormExists($this->reviewFormId, Application::getContextAssocType(), $context->getId())) {
|
||||
$reviewFormElementDao = DAORegistry::getDAO('ReviewFormElementDAO'); /** @var ReviewFormElementDAO $reviewFormElementDao */
|
||||
$reviewFormElementDao->deleteById($reviewFormElementId);
|
||||
return \PKP\db\DAO::getDataChangedEvent($reviewFormElementId);
|
||||
}
|
||||
|
||||
return new JSONMessage(false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
/**
|
||||
* @file controllers/grid/settings/reviewForms/ReviewFormGridCellProvider.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 ReviewFormGridCellProvider
|
||||
*
|
||||
* @ingroup controllers_grid_settings_reviewForms
|
||||
*
|
||||
* @brief Subclass for review form column's cell provider
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\settings\reviewForms;
|
||||
|
||||
use PKP\controllers\grid\GridCellProvider;
|
||||
use PKP\controllers\grid\GridColumn;
|
||||
use PKP\controllers\grid\GridHandler;
|
||||
use PKP\linkAction\LinkAction;
|
||||
use PKP\linkAction\request\RemoteActionConfirmationModal;
|
||||
use PKP\reviewForm\ReviewForm;
|
||||
|
||||
class ReviewFormGridCellProvider extends GridCellProvider
|
||||
{
|
||||
/**
|
||||
* Extracts variables for a given column from a data element
|
||||
* so that they may be assigned to template before rendering.
|
||||
*
|
||||
* @param \PKP\controllers\grid\GridRow $row
|
||||
* @param GridColumn $column
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getTemplateVarsFromRowColumn($row, $column)
|
||||
{
|
||||
$element = $row->getData();
|
||||
$columnId = $column->getId();
|
||||
assert($element instanceof ReviewForm && !empty($columnId));
|
||||
switch ($columnId) {
|
||||
case 'name':
|
||||
return ['label' => $element->getLocalizedTitle()];
|
||||
case 'inReview':
|
||||
return ['label' => $element->getIncompleteCount()];
|
||||
case 'completed':
|
||||
return ['label' => $element->getCompleteCount()];
|
||||
case 'active':
|
||||
return ['selected' => $element->getActive()];
|
||||
}
|
||||
return parent::getTemplateVarsFromRowColumn($row, $column);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see GridCellProvider::getCellActions()
|
||||
*/
|
||||
public function getCellActions($request, $row, $column, $position = GridHandler::GRID_ACTION_POSITION_DEFAULT)
|
||||
{
|
||||
switch ($column->getId()) {
|
||||
case 'active':
|
||||
/** @var ReviewForm */
|
||||
$element = $row->getData();
|
||||
|
||||
$router = $request->getRouter();
|
||||
|
||||
if ($element->getActive()) {
|
||||
return [new LinkAction(
|
||||
'deactivateReviewForm',
|
||||
new RemoteActionConfirmationModal(
|
||||
$request->getSession(),
|
||||
__('manager.reviewForms.confirmDeactivate'),
|
||||
null,
|
||||
$router->url(
|
||||
$request,
|
||||
null,
|
||||
'grid.settings.reviewForms.ReviewFormGridHandler',
|
||||
'deactivateReviewForm',
|
||||
null,
|
||||
['reviewFormKey' => $element->getId()]
|
||||
)
|
||||
)
|
||||
)];
|
||||
} else {
|
||||
return [new LinkAction(
|
||||
'activateReviewForm',
|
||||
new RemoteActionConfirmationModal(
|
||||
$request->getSession(),
|
||||
__('manager.reviewForms.confirmActivate'),
|
||||
null,
|
||||
$router->url(
|
||||
$request,
|
||||
null,
|
||||
'grid.settings.reviewForms.ReviewFormGridHandler',
|
||||
'activateReviewForm',
|
||||
null,
|
||||
['reviewFormKey' => $element->getId()]
|
||||
)
|
||||
)
|
||||
)];
|
||||
}
|
||||
}
|
||||
return parent::getCellActions($request, $row, $column, $position);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,525 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/settings/reviewForms/ReviewFormGridHandler.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 ReviewFormGridHandler
|
||||
*
|
||||
* @ingroup controllers_grid_settings_reviewForms
|
||||
*
|
||||
* @brief Handle review form grid requests.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\settings\reviewForms;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\notification\NotificationManager;
|
||||
use APP\template\TemplateManager;
|
||||
use PKP\controllers\grid\feature\OrderGridItemsFeature;
|
||||
use PKP\controllers\grid\GridColumn;
|
||||
use PKP\controllers\grid\GridHandler;
|
||||
use PKP\controllers\grid\settings\reviewForms\form\PreviewReviewForm;
|
||||
use PKP\controllers\grid\settings\reviewForms\form\ReviewFormForm;
|
||||
use PKP\core\JSONMessage;
|
||||
use PKP\core\PKPApplication;
|
||||
use PKP\core\PKPRequest;
|
||||
use PKP\db\DAORegistry;
|
||||
use PKP\linkAction\LinkAction;
|
||||
use PKP\linkAction\request\AjaxModal;
|
||||
use PKP\reviewForm\ReviewFormDAO;
|
||||
use PKP\reviewForm\ReviewFormElementDAO;
|
||||
use PKP\security\authorization\PolicySet;
|
||||
use PKP\security\authorization\RoleBasedHandlerOperationPolicy;
|
||||
use PKP\security\Role;
|
||||
use PKP\submission\reviewAssignment\ReviewAssignmentDAO;
|
||||
|
||||
class ReviewFormGridHandler extends GridHandler
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->addRoleAssignment(
|
||||
[Role::ROLE_ID_MANAGER, Role::ROLE_ID_SITE_ADMIN],
|
||||
['fetchGrid', 'fetchRow', 'createReviewForm', 'editReviewForm', 'updateReviewForm',
|
||||
'reviewFormBasics', 'reviewFormElements', 'copyReviewForm',
|
||||
'reviewFormPreview', 'activateReviewForm', 'deactivateReviewForm', 'deleteReviewForm',
|
||||
'saveSequence']
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Implement template methods from PKPHandler.
|
||||
//
|
||||
/**
|
||||
* @copydoc GridHandler::initialize()
|
||||
*
|
||||
* @param null|mixed $args
|
||||
*/
|
||||
public function initialize($request, $args = null)
|
||||
{
|
||||
parent::initialize($request, $args);
|
||||
|
||||
// Basic grid configuration.
|
||||
$this->setTitle('manager.reviewForms');
|
||||
|
||||
// Grid actions.
|
||||
$router = $request->getRouter();
|
||||
|
||||
$this->addAction(
|
||||
new LinkAction(
|
||||
'createReviewForm',
|
||||
new AjaxModal(
|
||||
$router->url($request, null, null, 'createReviewForm', null, null),
|
||||
__('manager.reviewForms.create'),
|
||||
'modal_add_item',
|
||||
true
|
||||
),
|
||||
__('manager.reviewForms.create'),
|
||||
'add_item'
|
||||
)
|
||||
);
|
||||
|
||||
//
|
||||
// Grid columns.
|
||||
//
|
||||
$reviewFormGridCellProvider = new ReviewFormGridCellProvider();
|
||||
|
||||
// Review form name.
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'name',
|
||||
'manager.reviewForms.title',
|
||||
null,
|
||||
null,
|
||||
$reviewFormGridCellProvider
|
||||
)
|
||||
);
|
||||
|
||||
// Review Form 'in review'
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'inReview',
|
||||
'manager.reviewForms.inReview',
|
||||
null,
|
||||
null,
|
||||
$reviewFormGridCellProvider
|
||||
)
|
||||
);
|
||||
|
||||
// Review Form 'completed'.
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'completed',
|
||||
'manager.reviewForms.completed',
|
||||
null,
|
||||
null,
|
||||
$reviewFormGridCellProvider
|
||||
)
|
||||
);
|
||||
|
||||
// Review form 'activate/deactivate'
|
||||
// if ($element->getActive()) {
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'active',
|
||||
'common.active',
|
||||
null,
|
||||
'controllers/grid/common/cell/selectStatusCell.tpl',
|
||||
$reviewFormGridCellProvider
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see 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);
|
||||
}
|
||||
|
||||
//
|
||||
// Implement methods from GridHandler.
|
||||
//
|
||||
/**
|
||||
* @see GridHandler::getRowInstance()
|
||||
*
|
||||
* @return ReviewFormGridRow
|
||||
*/
|
||||
protected function getRowInstance()
|
||||
{
|
||||
return new ReviewFormGridRow();
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::loadData()
|
||||
*
|
||||
* @param null|mixed $filter
|
||||
*/
|
||||
protected function loadData($request, $filter = null)
|
||||
{
|
||||
// Get all review forms.
|
||||
$reviewFormDao = DAORegistry::getDAO('ReviewFormDAO'); /** @var ReviewFormDAO $reviewFormDao */
|
||||
$context = $request->getContext();
|
||||
$reviewForms = $reviewFormDao->getByAssocId(Application::getContextAssocType(), $context->getId());
|
||||
|
||||
return $reviewForms->toAssociativeArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::setDataElementSequence()
|
||||
*/
|
||||
public function setDataElementSequence($request, $rowId, $gridDataElement, $newSequence)
|
||||
{
|
||||
$reviewFormDao = DAORegistry::getDAO('ReviewFormDAO'); /** @var ReviewFormDAO $reviewFormDao */
|
||||
$gridDataElement->setSequence($newSequence);
|
||||
$reviewFormDao->updateObject($gridDataElement);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see lib/pkp/classes/controllers/grid/GridHandler::getDataElementSequence()
|
||||
*/
|
||||
public function getDataElementSequence($reviewForm)
|
||||
{
|
||||
return $reviewForm->getSequence();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see GridHandler::addFeatures()
|
||||
*/
|
||||
public function initFeatures($request, $args)
|
||||
{
|
||||
return [new OrderGridItemsFeature()];
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Public grid actions.
|
||||
//
|
||||
/**
|
||||
* Preview a review form.
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function reviewFormPreview($args, $request)
|
||||
{
|
||||
// Identify the review form ID.
|
||||
$reviewFormId = (int) $request->getUserVar('reviewFormId');
|
||||
|
||||
// Identify the context id.
|
||||
$context = $request->getContext();
|
||||
|
||||
// Get review form object
|
||||
$reviewFormDao = DAORegistry::getDAO('ReviewFormDAO'); /** @var ReviewFormDAO $reviewFormDao */
|
||||
$reviewForm = $reviewFormDao->getById($reviewFormId, Application::getContextAssocType(), $context->getId());
|
||||
|
||||
$previewReviewForm = new PreviewReviewForm($reviewFormId);
|
||||
$previewReviewForm->initData();
|
||||
return new JSONMessage(true, $previewReviewForm->fetch($request));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new review form.
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function createReviewForm($args, $request)
|
||||
{
|
||||
// Form handling.
|
||||
$reviewFormForm = new ReviewFormForm(null);
|
||||
$reviewFormForm->initData();
|
||||
return new JSONMessage(true, $reviewFormForm->fetch($request));
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit an existing review form.
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function editReviewForm($args, $request)
|
||||
{
|
||||
$reviewFormDao = DAORegistry::getDAO('ReviewFormDAO'); /** @var ReviewFormDAO $reviewFormDao */
|
||||
$context = $request->getContext();
|
||||
$reviewForm = $reviewFormDao->getById(
|
||||
$request->getUserVar('rowId'),
|
||||
Application::getContextAssocType(),
|
||||
$context->getId()
|
||||
);
|
||||
|
||||
// Display 'editReviewForm' tabs
|
||||
$templateMgr = TemplateManager::getManager($request);
|
||||
$templateMgr->assign([
|
||||
'preview' => $request->getUserVar('preview'),
|
||||
'reviewFormId' => $reviewForm->getId(),
|
||||
'canEdit' => $reviewForm->getIncompleteCount() == 0 && $reviewForm->getCompleteCount() == 0,
|
||||
]);
|
||||
return new JSONMessage(true, $templateMgr->fetch('controllers/grid/settings/reviewForms/editReviewForm.tpl'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit an existing review form's basics (title, description)
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function reviewFormBasics($args, $request)
|
||||
{
|
||||
// Identify the review form Id
|
||||
$reviewFormId = (int) $request->getUserVar('reviewFormId');
|
||||
|
||||
// Form handling
|
||||
$reviewFormForm = new ReviewFormForm($reviewFormId);
|
||||
$reviewFormForm->initData();
|
||||
return new JSONMessage(true, $reviewFormForm->fetch($request));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Display a list of the review form elements within a review form.
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function reviewFormElements($args, $request)
|
||||
{
|
||||
$templateMgr = TemplateManager::getManager($request);
|
||||
$dispatcher = $request->getDispatcher();
|
||||
return $templateMgr->fetchAjax(
|
||||
'reviewFormElementsGridContainer',
|
||||
$dispatcher->url(
|
||||
$request,
|
||||
PKPApplication::ROUTE_COMPONENT,
|
||||
null,
|
||||
'grid.settings.reviewForms.ReviewFormElementsGridHandler',
|
||||
'fetchGrid',
|
||||
null,
|
||||
['reviewFormId' => (int) $request->getUserVar('reviewFormId')]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update an existing review form.
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return JSONMessage JSON message
|
||||
*/
|
||||
public function updateReviewForm($args, $request)
|
||||
{
|
||||
// Identify the review form Id.
|
||||
$reviewFormId = (int) $request->getUserVar('reviewFormId');
|
||||
|
||||
// Identify the context id.
|
||||
$context = $request->getContext();
|
||||
|
||||
// Get review form object
|
||||
$reviewFormDao = DAORegistry::getDAO('ReviewFormDAO'); /** @var ReviewFormDAO $reviewFormDao */
|
||||
$reviewForm = $reviewFormDao->getById($reviewFormId, Application::getContextAssocType(), $context->getId());
|
||||
|
||||
// Form handling.
|
||||
$reviewFormForm = new ReviewFormForm(!isset($reviewFormId) || empty($reviewFormId) ? null : $reviewFormId);
|
||||
$reviewFormForm->readInputData();
|
||||
|
||||
if ($reviewFormForm->validate()) {
|
||||
$reviewFormForm->execute();
|
||||
|
||||
// Create the notification.
|
||||
$notificationMgr = new NotificationManager();
|
||||
$user = $request->getUser();
|
||||
$notificationMgr->createTrivialNotification($user->getId());
|
||||
|
||||
return \PKP\db\DAO::getDataChangedEvent($reviewFormId);
|
||||
}
|
||||
|
||||
return new JSONMessage(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy a review form.
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function copyReviewForm($args, $request)
|
||||
{
|
||||
// Identify the current review form
|
||||
$reviewFormId = (int) $request->getUserVar('rowId');
|
||||
|
||||
// Identify the context id.
|
||||
$context = $request->getContext();
|
||||
|
||||
// Get review form object
|
||||
$reviewFormDao = DAORegistry::getDAO('ReviewFormDAO'); /** @var ReviewFormDAO $reviewFormDao */
|
||||
$reviewForm = $reviewFormDao->getById($reviewFormId, Application::getContextAssocType(), $context->getId());
|
||||
|
||||
if ($request->checkCSRF() && isset($reviewForm)) {
|
||||
$reviewForm->setActive(0);
|
||||
$reviewForm->setSequence(REALLY_BIG_NUMBER);
|
||||
$newReviewFormId = $reviewFormDao->insertObject($reviewForm);
|
||||
$reviewFormDao->resequenceReviewForms(Application::getContextAssocType(), $context->getId());
|
||||
|
||||
$reviewFormElementDao = DAORegistry::getDAO('ReviewFormElementDAO'); /** @var ReviewFormElementDAO $reviewFormElementDao */
|
||||
$reviewFormElements = $reviewFormElementDao->getByReviewFormId($reviewFormId);
|
||||
while ($reviewFormElement = $reviewFormElements->next()) {
|
||||
$reviewFormElement->setReviewFormId($newReviewFormId);
|
||||
$reviewFormElement->setSequence(REALLY_BIG_NUMBER);
|
||||
$reviewFormElementDao->insertObject($reviewFormElement);
|
||||
$reviewFormElementDao->resequenceReviewFormElements($newReviewFormId);
|
||||
}
|
||||
|
||||
// Create the notification.
|
||||
$notificationMgr = new NotificationManager();
|
||||
$user = $request->getUser();
|
||||
$notificationMgr->createTrivialNotification($user->getId());
|
||||
|
||||
return \PKP\db\DAO::getDataChangedEvent($newReviewFormId);
|
||||
}
|
||||
|
||||
return new JSONMessage(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Activate a review form.
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function activateReviewForm($args, $request)
|
||||
{
|
||||
// Identify the current review form
|
||||
$reviewFormId = (int) $request->getUserVar('reviewFormKey');
|
||||
|
||||
// Identify the context id.
|
||||
$context = $request->getContext();
|
||||
|
||||
// Get review form object
|
||||
$reviewFormDao = DAORegistry::getDAO('ReviewFormDAO'); /** @var ReviewFormDAO $reviewFormDao */
|
||||
$reviewForm = $reviewFormDao->getById($reviewFormId, Application::getContextAssocType(), $context->getId());
|
||||
|
||||
if ($request->checkCSRF() && isset($reviewForm) && !$reviewForm->getActive()) {
|
||||
$reviewForm->setActive(1);
|
||||
$reviewFormDao->updateObject($reviewForm);
|
||||
|
||||
// Create the notification.
|
||||
$notificationMgr = new NotificationManager();
|
||||
$user = $request->getUser();
|
||||
$notificationMgr->createTrivialNotification($user->getId());
|
||||
|
||||
return \PKP\db\DAO::getDataChangedEvent($reviewFormId);
|
||||
}
|
||||
|
||||
return new JSONMessage(false);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Deactivate a review form.
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function deactivateReviewForm($args, $request)
|
||||
{
|
||||
// Identify the current review form
|
||||
$reviewFormId = (int) $request->getUserVar('reviewFormKey');
|
||||
|
||||
// Identify the context id.
|
||||
$context = $request->getContext();
|
||||
|
||||
// Get review form object
|
||||
$reviewFormDao = DAORegistry::getDAO('ReviewFormDAO'); /** @var ReviewFormDAO $reviewFormDao */
|
||||
$reviewForm = $reviewFormDao->getById($reviewFormId, Application::getContextAssocType(), $context->getId());
|
||||
|
||||
if ($request->checkCSRF() && isset($reviewForm) && $reviewForm->getActive()) {
|
||||
$reviewForm->setActive(0);
|
||||
$reviewFormDao->updateObject($reviewForm);
|
||||
|
||||
// Create the notification.
|
||||
$notificationMgr = new NotificationManager();
|
||||
$user = $request->getUser();
|
||||
$notificationMgr->createTrivialNotification($user->getId());
|
||||
|
||||
return \PKP\db\DAO::getDataChangedEvent($reviewFormId);
|
||||
}
|
||||
|
||||
return new JSONMessage(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a review form.
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function deleteReviewForm($args, $request)
|
||||
{
|
||||
// Identify the current review form
|
||||
$reviewFormId = (int) $request->getUserVar('rowId');
|
||||
|
||||
// Identify the context id.
|
||||
$context = $request->getContext();
|
||||
|
||||
// Get review form object
|
||||
$reviewFormDao = DAORegistry::getDAO('ReviewFormDAO'); /** @var ReviewFormDAO $reviewFormDao */
|
||||
$reviewForm = $reviewFormDao->getById($reviewFormId, Application::getContextAssocType(), $context->getId());
|
||||
|
||||
if ($request->checkCSRF() && isset($reviewForm) && $reviewForm->getCompleteCount() == 0 && $reviewForm->getIncompleteCount() == 0) {
|
||||
$reviewAssignmentDao = DAORegistry::getDAO('ReviewAssignmentDAO'); /** @var ReviewAssignmentDAO $reviewAssignmentDao */
|
||||
$reviewAssignments = $reviewAssignmentDao->getByReviewFormId($reviewFormId);
|
||||
|
||||
foreach ($reviewAssignments as $reviewAssignment) {
|
||||
$reviewAssignment->setReviewFormId(null);
|
||||
$reviewAssignmentDao->updateObject($reviewAssignment);
|
||||
}
|
||||
|
||||
$reviewFormDao->deleteById($reviewFormId);
|
||||
|
||||
// Create the notification.
|
||||
$notificationMgr = new NotificationManager();
|
||||
$user = $request->getUser();
|
||||
$notificationMgr->createTrivialNotification($user->getId());
|
||||
|
||||
return \PKP\db\DAO::getDataChangedEvent($reviewFormId);
|
||||
}
|
||||
|
||||
return new JSONMessage(false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/settings/reviewForms/ReviewFormGridRow.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 ReviewFormGridRow
|
||||
*
|
||||
* @ingroup controllers_grid_settings_reviewForms
|
||||
*
|
||||
* @brief ReviewForm grid row definition
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\settings\reviewForms;
|
||||
|
||||
use PKP\controllers\grid\GridRow;
|
||||
use PKP\linkAction\LinkAction;
|
||||
use PKP\linkAction\request\AjaxModal;
|
||||
use PKP\linkAction\request\RemoteActionConfirmationModal;
|
||||
|
||||
class ReviewFormGridRow extends GridRow
|
||||
{
|
||||
//
|
||||
// Overridden methods from GridRow
|
||||
//
|
||||
/**
|
||||
* @copydoc GridRow::initialize()
|
||||
*
|
||||
* @param null|mixed $template
|
||||
*/
|
||||
public function initialize($request, $template = null)
|
||||
{
|
||||
parent::initialize($request, $template);
|
||||
|
||||
// Is this a new row or an existing row?
|
||||
$element = $this->getData();
|
||||
assert($element instanceof \PKP\reviewForm\ReviewForm);
|
||||
|
||||
$rowId = $this->getId();
|
||||
|
||||
if (!empty($rowId) && is_numeric($rowId)) {
|
||||
// Only add row actions if this is an existing row
|
||||
$router = $request->getRouter();
|
||||
|
||||
// determine whether or not this Review Form is editable.
|
||||
$canEdit = ($element->getIncompleteCount() == 0 && $element->getCompleteCount() == 0);
|
||||
|
||||
// if review form is editable, add 'edit' grid row action
|
||||
if ($canEdit) {
|
||||
$this->addAction(
|
||||
new LinkAction(
|
||||
'edit',
|
||||
new AjaxModal(
|
||||
$router->url($request, null, null, 'editReviewForm', null, ['rowId' => $rowId]),
|
||||
__('grid.action.edit'),
|
||||
'modal_edit',
|
||||
true
|
||||
),
|
||||
__('grid.action.edit'),
|
||||
'edit'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// if review form is not editable, add 'copy' grid row action
|
||||
$this->addAction(
|
||||
new LinkAction(
|
||||
'copy',
|
||||
new RemoteActionConfirmationModal(
|
||||
$request->getSession(),
|
||||
__('manager.reviewForms.confirmCopy'),
|
||||
null,
|
||||
$router->url($request, null, null, 'copyReviewForm', null, ['rowId' => $rowId])
|
||||
),
|
||||
__('grid.action.copy'),
|
||||
'copy'
|
||||
)
|
||||
);
|
||||
|
||||
// add 'preview' grid row action
|
||||
$this->addAction(
|
||||
new LinkAction(
|
||||
'preview',
|
||||
new AjaxModal(
|
||||
$router->url($request, null, null, 'editReviewForm', null, ['rowId' => $rowId, 'preview' => 1]),
|
||||
__('grid.action.preview'),
|
||||
'preview',
|
||||
true
|
||||
),
|
||||
__('grid.action.preview'),
|
||||
'preview'
|
||||
)
|
||||
);
|
||||
|
||||
// if review form is editable, add 'delete' grid row action.
|
||||
if ($canEdit) {
|
||||
$this->addAction(
|
||||
new LinkAction(
|
||||
'delete',
|
||||
new RemoteActionConfirmationModal(
|
||||
$request->getSession(),
|
||||
__('manager.reviewForms.confirmDelete'),
|
||||
null,
|
||||
$router->url($request, null, null, 'deleteReviewForm', null, ['rowId' => $rowId])
|
||||
),
|
||||
__('grid.action.delete'),
|
||||
'delete'
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
/**
|
||||
* @file controllers/grid/settings/reviewForms/form/PKPPreviewReviewForm.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 PreviewReviewForm
|
||||
*
|
||||
* @ingroup controllers_grid_settings_reviewForms_form
|
||||
*
|
||||
* @brief Form for manager to preview review form.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\settings\reviewForms\form;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\template\TemplateManager;
|
||||
use PKP\core\JSONMessage;
|
||||
use PKP\db\DAORegistry;
|
||||
use PKP\form\Form;
|
||||
use PKP\reviewForm\ReviewForm;
|
||||
use PKP\reviewForm\ReviewFormDAO;
|
||||
use PKP\reviewForm\ReviewFormElementDAO;
|
||||
use PKP\security\Validation;
|
||||
|
||||
class PreviewReviewForm extends Form
|
||||
{
|
||||
/** @var int The ID of the review form being edited */
|
||||
public $reviewFormId;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param int $reviewFormId omit for a new review form
|
||||
*/
|
||||
public function __construct($reviewFormId = null)
|
||||
{
|
||||
parent::__construct('manager/reviewForms/previewReviewForm.tpl');
|
||||
|
||||
$this->reviewFormId = (int) $reviewFormId;
|
||||
|
||||
// Validation checks for this form
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorPost($this));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorCSRF($this));
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::fetch
|
||||
*
|
||||
* @param null|mixed $template
|
||||
*/
|
||||
public function fetch($request, $template = null, $display = false)
|
||||
{
|
||||
$json = new JSONMessage();
|
||||
|
||||
$templateMgr = TemplateManager::getManager($request);
|
||||
$templateMgr->assign('reviewFormId', $this->reviewFormId);
|
||||
|
||||
return parent::fetch($request, $template, $display);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize form data from current settings.
|
||||
*/
|
||||
public function initData()
|
||||
{
|
||||
if ($this->reviewFormId) {
|
||||
// Get review form
|
||||
$request = Application::get()->getRequest();
|
||||
$context = $request->getContext();
|
||||
$reviewFormDao = DAORegistry::getDAO('ReviewFormDAO'); /** @var ReviewFormDAO $reviewFormDao */
|
||||
$reviewForm = $reviewFormDao->getById($this->reviewFormId, Application::getContextAssocType(), $context->getId()); /** @var ReviewForm $reviewForm */
|
||||
|
||||
// Get review form elements
|
||||
$reviewFormElementDao = DAORegistry::getDAO('ReviewFormElementDAO'); /** @var ReviewFormElementDAO $reviewFormElementDao */
|
||||
$reviewFormElements = $reviewFormElementDao->getByReviewFormId($this->reviewFormId);
|
||||
|
||||
// Set data
|
||||
$this->setData('title', $reviewForm->getLocalizedTitle());
|
||||
$this->setData('description', $reviewForm->getLocalizedDescription());
|
||||
$this->setData('reviewFormElements', $reviewFormElements);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,214 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/settings/reviewForms/form/ReviewFormElementForm.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 ReviewFormElementForm
|
||||
*
|
||||
* @ingroup controllers_grid_settings_reviewForms_form
|
||||
*
|
||||
* @see ReviewFormElement
|
||||
*
|
||||
* @brief Form for creating and modifying review form elements.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\settings\reviewForms\form;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\template\TemplateManager;
|
||||
use PKP\controllers\listbuilder\ListbuilderHandler;
|
||||
use PKP\db\DAORegistry;
|
||||
use PKP\form\Form;
|
||||
use PKP\reviewForm\ReviewFormDAO;
|
||||
use PKP\reviewForm\ReviewFormElement;
|
||||
use PKP\reviewForm\ReviewFormElementDAO;
|
||||
use PKP\security\Validation;
|
||||
|
||||
class ReviewFormElementForm extends Form
|
||||
{
|
||||
/** @var int $reviewFormId The ID of the review form being edited */
|
||||
public $reviewFormId;
|
||||
|
||||
/** @var int $reviewFormElementId The ID of the review form element being edited */
|
||||
public $reviewFormElementId;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param int $reviewFormId
|
||||
* @param int $reviewFormElementId
|
||||
*/
|
||||
public function __construct($reviewFormId, $reviewFormElementId = null)
|
||||
{
|
||||
parent::__construct('manager/reviewForms/reviewFormElementForm.tpl');
|
||||
|
||||
$this->reviewFormId = $reviewFormId;
|
||||
$this->reviewFormElementId = $reviewFormElementId;
|
||||
|
||||
// Validation checks for this form
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorLocale($this, 'question', 'required', 'manager.reviewFormElements.form.questionRequired'));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidator($this, 'elementType', 'required', 'manager.reviewFormElements.form.elementTypeRequired'));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorPost($this));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorCSRF($this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the names of fields for which localized data is allowed.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getLocaleFieldNames()
|
||||
{
|
||||
$reviewFormElementDao = DAORegistry::getDAO('ReviewFormElementDAO'); /** @var ReviewFormElementDAO $reviewFormElementDao */
|
||||
return $reviewFormElementDao->getLocaleFieldNames();
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::fetch
|
||||
*
|
||||
* @param null|mixed $template
|
||||
*/
|
||||
public function fetch($request, $template = null, $display = false)
|
||||
{
|
||||
$templateMgr = TemplateManager::getManager($request);
|
||||
$reviewFormElement = new ReviewFormElement();
|
||||
$templateMgr->assign([
|
||||
'reviewFormId' => $this->reviewFormId,
|
||||
'reviewFormElementId' => $this->reviewFormElementId,
|
||||
'multipleResponsesElementTypes' => $reviewFormElement->getMultipleResponsesElementTypes(),
|
||||
'multipleResponsesElementTypesString' => ';' . implode(';', $reviewFormElement->getMultipleResponsesElementTypes()) . ';',
|
||||
'reviewFormElementTypeOptions' => $reviewFormElement->getReviewFormElementTypeOptions(),
|
||||
]);
|
||||
return parent::fetch($request, $template, $display);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize form data from current review form.
|
||||
*/
|
||||
public function initData()
|
||||
{
|
||||
if ($this->reviewFormElementId) {
|
||||
$request = Application::get()->getRequest();
|
||||
$context = $request->getContext();
|
||||
$reviewFormElementDao = DAORegistry::getDAO('ReviewFormElementDAO'); /** @var ReviewFormElementDAO $reviewFormElementDao */
|
||||
$reviewFormElement = $reviewFormElementDao->getById($this->reviewFormElementId, $this->reviewFormId);
|
||||
$this->_data = [
|
||||
'question' => $reviewFormElement->getQuestion(null), // Localized
|
||||
'description' => $reviewFormElement->getDescription(null), // Localized
|
||||
'required' => $reviewFormElement->getRequired(),
|
||||
'included' => $reviewFormElement->getIncluded(),
|
||||
|
||||
'elementType' => $reviewFormElement->getElementType(),
|
||||
'possibleResponses' => $reviewFormElement->getPossibleResponses(null) //Localized
|
||||
];
|
||||
} else {
|
||||
$this->_data = [
|
||||
'included' => 1
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign form data to user-submitted data.
|
||||
*/
|
||||
public function readInputData()
|
||||
{
|
||||
$this->readUserVars(['question', 'description', 'required', 'included', 'elementType', 'possibleResponses']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::execute()
|
||||
*
|
||||
* @return int Review form element ID
|
||||
*/
|
||||
public function execute(...$functionArgs)
|
||||
{
|
||||
$reviewFormElementDao = DAORegistry::getDAO('ReviewFormElementDAO'); /** @var ReviewFormElementDAO $reviewFormElementDao */
|
||||
$request = Application::get()->getRequest();
|
||||
|
||||
if ($this->reviewFormElementId) {
|
||||
$context = $request->getContext();
|
||||
$reviewFormElement = $reviewFormElementDao->getById($this->reviewFormElementId);
|
||||
$reviewFormDao = DAORegistry::getDAO('ReviewFormDAO'); /** @var ReviewFormDAO $reviewFormDao */
|
||||
$reviewForm = $reviewFormDao->getById($reviewFormElement->getReviewFormId(), Application::getContextAssocType(), $context->getId());
|
||||
if (!$reviewForm) {
|
||||
fatalError('Invalid review form element ID!');
|
||||
}
|
||||
} else {
|
||||
$reviewFormElement = $reviewFormElementDao->newDataObject();
|
||||
$reviewFormElement->setReviewFormId($this->reviewFormId);
|
||||
$reviewFormElement->setSequence(REALLY_BIG_NUMBER);
|
||||
}
|
||||
|
||||
$reviewFormElement->setQuestion($this->getData('question'), null); // Localized
|
||||
$reviewFormElement->setDescription($this->getData('description'), null); // Localized
|
||||
$reviewFormElement->setRequired($this->getData('required') ? 1 : 0);
|
||||
$reviewFormElement->setIncluded($this->getData('included') ? 1 : 0);
|
||||
$reviewFormElement->setElementType($this->getData('elementType'));
|
||||
|
||||
if (in_array($this->getData('elementType'), $reviewFormElement->getMultipleResponsesElementTypes())) {
|
||||
$this->setData('possibleResponsesProcessed', $reviewFormElement->getPossibleResponses(null));
|
||||
ListbuilderHandler::unpack($request, $this->getData('possibleResponses'), [$this, 'deleteEntry'], [$this, 'insertEntry'], [$this, 'updateEntry']);
|
||||
$reviewFormElement->setPossibleResponses($this->getData('possibleResponsesProcessed'), null);
|
||||
} else {
|
||||
$reviewFormElement->setPossibleResponses(null, null);
|
||||
}
|
||||
if ($reviewFormElement->getId()) {
|
||||
$reviewFormElementDao->deleteSetting($reviewFormElement->getId(), 'possibleResponses');
|
||||
$reviewFormElementDao->updateObject($reviewFormElement);
|
||||
} else {
|
||||
$this->reviewFormElementId = $reviewFormElementDao->insertObject($reviewFormElement);
|
||||
$reviewFormElementDao->resequenceReviewFormElements($this->reviewFormId);
|
||||
}
|
||||
parent::execute(...$functionArgs);
|
||||
return $this->reviewFormElementId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc ListbuilderHandler::insertEntry()
|
||||
*/
|
||||
public function insertEntry($request, $newRowId)
|
||||
{
|
||||
$possibleResponsesProcessed = (array) $this->getData('possibleResponsesProcessed');
|
||||
foreach ($newRowId['possibleResponse'] as $key => $value) {
|
||||
$possibleResponsesProcessed[$key][] = $value;
|
||||
}
|
||||
$this->setData('possibleResponsesProcessed', $possibleResponsesProcessed);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc ListbuilderHandler::deleteEntry()
|
||||
*/
|
||||
public function deleteEntry($request, $rowId)
|
||||
{
|
||||
$possibleResponsesProcessed = (array) $this->getData('possibleResponsesProcessed');
|
||||
foreach (array_keys($possibleResponsesProcessed) as $locale) {
|
||||
// WARNING: Listbuilders don't like zero row IDs. They are offset
|
||||
// by 1 to avoid this case, so 1 is subtracted here to normalize.
|
||||
unset($possibleResponsesProcessed[$locale][$rowId - 1]);
|
||||
}
|
||||
$this->setData('possibleResponsesProcessed', $possibleResponsesProcessed);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc ListbuilderHandler::updateEntry
|
||||
*/
|
||||
public function updateEntry($request, $rowId, $newRowId)
|
||||
{
|
||||
$possibleResponsesProcessed = (array) $this->getData('possibleResponsesProcessed');
|
||||
foreach ($newRowId['possibleResponse'] as $locale => $value) {
|
||||
// WARNING: Listbuilders don't like zero row IDs. They are offset
|
||||
// by 1 to avoid this case, so 1 is subtracted here to normalize.
|
||||
$possibleResponsesProcessed[$locale][$rowId - 1] = $value;
|
||||
}
|
||||
$this->setData('possibleResponsesProcessed', $possibleResponsesProcessed);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
/**
|
||||
* @file controllers/grid/settings/reviewForms/form/ReviewFormElements.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 ReviewFormElements
|
||||
*
|
||||
* @ingroup controllers_grid_settings_reviewForms_form
|
||||
*
|
||||
* @brief Form for manager to edit review form elements.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\settings\reviewForms\form;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\template\TemplateManager;
|
||||
use PKP\core\JSONMessage;
|
||||
use PKP\db\DAORegistry;
|
||||
use PKP\form\Form;
|
||||
use PKP\reviewForm\ReviewFormDAO;
|
||||
use PKP\reviewForm\ReviewFormElementDAO;
|
||||
use PKP\security\Validation;
|
||||
|
||||
class ReviewFormElements extends Form
|
||||
{
|
||||
/** @var int The ID of the review form being edited */
|
||||
public $reviewFormId;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param int $reviewFormId
|
||||
*/
|
||||
public function __construct($reviewFormId)
|
||||
{
|
||||
parent::__construct('manager/reviewForms/reviewFormElements.tpl');
|
||||
|
||||
$this->reviewFormId = (int) $reviewFormId;
|
||||
|
||||
// Validation checks for this form
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorPost($this));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorCSRF($this));
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::fetch
|
||||
*
|
||||
* @param null|mixed $template
|
||||
*/
|
||||
public function fetch($request, $template = null, $display = false)
|
||||
{
|
||||
$json = new JSONMessage();
|
||||
|
||||
$templateMgr = TemplateManager::getManager($request);
|
||||
$templateMgr->assign('reviewFormId', $this->reviewFormId);
|
||||
|
||||
return parent::fetch($request, $template, $display);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize form data from current settings.
|
||||
*/
|
||||
public function initData()
|
||||
{
|
||||
if (isset($this->reviewFormId)) {
|
||||
// Get review form
|
||||
$reviewFormDao = DAORegistry::getDAO('ReviewFormDAO'); /** @var ReviewFormDAO $reviewFormDao */
|
||||
$reviewForm = $reviewFormDao->getById($this->reviewFormId, Application::getContextAssocType(), Application::get()->getRequest()->getContext()->getId());
|
||||
|
||||
// Get review form elements
|
||||
$reviewFormElementDao = DAORegistry::getDAO('ReviewFormElementDAO'); /** @var ReviewFormElementDAO $reviewFormElementDao */
|
||||
$reviewFormElements = $reviewFormElementDao->getByReviewFormId($this->reviewFormId, null);
|
||||
|
||||
// Set data
|
||||
$this->setData('reviewFormId', $this->reviewFormId);
|
||||
$this->setData('reviewFormElements', $reviewFormElements);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/settings/reviewForms/form/ReviewFormForm.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 ReviewFormForm
|
||||
*
|
||||
* @ingroup controllers_grid_settings_reviewForms_form
|
||||
*
|
||||
* @brief Form for manager to edit a review form.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\settings\reviewForms\form;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\template\TemplateManager;
|
||||
use PKP\core\JSONMessage;
|
||||
use PKP\db\DAORegistry;
|
||||
use PKP\form\Form;
|
||||
use PKP\reviewForm\ReviewFormDAO;
|
||||
|
||||
class ReviewFormForm extends Form
|
||||
{
|
||||
/** @var int The ID of the review form being edited, if any */
|
||||
public $reviewFormId;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param int $reviewFormId omit for a new review form
|
||||
*/
|
||||
public function __construct($reviewFormId = null)
|
||||
{
|
||||
parent::__construct('manager/reviewForms/reviewFormForm.tpl');
|
||||
$this->reviewFormId = $reviewFormId ? (int) $reviewFormId : null;
|
||||
|
||||
// Validation checks for this form
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorLocale($this, 'title', 'required', 'manager.reviewForms.form.titleRequired'));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorPost($this));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorCSRF($this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign form data to user-submitted data.
|
||||
*/
|
||||
public function readInputData()
|
||||
{
|
||||
$this->readUserVars(['title', 'description']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize form data from current settings.
|
||||
*/
|
||||
public function initData()
|
||||
{
|
||||
if ($this->reviewFormId) {
|
||||
$request = Application::get()->getRequest();
|
||||
$context = $request->getContext();
|
||||
$reviewFormDao = DAORegistry::getDAO('ReviewFormDAO'); /** @var ReviewFormDAO $reviewFormDao */
|
||||
$reviewForm = $reviewFormDao->getById($this->reviewFormId, Application::getContextAssocType(), $context->getId());
|
||||
|
||||
$this->setData('title', $reviewForm->getTitle(null));
|
||||
$this->setData('description', $reviewForm->getDescription(null));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::fetch
|
||||
*
|
||||
* @param null|mixed $template
|
||||
*/
|
||||
public function fetch($request, $template = null, $display = false)
|
||||
{
|
||||
$json = new JSONMessage();
|
||||
|
||||
$templateMgr = TemplateManager::getManager($request);
|
||||
$templateMgr->assign('reviewFormId', $this->reviewFormId);
|
||||
|
||||
return parent::fetch($request, $template, $display);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::execute()
|
||||
*/
|
||||
public function execute(...$functionArgs)
|
||||
{
|
||||
$request = Application::get()->getRequest();
|
||||
$context = $request->getContext();
|
||||
$reviewFormDao = DAORegistry::getDAO('ReviewFormDAO'); /** @var ReviewFormDAO $reviewFormDao */
|
||||
|
||||
if ($this->reviewFormId) {
|
||||
$reviewForm = $reviewFormDao->getById($this->reviewFormId, Application::getContextAssocType(), $context->getId());
|
||||
} else {
|
||||
$reviewForm = $reviewFormDao->newDataObject();
|
||||
$reviewForm->setAssocType(Application::getContextAssocType());
|
||||
$reviewForm->setAssocId($context->getId());
|
||||
$reviewForm->setActive(0);
|
||||
$reviewForm->setSequence(REALLY_BIG_NUMBER);
|
||||
}
|
||||
|
||||
$reviewForm->setTitle($this->getData('title'), null); // Localized
|
||||
$reviewForm->setDescription($this->getData('description'), null); // Localized
|
||||
|
||||
if ($this->reviewFormId) {
|
||||
$reviewFormDao->updateObject($reviewForm);
|
||||
$this->reviewFormId = $reviewForm->getId();
|
||||
} else {
|
||||
$this->reviewFormId = $reviewFormDao->insertObject($reviewForm);
|
||||
$reviewFormDao->resequenceReviewForms(Application::getContextAssocType(), $context->getId());
|
||||
}
|
||||
parent::execute(...$functionArgs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of field names for which localized settings are used
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getLocaleFieldNames()
|
||||
{
|
||||
$reviewFormDao = DAORegistry::getDAO('ReviewFormDAO'); /** @var ReviewFormDAO $reviewFormDao */
|
||||
return $reviewFormDao->getLocaleFieldNames();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/settings/roles/UserGroupGridCellProvider.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 UserGroupGridCellProvider
|
||||
*
|
||||
* @ingroup controllers_grid_settings_roles
|
||||
*
|
||||
* @brief Cell provider for columns in a user group grid.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\settings\roles;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\facades\Repo;
|
||||
use PKP\controllers\grid\GridCellProvider;
|
||||
use PKP\controllers\grid\GridColumn;
|
||||
use PKP\controllers\grid\GridHandler;
|
||||
use PKP\db\DAORegistry;
|
||||
use PKP\linkAction\LinkAction;
|
||||
use PKP\linkAction\request\AjaxAction;
|
||||
use PKP\security\RoleDAO;
|
||||
use PKP\userGroup\UserGroup;
|
||||
|
||||
class UserGroupGridCellProvider 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)
|
||||
{
|
||||
$userGroup = $row->getData(); /** @var UserGroup $userGroup */
|
||||
$columnId = $column->getId();
|
||||
$workflowStages = Application::getApplicationStages();
|
||||
$roleDao = DAORegistry::getDAO('RoleDAO'); /** @var RoleDAO $roleDao */
|
||||
|
||||
$assignedStages = Repo::userGroup()->getAssignedStagesByUserGroupId($userGroup->getContextId(), $userGroup->getId())->toArray();
|
||||
|
||||
switch ($columnId) {
|
||||
case 'name':
|
||||
return ['label' => $userGroup->getLocalizedName()];
|
||||
case 'roleId':
|
||||
$roleNames = Application::getRoleNames(false, [$userGroup->getRoleId()]);
|
||||
return ['label' => __(array_shift($roleNames))];
|
||||
case in_array($columnId, $workflowStages):
|
||||
// Set the state of the select element that will
|
||||
// be used to assign the stage to the user group.
|
||||
$selectDisabled = false;
|
||||
if (in_array($columnId, $roleDao->getForbiddenStages($userGroup->getRoleId()))) {
|
||||
// This stage should not be assigned to the user group.
|
||||
$selectDisabled = true;
|
||||
}
|
||||
|
||||
return ['selected' => in_array($columnId, $assignedStages),
|
||||
'disabled' => $selectDisabled];
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return parent::getTemplateVarsFromRowColumn($row, $column);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridCellProvider::getCellActions()
|
||||
*/
|
||||
public function getCellActions($request, $row, $column, $position = GridHandler::GRID_ACTION_POSITION_DEFAULT)
|
||||
{
|
||||
$workflowStages = Application::getApplicationStages();
|
||||
$columnId = $column->getId();
|
||||
|
||||
if (in_array($columnId, $workflowStages)) {
|
||||
$userGroup = $row->getData(); /** @var UserGroup $userGroup */
|
||||
|
||||
$assignedStages = Repo::userGroup()->getAssignedStagesByUserGroupId($userGroup->getContextId(), $userGroup->getId())->toArray();
|
||||
|
||||
$router = $request->getRouter();
|
||||
$roleDao = DAORegistry::getDAO('RoleDAO'); /** @var RoleDAO $roleDao */
|
||||
|
||||
if (!in_array($columnId, $roleDao->getForbiddenStages($userGroup->getRoleId()))) {
|
||||
if (in_array($columnId, $assignedStages)) {
|
||||
$operation = 'unassignStage';
|
||||
$actionTitleKey = 'grid.userGroup.unassignStage';
|
||||
} else {
|
||||
$operation = 'assignStage';
|
||||
$actionTitleKey = 'grid.userGroup.assignStage';
|
||||
}
|
||||
$actionArgs = array_merge(
|
||||
['stageId' => $columnId],
|
||||
$row->getRequestArgs()
|
||||
);
|
||||
|
||||
$actionUrl = $router->url($request, null, null, $operation, null, $actionArgs);
|
||||
$actionRequest = new AjaxAction($actionUrl);
|
||||
|
||||
$linkAction = new LinkAction(
|
||||
$operation,
|
||||
$actionRequest,
|
||||
__($actionTitleKey),
|
||||
null
|
||||
);
|
||||
|
||||
return [$linkAction];
|
||||
}
|
||||
}
|
||||
|
||||
return parent::getCellActions($request, $row, $column, $position);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,499 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/settings/roles/UserGroupGridHandler.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 UserGroupGridHandler
|
||||
*
|
||||
* @ingroup controllers_grid_settings
|
||||
*
|
||||
* @brief Handle operations for user group management operations.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\settings\roles;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\core\Request;
|
||||
use APP\facades\Repo;
|
||||
use APP\notification\NotificationManager;
|
||||
use PKP\controllers\grid\feature\PagingFeature;
|
||||
use PKP\controllers\grid\GridColumn;
|
||||
use PKP\controllers\grid\GridHandler;
|
||||
use PKP\controllers\grid\settings\roles\form\UserGroupForm;
|
||||
use PKP\core\JSONMessage;
|
||||
use PKP\core\PKPRequest;
|
||||
use PKP\db\DAORegistry;
|
||||
use PKP\linkAction\LinkAction;
|
||||
use PKP\linkAction\request\AjaxModal;
|
||||
use PKP\notification\PKPNotification;
|
||||
use PKP\security\authorization\ContextAccessPolicy;
|
||||
use PKP\security\authorization\internal\WorkflowStageRequiredPolicy;
|
||||
use PKP\security\Role;
|
||||
use PKP\security\RoleDAO;
|
||||
use PKP\userGroup\relationships\UserGroupStage;
|
||||
use PKP\userGroup\UserGroup;
|
||||
use PKP\workflow\WorkflowStageDAO;
|
||||
|
||||
class UserGroupGridHandler extends GridHandler
|
||||
{
|
||||
/** @var int Context id. */
|
||||
private $_contextId;
|
||||
|
||||
/** @var UserGroup User group object handled by some grid operations. */
|
||||
private $_userGroup;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->addRoleAssignment(
|
||||
[Role::ROLE_ID_MANAGER, Role::ROLE_ID_SITE_ADMIN],
|
||||
[
|
||||
'fetchGrid',
|
||||
'fetchCategory',
|
||||
'fetchRow',
|
||||
'addUserGroup',
|
||||
'editUserGroup',
|
||||
'updateUserGroup',
|
||||
'removeUserGroup',
|
||||
'assignStage',
|
||||
'unassignStage'
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// Overridden methods from PKPHandler.
|
||||
//
|
||||
/**
|
||||
* @copydoc PKPHandler::authorize()
|
||||
*/
|
||||
public function authorize($request, &$args, $roleAssignments)
|
||||
{
|
||||
$this->addPolicy(new ContextAccessPolicy($request, $roleAssignments));
|
||||
|
||||
$operation = $request->getRequestedOp();
|
||||
$workflowStageRequiredOps = ['assignStage', 'unassignStage'];
|
||||
if (in_array($operation, $workflowStageRequiredOps)) {
|
||||
$this->addPolicy(new WorkflowStageRequiredPolicy($request->getUserVar('stageId')));
|
||||
}
|
||||
|
||||
$userGroupRequiredOps = array_merge($workflowStageRequiredOps, ['editUserGroup', 'removeUserGroup']);
|
||||
if (in_array($operation, $userGroupRequiredOps)) {
|
||||
// Validate the user group object.
|
||||
$userGroupId = $request->getUserVar('userGroupId');
|
||||
|
||||
$userGroup = Repo::userGroup()->get($userGroupId);
|
||||
|
||||
if (!$userGroup) {
|
||||
fatalError('Invalid user group id!');
|
||||
} else {
|
||||
$this->_userGroup = $userGroup;
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
$this->_contextId = $context->getId();
|
||||
|
||||
// Basic grid configuration.
|
||||
$this->setTitle('grid.roles.currentRoles');
|
||||
|
||||
// Add grid-level actions.
|
||||
$router = $request->getRouter();
|
||||
$this->addAction(
|
||||
new LinkAction(
|
||||
'addUserGroup',
|
||||
new AjaxModal(
|
||||
$router->url($request, null, null, 'addUserGroup'),
|
||||
__('grid.roles.add'),
|
||||
'modal_add_role'
|
||||
),
|
||||
__('grid.roles.add'),
|
||||
'add_role'
|
||||
)
|
||||
);
|
||||
|
||||
$cellProvider = new UserGroupGridCellProvider();
|
||||
|
||||
$workflowStagesLocales = WorkflowStageDAO::getWorkflowStageTranslationKeys();
|
||||
|
||||
// Set array containing the columns info with the same cell provider.
|
||||
$columnsInfo = [
|
||||
1 => ['id' => 'name', 'title' => 'settings.roles.roleName', 'template' => null],
|
||||
2 => ['id' => 'roleId', 'title' => 'settings.roles.from', 'template' => null]
|
||||
];
|
||||
|
||||
foreach ($workflowStagesLocales as $stageId => $stageTitleKey) {
|
||||
$columnsInfo[] = ['id' => $stageId, 'title' => $stageTitleKey, 'template' => 'controllers/grid/common/cell/selectStatusCell.tpl'];
|
||||
}
|
||||
|
||||
// Add array columns to the grid.
|
||||
foreach ($columnsInfo as $columnInfo) {
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
$columnInfo['id'],
|
||||
$columnInfo['title'],
|
||||
null,
|
||||
$columnInfo['template'],
|
||||
$cellProvider
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::loadData()
|
||||
*/
|
||||
protected function loadData($request, $filter)
|
||||
{
|
||||
$contextId = $this->_getContextId();
|
||||
|
||||
$roleIdFilter = null;
|
||||
$stageIdFilter = null;
|
||||
|
||||
if (!is_array($filter)) {
|
||||
$filter = [];
|
||||
}
|
||||
|
||||
if (isset($filter['selectedRoleId'])) {
|
||||
$roleIdFilter = $filter['selectedRoleId'];
|
||||
}
|
||||
|
||||
if (isset($filter['selectedStageId'])) {
|
||||
$stageIdFilter = $filter['selectedStageId'];
|
||||
}
|
||||
|
||||
$rangeInfo = $this->getGridRangeInfo($request, $this->getId());
|
||||
|
||||
if ($stageIdFilter && $stageIdFilter != 0) {
|
||||
return Repo::userGroup()->getCollector()
|
||||
->filterByContextIds([$contextId])
|
||||
->filterByStageIds([$stageIdFilter])
|
||||
->filterByRoleIds([$roleIdFilter])
|
||||
->limit($rangeInfo->getCount())
|
||||
->offset($rangeInfo->getOffset() + max(0, $rangeInfo->getPage() - 1) * $rangeInfo->getCount())
|
||||
->getMany()
|
||||
->toArray();
|
||||
} elseif ($roleIdFilter && $roleIdFilter != 0) {
|
||||
return Repo::userGroup()->getByRoleIds([$roleIdFilter], $contextId)->toArray();
|
||||
} else {
|
||||
return Repo::userGroup()->getCollector()
|
||||
->filterByContextIds([$contextId])
|
||||
->getMany()
|
||||
->toArray();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::getRowInstance()
|
||||
*
|
||||
* @return UserGroupGridRow
|
||||
*/
|
||||
protected function getRowInstance()
|
||||
{
|
||||
return new UserGroupGridRow();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see GridHandler::renderFilter()
|
||||
*/
|
||||
public function renderFilter($request, $filterData = [])
|
||||
{
|
||||
// Get filter data.
|
||||
$roleDao = DAORegistry::getDAO('RoleDAO'); /** @var RoleDAO $roleDao */
|
||||
$roleOptions = [0 => 'grid.user.allPermissionLevels'] + Application::getRoleNames(true);
|
||||
|
||||
// Reader roles are not important for stage assignments.
|
||||
if (array_key_exists(Role::ROLE_ID_READER, $roleOptions)) {
|
||||
unset($roleOptions[Role::ROLE_ID_READER]);
|
||||
}
|
||||
|
||||
$filterData = ['roleOptions' => $roleOptions];
|
||||
|
||||
$workflowStages = [0 => 'grid.userGroup.allStages'] + WorkflowStageDAO::getWorkflowStageTranslationKeys();
|
||||
$filterData['stageOptions'] = $workflowStages;
|
||||
|
||||
return parent::renderFilter($request, $filterData);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see GridHandler::getFilterSelectionData()
|
||||
*
|
||||
* @return array Filter selection data.
|
||||
*/
|
||||
public function getFilterSelectionData($request)
|
||||
{
|
||||
$selectedRoleId = $request->getUserVar('selectedRoleId');
|
||||
$selectedStageId = $request->getUserVar('selectedStageId');
|
||||
|
||||
// Cast or set to grid filter default value (all roles).
|
||||
$selectedRoleId = (is_null($selectedRoleId) ? 0 : (int)$selectedRoleId);
|
||||
$selectedStageId = (is_null($selectedStageId) ? 0 : (int)$selectedStageId);
|
||||
|
||||
return ['selectedRoleId' => $selectedRoleId, 'selectedStageId' => $selectedStageId];
|
||||
}
|
||||
|
||||
/**
|
||||
* @see GridHandler::getFilterForm()
|
||||
*
|
||||
* @return string Filter template.
|
||||
*/
|
||||
protected function getFilterForm()
|
||||
{
|
||||
return 'controllers/grid/settings/roles/userGroupsGridFilter.tpl';
|
||||
}
|
||||
|
||||
/**
|
||||
* @see GridHandler::initFeatures()
|
||||
*/
|
||||
public function initFeatures($request, $args)
|
||||
{
|
||||
return [new PagingFeature()];
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Handler operations.
|
||||
//
|
||||
/**
|
||||
* Handle the add user group operation.
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*/
|
||||
public function addUserGroup($args, $request)
|
||||
{
|
||||
return $this->editUserGroup($args, $request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the edit user group operation.
|
||||
*
|
||||
* @param array $args
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function editUserGroup($args, $request)
|
||||
{
|
||||
$userGroupForm = $this->_getUserGroupForm($request);
|
||||
|
||||
$userGroupForm->initData();
|
||||
|
||||
return new JSONMessage(true, $userGroupForm->fetch($request));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update user group data on database and grid.
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function updateUserGroup($args, $request)
|
||||
{
|
||||
$userGroupForm = $this->_getUserGroupForm($request);
|
||||
|
||||
$userGroupForm->readInputData();
|
||||
if ($userGroupForm->validate()) {
|
||||
$notificationMgr = new NotificationManager();
|
||||
$notificationMgr->createTrivialNotification($request->getUser()->getId());
|
||||
$userGroupForm->execute();
|
||||
$json = \PKP\db\DAO::getDataChangedEvent();
|
||||
$json->setGlobalEvent('userGroupUpdated');
|
||||
return $json;
|
||||
} else {
|
||||
return new JSONMessage(true, $userGroupForm->fetch($request));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove user group.
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function removeUserGroup($args, $request)
|
||||
{
|
||||
if (!$request->checkCSRF()) {
|
||||
return new JSONMessage(false);
|
||||
}
|
||||
|
||||
$user = $request->getUser();
|
||||
$userGroup = $this->_userGroup;
|
||||
$contextId = $this->_getContextId();
|
||||
$notificationMgr = new NotificationManager();
|
||||
|
||||
$usersAssignedToUserGroupCount = Repo::user()->getCollector()
|
||||
->filterByContextIds([$contextId])
|
||||
->filterByUserGroupIds([$userGroup->getId()])
|
||||
->getCount();
|
||||
|
||||
if ($usersAssignedToUserGroupCount == 0) {
|
||||
if ($userGroup->getData('isDefault')) {
|
||||
// Can't delete default user groups.
|
||||
$notificationMgr->createTrivialNotification(
|
||||
$user->getId(),
|
||||
PKPNotification::NOTIFICATION_TYPE_WARNING,
|
||||
['contents' => __(
|
||||
'grid.userGroup.cantRemoveDefaultUserGroup',
|
||||
['userGroupName' => $userGroup->getLocalizedName() ]
|
||||
)]
|
||||
);
|
||||
} else {
|
||||
// We can delete, no user assigned yet.
|
||||
Repo::userGroup()->delete($userGroup);
|
||||
|
||||
$notificationMgr->createTrivialNotification(
|
||||
$user->getId(),
|
||||
PKPNotification::NOTIFICATION_TYPE_SUCCESS,
|
||||
['contents' => __(
|
||||
'grid.userGroup.removed',
|
||||
['userGroupName' => $userGroup->getLocalizedName() ]
|
||||
)]
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// Can't delete while an user
|
||||
// is still assigned to that user group.
|
||||
$notificationMgr->createTrivialNotification(
|
||||
$user->getId(),
|
||||
PKPNotification::NOTIFICATION_TYPE_WARNING,
|
||||
['contents' => __(
|
||||
'grid.userGroup.cantRemoveUserGroup',
|
||||
['userGroupName' => $userGroup->getLocalizedName(), 'usersCount' => $usersAssignedToUserGroupCount]
|
||||
)]
|
||||
);
|
||||
}
|
||||
|
||||
$json = \PKP\db\DAO::getDataChangedEvent($userGroup->getId());
|
||||
$json->setGlobalEvent('userGroupUpdated');
|
||||
return $json;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign stage to user group.
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*/
|
||||
public function assignStage($args, $request)
|
||||
{
|
||||
return $this->_toggleAssignment($args, $request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unassign stage to user group.
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*/
|
||||
public function unassignStage($args, $request)
|
||||
{
|
||||
return $this->_toggleAssignment($args, $request);
|
||||
}
|
||||
|
||||
//
|
||||
// Private helper methods.
|
||||
//
|
||||
|
||||
/**
|
||||
* Toggle user group stage assignment.
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
private function _toggleAssignment($args, $request)
|
||||
{
|
||||
if (!$request->checkCSRF()) {
|
||||
return new JSONMessage(false);
|
||||
}
|
||||
$userGroup = $this->_userGroup;
|
||||
$stageId = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_WORKFLOW_STAGE);
|
||||
$contextId = $this->_getContextId();
|
||||
$operation = $request->getRequestedOp();
|
||||
|
||||
switch ($operation) {
|
||||
case 'assignStage':
|
||||
UserGroupStage::create([
|
||||
'contextId' => $contextId,
|
||||
'userGroupId' => $userGroup->getId(),
|
||||
'stageId' => $stageId
|
||||
]);
|
||||
|
||||
$messageKey = 'grid.userGroup.assignedStage';
|
||||
break;
|
||||
case 'unassignStage':
|
||||
Repo::userGroup()->removeGroupFromStage($contextId, $userGroup->getId(), $stageId);
|
||||
$messageKey = 'grid.userGroup.unassignedStage';
|
||||
break;
|
||||
}
|
||||
|
||||
$notificationMgr = new NotificationManager();
|
||||
$user = $request->getUser();
|
||||
|
||||
$stageLocaleKeys = WorkflowStageDAO::getWorkflowStageTranslationKeys();
|
||||
|
||||
$notificationMgr->createTrivialNotification(
|
||||
$user->getId(),
|
||||
PKPNotification::NOTIFICATION_TYPE_SUCCESS,
|
||||
['contents' => __(
|
||||
$messageKey,
|
||||
['userGroupName' => $userGroup->getLocalizedName(), 'stageName' => __($stageLocaleKeys[$stageId])]
|
||||
)]
|
||||
);
|
||||
|
||||
return \PKP\db\DAO::getDataChangedEvent($userGroup->getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a UserGroupForm instance.
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return UserGroupForm
|
||||
*/
|
||||
private function _getUserGroupForm($request)
|
||||
{
|
||||
// Get the user group Id.
|
||||
$userGroupId = (int) $request->getUserVar('userGroupId');
|
||||
|
||||
// Instantiate the files form.
|
||||
$contextId = $this->_getContextId();
|
||||
return new UserGroupForm($contextId, $userGroupId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get context id.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
private function _getContextId()
|
||||
{
|
||||
return $this->_contextId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/settings/roles/UserGroupGridRow.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 UserGroupGridRow
|
||||
*
|
||||
* @ingroup controllers_grid_settings_roles
|
||||
*
|
||||
* @brief User group grid row definition
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\settings\roles;
|
||||
|
||||
use PKP\controllers\grid\GridRow;
|
||||
use PKP\linkAction\LinkAction;
|
||||
use PKP\linkAction\request\AjaxModal;
|
||||
use PKP\linkAction\request\RemoteActionConfirmationModal;
|
||||
use PKP\userGroup\UserGroup;
|
||||
|
||||
class UserGroupGridRow extends GridRow
|
||||
{
|
||||
//
|
||||
// Overridden methods from GridRow
|
||||
//
|
||||
/**
|
||||
* @copydoc GridRow::initialize()
|
||||
*
|
||||
* @param null|mixed $template
|
||||
*/
|
||||
public function initialize($request, $template = null)
|
||||
{
|
||||
parent::initialize($request, $template);
|
||||
|
||||
$userGroup = $this->getData(); /** @var UserGroup $userGroup */
|
||||
assert($userGroup != null);
|
||||
|
||||
$rowId = $this->getId();
|
||||
|
||||
$actionArgs = ['userGroupId' => $userGroup->getId()];
|
||||
$this->setRequestArgs($actionArgs);
|
||||
|
||||
// Only add row actions if this is an existing row.
|
||||
if (!empty($rowId) && is_numeric($rowId)) {
|
||||
$router = $request->getRouter();
|
||||
|
||||
$this->addAction(new LinkAction(
|
||||
'editUserGroup',
|
||||
new AjaxModal(
|
||||
$router->url($request, null, null, 'editUserGroup', null, $actionArgs),
|
||||
__('grid.action.edit'),
|
||||
'modal_edit'
|
||||
),
|
||||
__('grid.action.edit'),
|
||||
'edit'
|
||||
));
|
||||
|
||||
$this->addAction(new LinkAction(
|
||||
'removeUserGroup',
|
||||
new RemoteActionConfirmationModal(
|
||||
$request->getSession(),
|
||||
__('settings.roles.removeText'),
|
||||
null,
|
||||
$router->url($request, null, null, 'removeUserGroup', null, $actionArgs)
|
||||
),
|
||||
__('grid.action.remove'),
|
||||
'delete'
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,327 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/settings/roles/form/UserGroupForm.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 UserGroupForm
|
||||
*
|
||||
* @ingroup controllers_grid_settings_roles_form
|
||||
*
|
||||
* @brief Form to add/edit user group.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\settings\roles\form;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\core\Request;
|
||||
use APP\facades\Repo;
|
||||
use APP\template\TemplateManager;
|
||||
use PKP\core\JSONMessage;
|
||||
use PKP\db\DAORegistry;
|
||||
use PKP\facades\Locale;
|
||||
use PKP\form\Form;
|
||||
use PKP\security\Role;
|
||||
use PKP\security\RoleDAO;
|
||||
use PKP\security\Validation;
|
||||
use PKP\stageAssignment\StageAssignmentDAO;
|
||||
use PKP\userGroup\relationships\UserGroupStage;
|
||||
use PKP\workflow\WorkflowStageDAO;
|
||||
|
||||
class UserGroupForm extends Form
|
||||
{
|
||||
/** @var int Id of the user group being edited */
|
||||
public $_userGroupId;
|
||||
|
||||
/** @var int The context of the user group being edited */
|
||||
public $_contextId;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param int $contextId id.
|
||||
* @param int $userGroupId group id.
|
||||
*/
|
||||
public function __construct($contextId, $userGroupId = null)
|
||||
{
|
||||
parent::__construct('controllers/grid/settings/roles/form/userGroupForm.tpl');
|
||||
$this->_contextId = $contextId;
|
||||
$this->_userGroupId = $userGroupId;
|
||||
|
||||
// Validation checks for this form
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorLocale($this, 'name', 'required', 'settings.roles.nameRequired'));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorLocale($this, 'abbrev', 'required', 'settings.roles.abbrevRequired'));
|
||||
if ($this->getUserGroupId() == null) {
|
||||
$this->addCheck(new \PKP\form\validation\FormValidator($this, 'roleId', 'required', 'settings.roles.roleIdRequired'));
|
||||
}
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorPost($this));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorCSRF($this));
|
||||
}
|
||||
|
||||
//
|
||||
// Getters and Setters
|
||||
//
|
||||
/**
|
||||
* Get the user group id.
|
||||
*
|
||||
* @return int userGroupId
|
||||
*/
|
||||
public function getUserGroupId()
|
||||
{
|
||||
return $this->_userGroupId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the context id.
|
||||
*
|
||||
* @return int contextId
|
||||
*/
|
||||
public function getContextId()
|
||||
{
|
||||
return $this->_contextId;
|
||||
}
|
||||
|
||||
//
|
||||
// Implement template methods from Form.
|
||||
//
|
||||
/**
|
||||
* Get all locale field names
|
||||
*/
|
||||
public function getLocaleFieldNames()
|
||||
{
|
||||
return ['name', 'abbrev'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::initData()
|
||||
*/
|
||||
public function initData()
|
||||
{
|
||||
$userGroup = Repo::userGroup()->get($this->getUserGroupId());
|
||||
$stages = WorkflowStageDAO::getWorkflowStageTranslationKeys();
|
||||
$this->setData('stages', $stages);
|
||||
$this->setData('assignedStages', []); // sensible default
|
||||
|
||||
$roleDao = DAORegistry::getDAO('RoleDAO'); /** @var RoleDAO $roleDao */
|
||||
$jsonMessage = new JSONMessage();
|
||||
$jsonMessage->setContent($roleDao->getForbiddenStages());
|
||||
$this->setData('roleForbiddenStagesJSON', $jsonMessage->getString());
|
||||
|
||||
if ($userGroup) {
|
||||
$assignedStages = Repo::userGroup()->getAssignedStagesByUserGroupId($this->getContextId(), $userGroup->getId())->toArray();
|
||||
|
||||
$data = [
|
||||
'userGroupId' => $userGroup->getId(),
|
||||
'roleId' => $userGroup->getRoleId(),
|
||||
'name' => $userGroup->getName(null), //Localized
|
||||
'abbrev' => $userGroup->getAbbrev(null), //Localized
|
||||
'assignedStages' => $assignedStages,
|
||||
'showTitle' => $userGroup->getShowTitle(),
|
||||
'permitSelfRegistration' => $userGroup->getPermitSelfRegistration(),
|
||||
'permitMetadataEdit' => $userGroup->getPermitMetadataEdit(),
|
||||
'recommendOnly' => $userGroup->getRecommendOnly(),
|
||||
];
|
||||
|
||||
foreach ($data as $field => $value) {
|
||||
$this->setData($field, $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::readInputData()
|
||||
*/
|
||||
public function readInputData()
|
||||
{
|
||||
$this->readUserVars(['roleId', 'name', 'abbrev', 'assignedStages', 'showTitle', 'permitSelfRegistration', 'recommendOnly', 'permitMetadataEdit']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::fetch()
|
||||
*
|
||||
* @param null|mixed $template
|
||||
*/
|
||||
public function fetch($request, $template = null, $display = false)
|
||||
{
|
||||
$templateMgr = TemplateManager::getManager($request);
|
||||
|
||||
$roleDao = DAORegistry::getDAO('RoleDAO'); /** @var RoleDAO $roleDao */
|
||||
$templateMgr->assign('roleOptions', Application::getRoleNames(true));
|
||||
|
||||
// Users can't edit the role once user group is created.
|
||||
// userGroupId is 0 for new User Groups because it is cast to int in UserGroupGridHandler.
|
||||
$disableRoleSelect = ($this->getUserGroupId() > 0) ? true : false;
|
||||
$templateMgr->assign('disableRoleSelect', $disableRoleSelect);
|
||||
$templateMgr->assign('selfRegistrationRoleIds', $this->getPermitSelfRegistrationRoles());
|
||||
$templateMgr->assign('recommendOnlyRoleIds', $this->getRecommendOnlyRoles());
|
||||
$templateMgr->assign('notChangeMetadataEditPermissionRoles', Repo::userGroup()::NOT_CHANGE_METADATA_EDIT_PERMISSION_ROLES);
|
||||
|
||||
return parent::fetch($request, $template, $display);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of roles optionally permitting user self-registration.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getPermitSelfRegistrationRoles()
|
||||
{
|
||||
return [Role::ROLE_ID_REVIEWER, Role::ROLE_ID_AUTHOR, Role::ROLE_ID_READER];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of roles optionally permitting recommendOnly option.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getRecommendOnlyRoles()
|
||||
{
|
||||
return [Role::ROLE_ID_MANAGER, Role::ROLE_ID_SUB_EDITOR];
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::execute()
|
||||
*/
|
||||
public function execute(...$functionParams)
|
||||
{
|
||||
parent::execute(...$functionParams);
|
||||
|
||||
$request = Application::get()->getRequest();
|
||||
$userGroupId = $this->getUserGroupId();
|
||||
|
||||
$roleDao = DAORegistry::getDAO('RoleDAO'); /** @var RoleDAO $roleDao */
|
||||
|
||||
// Check if we are editing an existing user group or creating another one.
|
||||
if ($userGroupId == null) {
|
||||
$userGroup = Repo::userGroup()->newDataObject();
|
||||
$userGroup->setRoleId($this->getData('roleId'));
|
||||
$userGroup->setContextId($this->getContextId());
|
||||
$userGroup->setDefault(false);
|
||||
$userGroup->setShowTitle(is_null($this->getData('showTitle')) ? false : $this->getData('showTitle'));
|
||||
$userGroup->setPermitSelfRegistration($this->getData('permitSelfRegistration') && in_array($userGroup->getRoleId(), $this->getPermitSelfRegistrationRoles()));
|
||||
$userGroup->setPermitMetadataEdit($this->getData('permitMetadataEdit') && !in_array($this->getData('roleId'), Repo::userGroup()::NOT_CHANGE_METADATA_EDIT_PERMISSION_ROLES));
|
||||
if (in_array($this->getData('roleId'), Repo::userGroup()::NOT_CHANGE_METADATA_EDIT_PERMISSION_ROLES)) {
|
||||
$userGroup->setPermitMetadataEdit(true);
|
||||
}
|
||||
|
||||
$userGroup->setRecommendOnly($this->getData('recommendOnly') && in_array($userGroup->getRoleId(), $this->getRecommendOnlyRoles()));
|
||||
$userGroup = $this->_setUserGroupLocaleFields($userGroup, $request);
|
||||
|
||||
$userGroupId = Repo::userGroup()->add($userGroup);
|
||||
} else {
|
||||
$userGroup = Repo::userGroup()->get($userGroupId);
|
||||
$userGroup = $this->_setUserGroupLocaleFields($userGroup, $request);
|
||||
$userGroup->setShowTitle(is_null($this->getData('showTitle')) ? false : $this->getData('showTitle'));
|
||||
$userGroup->setPermitSelfRegistration($this->getData('permitSelfRegistration') && in_array($userGroup->getRoleId(), $this->getPermitSelfRegistrationRoles()));
|
||||
$userGroup->setPermitMetadataEdit($this->getData('permitMetadataEdit') && !in_array($userGroup->getRoleId(), Repo::userGroup()::NOT_CHANGE_METADATA_EDIT_PERMISSION_ROLES));
|
||||
if (in_array($userGroup->getRoleId(), Repo::userGroup()::NOT_CHANGE_METADATA_EDIT_PERMISSION_ROLES)) {
|
||||
$userGroup->setPermitMetadataEdit(true);
|
||||
} else {
|
||||
$stageAssignmentDao = DAORegistry::getDAO('StageAssignmentDAO'); /** @var StageAssignmentDAO $stageAssignmentDao */
|
||||
$allUserAssignments = $stageAssignmentDao
|
||||
->getByUserGroupId($userGroupId, $this->getContextId())
|
||||
->toAssociativeArray();
|
||||
|
||||
foreach ($allUserAssignments as $userAssignment) {
|
||||
$userAssignment->setCanChangeMetadata($userGroup->getPermitMetadataEdit());
|
||||
$stageAssignmentDao->updateObject($userAssignment);
|
||||
}
|
||||
}
|
||||
|
||||
$userGroup->setRecommendOnly($this->getData('recommendOnly') && in_array($userGroup->getRoleId(), $this->getRecommendOnlyRoles()));
|
||||
|
||||
Repo::userGroup()->edit($userGroup, []);
|
||||
}
|
||||
|
||||
// After we have created/edited the user group, we assign/update its stages.
|
||||
$assignedStages = $this->getData('assignedStages');
|
||||
// Always set all stages active for some permission levels.
|
||||
if (in_array($userGroup->getRoleId(), $roleDao->getAlwaysActiveStages())) {
|
||||
$assignedStages = array_keys(WorkflowStageDAO::getWorkflowStageTranslationKeys());
|
||||
}
|
||||
if ($assignedStages) {
|
||||
$this->_assignStagesToUserGroup($userGroupId, $assignedStages);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Private helper methods
|
||||
//
|
||||
/**
|
||||
* Setup the stages assignments to a user group in database.
|
||||
*
|
||||
* @param int $userGroupId User group id that will receive the stages.
|
||||
* @param array $userAssignedStages of stages currently assigned to a user.
|
||||
*/
|
||||
public function _assignStagesToUserGroup($userGroupId, $userAssignedStages)
|
||||
{
|
||||
$contextId = $this->getContextId();
|
||||
|
||||
// Current existing workflow stages.
|
||||
$stages = WorkflowStageDAO::getWorkflowStageTranslationKeys();
|
||||
|
||||
foreach (array_keys($stages) as $stageId) {
|
||||
Repo::userGroup()->removeGroupFromStage($contextId, $userGroupId, $stageId);
|
||||
}
|
||||
|
||||
foreach ($userAssignedStages as $stageId) {
|
||||
// Make sure we don't assign forbidden stages based on
|
||||
// user groups role id. Override in case of some permission levels.
|
||||
$roleId = $this->getData('roleId');
|
||||
$roleDao = DAORegistry::getDAO('RoleDAO'); /** @var RoleDAO $roleDao */
|
||||
$forbiddenStages = $roleDao->getForbiddenStages($roleId);
|
||||
if (in_array($stageId, $forbiddenStages) && !in_array($roleId, $roleDao->getAlwaysActiveStages())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check if is a valid stage.
|
||||
if (in_array($stageId, array_keys($stages))) {
|
||||
UserGroupStage::create([
|
||||
'contextId' => $contextId,
|
||||
'userGroupId' => $userGroupId,
|
||||
'stageId' => $stageId
|
||||
]);
|
||||
} else {
|
||||
fatalError('Invalid stage id');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set locale fields on a User Group object.
|
||||
*
|
||||
* @param \PKP\userGroup\UserGroup $userGroup
|
||||
* @param Request $request
|
||||
*
|
||||
*/
|
||||
public function _setUserGroupLocaleFields($userGroup, $request): \PKP\userGroup\UserGroup
|
||||
{
|
||||
$router = $request->getRouter();
|
||||
$context = $router->getContext($request);
|
||||
$supportedLocales = $context->getSupportedLocaleNames();
|
||||
|
||||
if (!empty($supportedLocales)) {
|
||||
foreach ($context->getSupportedLocaleNames() as $localeKey => $localeName) {
|
||||
$name = $this->getData('name');
|
||||
$abbrev = $this->getData('abbrev');
|
||||
if (isset($name[$localeKey])) {
|
||||
$userGroup->setName($name[$localeKey], $localeKey);
|
||||
}
|
||||
if (isset($abbrev[$localeKey])) {
|
||||
$userGroup->setAbbrev($abbrev[$localeKey], $localeKey);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$localeKey = Locale::getLocale();
|
||||
$userGroup->setName($this->getData('name'), $localeKey);
|
||||
$userGroup->setAbbrev($this->getData('abbrev'), $localeKey);
|
||||
}
|
||||
|
||||
return $userGroup;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,201 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/settings/sections/form/PKPSectionForm.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 PKPSectionForm
|
||||
*
|
||||
* @ingroup controllers_grid_settings_section_form
|
||||
*
|
||||
* @brief Form for adding/editing a section
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\settings\sections\form;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\facades\Repo;
|
||||
use APP\section\Section;
|
||||
use APP\template\TemplateManager;
|
||||
use PKP\context\SubEditorsDAO;
|
||||
use PKP\core\PKPRequest;
|
||||
use PKP\db\DAORegistry;
|
||||
use PKP\form\Form;
|
||||
use PKP\security\Role;
|
||||
use PKP\userGroup\UserGroup;
|
||||
|
||||
class PKPSectionForm extends Form
|
||||
{
|
||||
/** @var int the id for the section being edited */
|
||||
public $_sectionId;
|
||||
|
||||
/** @var int The current user ID */
|
||||
public $_userId;
|
||||
|
||||
/** @var string Cover image extension */
|
||||
public $_imageExtension;
|
||||
|
||||
/** @var array Cover image information from getimagesize */
|
||||
public $_sizeArray;
|
||||
|
||||
public ?Section $section = null;
|
||||
|
||||
/** @var array Roles that can be assigned to this section */
|
||||
public $assignableRoles = [Role::ROLE_ID_MANAGER, Role::ROLE_ID_SUB_EDITOR, Role::ROLE_ID_ASSISTANT];
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param PKPRequest $request
|
||||
* @param string $template Template path
|
||||
* @param int $sectionId optional
|
||||
*/
|
||||
public function __construct($request, $template, $sectionId = null)
|
||||
{
|
||||
$this->setSectionId($sectionId);
|
||||
|
||||
$user = $request->getUser();
|
||||
$this->_userId = $user->getId();
|
||||
|
||||
parent::__construct($template);
|
||||
|
||||
// Validation checks for this form
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorPost($this));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorCSRF($this));
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::readInputData()
|
||||
*/
|
||||
public function readInputData()
|
||||
{
|
||||
$this->readUserVars(['title', 'subEditors']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the section ID for this section.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getSectionId()
|
||||
{
|
||||
return $this->_sectionId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the section ID for this section.
|
||||
*
|
||||
* @param int $sectionId
|
||||
*/
|
||||
public function setSectionId($sectionId)
|
||||
{
|
||||
$this->_sectionId = $sectionId;
|
||||
}
|
||||
|
||||
public function getSection(): ?Section
|
||||
{
|
||||
return $this->section;
|
||||
}
|
||||
|
||||
public function setSection(Section $section): void
|
||||
{
|
||||
$this->section = $section;
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::fetch()
|
||||
*
|
||||
* @param null|mixed $template
|
||||
*/
|
||||
public function fetch($request, $template = null, $display = false)
|
||||
{
|
||||
$assignableUserGroups = Repo::userGroup()
|
||||
->getCollector()
|
||||
->filterByContextIds([$request->getContext()->getId()])
|
||||
->filterByRoleIds($this->assignableRoles)
|
||||
->filterByStageIds([WORKFLOW_STAGE_ID_SUBMISSION])
|
||||
->getMany()
|
||||
->map(function (UserGroup $userGroup) use ($request) {
|
||||
return [
|
||||
'userGroup' => $userGroup,
|
||||
'users' => Repo::user()
|
||||
->getCollector()
|
||||
->filterByUserGroupIds([$userGroup->getId()])
|
||||
->filterByContextIds([$request->getContext()->getId()])
|
||||
->getMany()
|
||||
->mapWithKeys(fn ($user, $key) => [$user->getId() => $user->getFullName()])
|
||||
->toArray()
|
||||
];
|
||||
});
|
||||
|
||||
$templateMgr = TemplateManager::getManager($request);
|
||||
$templateMgr->assign([
|
||||
'assignableUserGroups' => $assignableUserGroups->toArray(),
|
||||
]);
|
||||
|
||||
return parent::fetch($request, $template, $display);
|
||||
}
|
||||
|
||||
public function initData()
|
||||
{
|
||||
$subeditorUserGroups = [];
|
||||
|
||||
if ($this->getSection() !== null) {
|
||||
$assignedSubeditors = Repo::user()
|
||||
->getCollector()
|
||||
->filterByContextIds([Application::get()->getRequest()->getContext()->getId()])
|
||||
->filterByRoleIds($this->assignableRoles)
|
||||
->assignedToSectionIds([$this->getSectionId()])
|
||||
->getIds()
|
||||
->toArray();
|
||||
|
||||
if (!empty($assignedSubeditors)) {
|
||||
$subEditorsDao = DAORegistry::getDAO('SubEditorsDAO'); /** @var SubEditorsDAO $subEditorsDao */
|
||||
$subeditorUserGroups = $subEditorsDao->getAssignedUserGroupIds(
|
||||
Application::get()->getRequest()->getContext()->getId(),
|
||||
Application::ASSOC_TYPE_SECTION,
|
||||
$this->getSection()->getId(),
|
||||
$assignedSubeditors
|
||||
)->toArray();
|
||||
}
|
||||
}
|
||||
|
||||
$this->setData([
|
||||
'subeditorUserGroups' => $subeditorUserGroups,
|
||||
]);
|
||||
|
||||
parent::initData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Save changes to subeditors
|
||||
*
|
||||
*/
|
||||
public function execute(...$functionArgs)
|
||||
{
|
||||
$contextId = Application::get()->getRequest()->getContext()->getId();
|
||||
$subEditorsDao = DAORegistry::getDAO('SubEditorsDAO'); /** @var SubEditorsDAO $subEditorsDao */
|
||||
$subEditorsDao->deleteBySubmissionGroupId($this->getSectionId(), Application::ASSOC_TYPE_SECTION, $contextId);
|
||||
$subEditors = $this->getData('subEditors');
|
||||
if (!empty($subEditors)) {
|
||||
$allowedEditors = Repo::user()
|
||||
->getCollector()
|
||||
->filterByRoleIds($this->assignableRoles)
|
||||
->filterByContextIds([Application::get()->getRequest()->getContext()->getId()])
|
||||
->getIds();
|
||||
foreach ($subEditors as $userGroupId => $userIds) {
|
||||
foreach ($userIds as $userId) {
|
||||
if (!$allowedEditors->contains($userId)) {
|
||||
continue;
|
||||
}
|
||||
$subEditorsDao->insertEditor($contextId, $this->getSectionId(), $userId, Application::ASSOC_TYPE_SECTION, (int) $userGroupId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
parent::execute($functionArgs);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,686 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/settings/user/UserGridHandler.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 UserGridHandler
|
||||
*
|
||||
* @ingroup controllers_grid_settings_user
|
||||
*
|
||||
* @brief Handle user grid requests.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\settings\user;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\facades\Repo;
|
||||
use APP\notification\NotificationManager;
|
||||
use PKP\controllers\grid\ColumnBasedGridCellProvider;
|
||||
use PKP\controllers\grid\DataObjectGridCellProvider;
|
||||
use PKP\controllers\grid\feature\PagingFeature;
|
||||
use PKP\controllers\grid\GridColumn;
|
||||
use PKP\controllers\grid\GridHandler;
|
||||
use PKP\controllers\grid\settings\user\form\UserDetailsForm;
|
||||
use PKP\controllers\grid\settings\user\form\UserDisableForm;
|
||||
use PKP\controllers\grid\settings\user\form\UserEmailForm;
|
||||
use PKP\controllers\grid\settings\user\form\UserRoleForm;
|
||||
use PKP\core\JSONMessage;
|
||||
use PKP\core\PKPRequest;
|
||||
use PKP\core\VirtualArrayIterator;
|
||||
use PKP\db\DAORegistry;
|
||||
use PKP\identity\Identity;
|
||||
use PKP\linkAction\LinkAction;
|
||||
use PKP\linkAction\request\AjaxModal;
|
||||
use PKP\notification\PKPNotification;
|
||||
use PKP\security\authorization\ContextAccessPolicy;
|
||||
use PKP\security\Role;
|
||||
use PKP\security\RoleDAO;
|
||||
use PKP\security\Validation;
|
||||
use PKP\user\User;
|
||||
use PKP\userGroup\UserGroup;
|
||||
|
||||
class UserGridHandler extends GridHandler
|
||||
{
|
||||
/** @var int user id for the user to remove */
|
||||
public $_oldUserId;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->addRoleAssignment(
|
||||
[
|
||||
Role::ROLE_ID_MANAGER, Role::ROLE_ID_SITE_ADMIN],
|
||||
['fetchGrid', 'fetchRow', 'editUser', 'updateUser', 'updateUserRoles',
|
||||
'editDisableUser', 'disableUser', 'removeUser', 'addUser',
|
||||
'editEmail', 'sendEmail', 'mergeUsers']
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// 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);
|
||||
|
||||
$this->_oldUserId = (int) $request->getUserVar('oldUserId');
|
||||
// Basic grid configuration.
|
||||
$this->setTitle('grid.user.currentUsers');
|
||||
|
||||
// Grid actions.
|
||||
$router = $request->getRouter();
|
||||
|
||||
$this->addAction(
|
||||
new LinkAction(
|
||||
'addUser',
|
||||
new AjaxModal(
|
||||
$router->url($request, null, null, 'addUser', null, null),
|
||||
__('grid.user.add'),
|
||||
'modal_add_user',
|
||||
true
|
||||
),
|
||||
__('grid.user.add'),
|
||||
'add_user'
|
||||
)
|
||||
);
|
||||
|
||||
//
|
||||
// Grid columns.
|
||||
//
|
||||
$cellProvider = new DataObjectGridCellProvider();
|
||||
|
||||
// First Name.
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'givenName',
|
||||
'user.givenName',
|
||||
null,
|
||||
null,
|
||||
$cellProvider
|
||||
)
|
||||
);
|
||||
|
||||
// Last Name.
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'familyName',
|
||||
'user.familyName',
|
||||
null,
|
||||
null,
|
||||
$cellProvider
|
||||
)
|
||||
);
|
||||
|
||||
// User name.
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'userName',
|
||||
'user.username',
|
||||
null,
|
||||
null,
|
||||
$cellProvider
|
||||
)
|
||||
);
|
||||
|
||||
// Roles.
|
||||
$columnBasedGridCellProvider = new ColumnBasedGridCellProvider();
|
||||
$this->addColumn(
|
||||
new class (
|
||||
'roles',
|
||||
'user.roles',
|
||||
null,
|
||||
null,
|
||||
$columnBasedGridCellProvider
|
||||
) extends GridColumn {
|
||||
public function getTemplateVarsFromRow($row): array
|
||||
{
|
||||
$user = $row->getData();
|
||||
assert($user instanceof User);
|
||||
$contextId = Application::get()->getRequest()->getContext()->getId();
|
||||
$userGroupsIterator = Repo::userGroup()->userUserGroups($user->getId(), $contextId);
|
||||
$roles = $userGroupsIterator->map(fn (UserGroup $userGroup) => $userGroup->getLocalizedName())->join(__('common.commaListSeparator'));
|
||||
return ['label' => $roles];
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// Email.
|
||||
$this->addColumn(
|
||||
new GridColumn(
|
||||
'email',
|
||||
'user.email',
|
||||
null,
|
||||
null,
|
||||
$cellProvider
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Implement methods from GridHandler.
|
||||
//
|
||||
/**
|
||||
* @copydoc GridHandler::getRowInstance()
|
||||
*
|
||||
* @return UserGridRow
|
||||
*/
|
||||
protected function getRowInstance()
|
||||
{
|
||||
return new UserGridRow($this->_oldUserId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::initFeatures()
|
||||
*/
|
||||
public function initFeatures($request, $args)
|
||||
{
|
||||
return [new PagingFeature()];
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::loadData()
|
||||
*
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return VirtualArrayIterator Grid data.
|
||||
*/
|
||||
protected function loadData($request, $filter)
|
||||
{
|
||||
$context = $request->getContext();
|
||||
|
||||
$collector = Repo::user()->getCollector();
|
||||
$collector->filterByStatus($collector::STATUS_ALL);
|
||||
if ($filter['userGroup'] ?? false) {
|
||||
$collector->filterByUserGroupIds((array) $filter['userGroup']);
|
||||
}
|
||||
if (!($filter['includeNoRole'] ?? false)) {
|
||||
$collector->filterByContextIds([$context->getId()]);
|
||||
}
|
||||
if (strlen($filter['search'] ?? '')) {
|
||||
$collector->searchPhrase($filter['search']);
|
||||
}
|
||||
|
||||
// Handle grid paging (deprecated style)
|
||||
$rangeInfo = $this->getGridRangeInfo($request, $this->getId());
|
||||
$totalCount = $collector->getCount();
|
||||
$collector->limit($rangeInfo->getCount());
|
||||
$collector->offset($rangeInfo->getOffset() + max(0, $rangeInfo->getPage() - 1) * $rangeInfo->getCount());
|
||||
$iterator = $collector->getMany();
|
||||
return new VirtualArrayIterator(iterator_to_array($iterator, 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();
|
||||
}
|
||||
|
||||
$userDao = Repo::user()->dao;
|
||||
$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'
|
||||
];
|
||||
|
||||
$matchOptions = [
|
||||
'contains' => 'form.contains',
|
||||
'is' => 'form.is'
|
||||
];
|
||||
|
||||
$filterData = [
|
||||
'userGroupOptions' => $userGroupOptions,
|
||||
'fieldOptions' => $fieldOptions,
|
||||
'matchOptions' => $matchOptions,
|
||||
// oldUserId is used when merging users. see: userGridFilter.tpl
|
||||
'oldUserId' => $request->getUserVar('oldUserId'),
|
||||
];
|
||||
|
||||
return parent::renderFilter($request, $filterData);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::getFilterSelectionData()
|
||||
*
|
||||
* @return array Filter selection data.
|
||||
*/
|
||||
public function getFilterSelectionData($request)
|
||||
{
|
||||
// Get the search terms.
|
||||
$includeNoRole = $request->getUserVar('includeNoRole') ? (int) $request->getUserVar('includeNoRole') : null;
|
||||
$userGroup = $request->getUserVar('userGroup') ? (int)$request->getUserVar('userGroup') : null;
|
||||
$searchField = $request->getUserVar('searchField');
|
||||
$searchMatch = $request->getUserVar('searchMatch');
|
||||
$search = $request->getUserVar('search');
|
||||
|
||||
return $filterSelectionData = [
|
||||
'includeNoRole' => $includeNoRole,
|
||||
'userGroup' => $userGroup,
|
||||
'searchField' => $searchField,
|
||||
'searchMatch' => $searchMatch,
|
||||
'search' => $search ? $search : ''
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc GridHandler::getFilterForm()
|
||||
*
|
||||
* @return string Filter template.
|
||||
*/
|
||||
protected function getFilterForm()
|
||||
{
|
||||
return 'controllers/grid/settings/user/userGridFilter.tpl';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the js handler for this component.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getJSHandler()
|
||||
{
|
||||
return '$.pkp.controllers.grid.users.UserGridHandler';
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Public grid actions.
|
||||
//
|
||||
/**
|
||||
* Add a new user.
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*/
|
||||
public function addUser($args, $request)
|
||||
{
|
||||
// Calling editUser with an empty row id will add a new user.
|
||||
return $this->editUser($args, $request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit an existing user.
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function editUser($args, $request)
|
||||
{
|
||||
// Identify the user Id.
|
||||
$userId = $request->getUserVar('rowId');
|
||||
|
||||
if (!$userId) {
|
||||
$userId = $request->getUserVar('userId');
|
||||
}
|
||||
|
||||
$user = $request->getUser();
|
||||
$administrationLevel = null;
|
||||
|
||||
if ($userId !== null && ($administrationLevel = Validation::getAdministrationLevel($userId, $user->getId(), $request->getContext()->getId())) === Validation::ADMINISTRATION_PROHIBITED) {
|
||||
// We don't have administrative rights over this user.
|
||||
return new JSONMessage(false, __('grid.user.cannotAdminister'));
|
||||
}
|
||||
|
||||
// Form handling.
|
||||
$userForm = new UserDetailsForm($request, $userId);
|
||||
|
||||
$administrationLevel === Validation::ADMINISTRATION_PARTIAL
|
||||
? $userForm->applyUserGroupUpdateOnly()
|
||||
: $userForm->attachValidationChecks($request);
|
||||
|
||||
$userForm->initData();
|
||||
|
||||
return new JSONMessage(true, $userForm->display($request));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update an existing user.
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function updateUser($args, $request)
|
||||
{
|
||||
$user = $request->getUser();
|
||||
|
||||
// Identify the user Id.
|
||||
$userId = $request->getUserVar('userId');
|
||||
$administrationLevel = null;
|
||||
|
||||
if ($userId !== null && ($administrationLevel = Validation::getAdministrationLevel($userId, $user->getId(), $request->getContext()->getId())) === Validation::ADMINISTRATION_PROHIBITED) {
|
||||
// We don't have administrative rights over this user.
|
||||
return new JSONMessage(false, __('grid.user.cannotAdminister'));
|
||||
}
|
||||
|
||||
// Form handling.
|
||||
$userForm = new UserDetailsForm($request, $userId);
|
||||
|
||||
$administrationLevel === Validation::ADMINISTRATION_PARTIAL
|
||||
? $userForm->applyUserGroupUpdateOnly()
|
||||
: $userForm->attachValidationChecks($request);
|
||||
|
||||
$userForm->readInputData();
|
||||
|
||||
if ($userForm->validate()) {
|
||||
$user = $userForm->execute();
|
||||
|
||||
// If this is a newly created user, show role management form.
|
||||
if (!$userId) {
|
||||
$userRoleForm = new UserRoleForm($user->getId(), $user->getFullName());
|
||||
$userRoleForm->initData();
|
||||
return new JSONMessage(true, $userRoleForm->display($request));
|
||||
} else {
|
||||
// Successful edit of an existing user.
|
||||
$notificationManager = new NotificationManager();
|
||||
$user = $request->getUser();
|
||||
$notificationManager->createTrivialNotification($user->getId(), PKPNotification::NOTIFICATION_TYPE_SUCCESS, ['contents' => __('notification.editedUser')]);
|
||||
|
||||
// Prepare the grid row data.
|
||||
return \PKP\db\DAO::getDataChangedEvent($userId);
|
||||
}
|
||||
} else {
|
||||
return new JSONMessage(false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a newly created user's roles
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function updateUserRoles($args, $request)
|
||||
{
|
||||
$user = $request->getUser();
|
||||
|
||||
// Identify the user Id.
|
||||
$userId = $request->getUserVar('userId');
|
||||
|
||||
if ($userId !== null && Validation::getAdministrationLevel($userId, $user->getId()) !== Validation::ADMINISTRATION_FULL) {
|
||||
// We don't have administrative rights over this user.
|
||||
return new JSONMessage(false, __('grid.user.cannotAdminister'));
|
||||
}
|
||||
|
||||
// Form handling.
|
||||
$userRoleForm = new UserRoleForm($userId, $user->getFullName());
|
||||
$userRoleForm->readInputData();
|
||||
|
||||
if ($userRoleForm->validate()) {
|
||||
$userRoleForm->execute();
|
||||
|
||||
// Successfully managed newly created user's roles.
|
||||
return \PKP\db\DAO::getDataChangedEvent();
|
||||
} else {
|
||||
return new JSONMessage(false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit enable/disable user form
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return JSONMessage Serialized JSON object
|
||||
*/
|
||||
public function editDisableUser($args, $request)
|
||||
{
|
||||
$user = $request->getUser();
|
||||
|
||||
// Identify the user Id.
|
||||
$userId = $request->getUserVar('rowId');
|
||||
if (!$userId) {
|
||||
$userId = $request->getUserVar('userId');
|
||||
}
|
||||
|
||||
// Are we enabling or disabling this user.
|
||||
$enable = isset($args['enable']) ? (bool) $args['enable'] : false;
|
||||
|
||||
if ($userId !== null && Validation::getAdministrationLevel($userId, $user->getId()) !== Validation::ADMINISTRATION_FULL) {
|
||||
// We don't have administrative rights over this user.
|
||||
return new JSONMessage(false, __('grid.user.cannotAdminister'));
|
||||
} else {
|
||||
// Form handling
|
||||
$userForm = new UserDisableForm($userId, $enable);
|
||||
|
||||
$userForm->initData();
|
||||
|
||||
return new JSONMessage(true, $userForm->display($request));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable/Disable an existing user
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function disableUser($args, $request)
|
||||
{
|
||||
$user = $request->getUser();
|
||||
|
||||
// Identify the user Id.
|
||||
$userId = $request->getUserVar('userId');
|
||||
|
||||
// Are we enabling or disabling this user.
|
||||
$enable = (bool) $request->getUserVar('enable');
|
||||
|
||||
if ($userId !== null && Validation::getAdministrationLevel($userId, $user->getId()) !== Validation::ADMINISTRATION_FULL) {
|
||||
// We don't have administrative rights over this user.
|
||||
return new JSONMessage(false, __('grid.user.cannotAdminister'));
|
||||
}
|
||||
|
||||
// Form handling.
|
||||
$userForm = new UserDisableForm($userId, $enable);
|
||||
|
||||
$userForm->readInputData();
|
||||
|
||||
if ($userForm->validate()) {
|
||||
$user = $userForm->execute();
|
||||
|
||||
// Successful enable/disable of an existing user.
|
||||
// Update grid data.
|
||||
return \PKP\db\DAO::getDataChangedEvent($userId);
|
||||
} else {
|
||||
return new JSONMessage(false, $userForm->display($request));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all user group assignments for a context for a given user.
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function removeUser($args, $request)
|
||||
{
|
||||
if (!$request->checkCSRF()) {
|
||||
return new JSONMessage(false);
|
||||
}
|
||||
|
||||
$context = $request->getContext();
|
||||
$user = $request->getUser();
|
||||
|
||||
// Identify the user Id.
|
||||
$userId = $request->getUserVar('rowId');
|
||||
|
||||
if ($userId !== null && Validation::getAdministrationLevel($userId, $user->getId(), $request->getContext()->getId()) === Validation::ADMINISTRATION_PROHIBITED) {
|
||||
// We don't have administrative rights over this user.
|
||||
return new JSONMessage(false, __('grid.user.cannotAdminister'));
|
||||
}
|
||||
|
||||
// Remove user from all user group assignments for this context.
|
||||
// Check if this user has any user group assignments for this context.
|
||||
$userGroupCount = Repo::userGroup()
|
||||
->userUserGroups($userId, $context->getId())
|
||||
->count();
|
||||
|
||||
if (!$userGroupCount) {
|
||||
return new JSONMessage(false, __('grid.user.userNoRoles'));
|
||||
} else {
|
||||
Repo::userGroup()->deleteAssignmentsByContextId($context->getId(), $userId);
|
||||
|
||||
return \PKP\db\DAO::getDataChangedEvent($userId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays a modal to edit an email message to the user.
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return JSONMessage Serialized JSON object
|
||||
*/
|
||||
public function editEmail($args, $request)
|
||||
{
|
||||
$user = $request->getUser();
|
||||
$context = $request->getContext();
|
||||
|
||||
// Identify the user Id.
|
||||
$userId = $request->getUserVar('rowId');
|
||||
|
||||
$roleDao = DAORegistry::getDAO('RoleDAO'); /** @var RoleDAO $roleDao */
|
||||
if (
|
||||
!$roleDao->userHasRole(\PKP\core\PKPApplication::CONTEXT_SITE, $user->getId(), Role::ROLE_ID_SITE_ADMIN) && !(
|
||||
$context &&
|
||||
$roleDao->userHasRole($context->getId(), $user->getId(), Role::ROLE_ID_MANAGER)
|
||||
)
|
||||
) {
|
||||
// We don't have administrative rights over this user.
|
||||
return new JSONMessage(false, __('grid.user.cannotAdminister'));
|
||||
} else {
|
||||
// Form handling.
|
||||
$userEmailForm = new UserEmailForm($userId);
|
||||
$userEmailForm->initData();
|
||||
|
||||
return new JSONMessage(true, $userEmailForm->fetch($request));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the user email and close the modal.
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function sendEmail($args, $request)
|
||||
{
|
||||
$user = $request->getUser();
|
||||
$context = $request->getContext();
|
||||
|
||||
// Identify the user Id.
|
||||
$userId = $request->getUserVar('userId');
|
||||
|
||||
$roleDao = DAORegistry::getDAO('RoleDAO'); /** @var RoleDAO $roleDao */
|
||||
if (
|
||||
!$roleDao->userHasRole(\PKP\core\PKPApplication::CONTEXT_SITE, $user->getId(), Role::ROLE_ID_SITE_ADMIN) && !(
|
||||
$context &&
|
||||
$roleDao->userHasRole($context->getId(), $user->getId(), Role::ROLE_ID_MANAGER)
|
||||
)
|
||||
) {
|
||||
// We don't have administrative rights over this user.
|
||||
return new JSONMessage(false, __('grid.user.cannotAdminister'));
|
||||
}
|
||||
// Form handling.
|
||||
$userEmailForm = new UserEmailForm($userId);
|
||||
$userEmailForm->readInputData();
|
||||
|
||||
if ($userEmailForm->validate()) {
|
||||
$userEmailForm->execute();
|
||||
return new JSONMessage(true);
|
||||
} else {
|
||||
return new JSONMessage(false, __('validator.filled'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow user account merging, including attributed submissions etc.
|
||||
*
|
||||
* @param array $args
|
||||
* @param PKPRequest $request
|
||||
*
|
||||
* @return JSONMessage JSON object
|
||||
*/
|
||||
public function mergeUsers($args, $request)
|
||||
{
|
||||
$newUserId = (int) $request->getUserVar('newUserId');
|
||||
$oldUserId = (int) $request->getUserVar('oldUserId');
|
||||
$user = $request->getUser();
|
||||
|
||||
// if there is a $newUserId, this is the second time through, so merge the users.
|
||||
if ($newUserId > 0 && $oldUserId > 0 && Validation::getAdministrationLevel($oldUserId, $user->getId()) === Validation::ADMINISTRATION_FULL) {
|
||||
if (!$request->checkCSRF()) {
|
||||
return new JSONMessage(false);
|
||||
}
|
||||
Repo::user()->mergeUsers($oldUserId, $newUserId);
|
||||
$json = new JSONMessage(true);
|
||||
$json->setGlobalEvent('userMerged', [
|
||||
'oldUserId' => $oldUserId,
|
||||
'newUserId' => $newUserId,
|
||||
]);
|
||||
return $json;
|
||||
|
||||
// Otherwise present the grid for selecting the user to merge into
|
||||
} else {
|
||||
$userGrid = new UserGridHandler();
|
||||
$userGrid->initialize($request);
|
||||
$userGrid->setTitle('grid.user.mergeUsers.mergeIntoUser');
|
||||
return $userGrid->fetchGrid($args, $request);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see GridHandler::getRequestArgs()
|
||||
*/
|
||||
public function getRequestArgs()
|
||||
{
|
||||
$requestArgs = parent::getRequestArgs();
|
||||
$requestArgs['oldUserId'] = $this->_oldUserId;
|
||||
return $requestArgs;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,227 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/settings/user/UserGridRow.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 UserGridRow
|
||||
*
|
||||
* @ingroup controllers_grid_settings_user
|
||||
*
|
||||
* @brief User grid row definition
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\settings\user;
|
||||
|
||||
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\RedirectConfirmationModal;
|
||||
use PKP\linkAction\request\RemoteActionConfirmationModal;
|
||||
use PKP\security\Validation;
|
||||
|
||||
class UserGridRow extends GridRow
|
||||
{
|
||||
/** @var int the user id of the old user to remove when merging users. */
|
||||
public $_oldUserId;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param null|mixed $oldUserId
|
||||
*/
|
||||
public function __construct($oldUserId = null)
|
||||
{
|
||||
$this->_oldUserId = $oldUserId;
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// 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, 'User'));
|
||||
|
||||
$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());
|
||||
|
||||
// If this is the grid for merging a user, only show the merge
|
||||
// linkaction
|
||||
if ($this->getOldUserId()) {
|
||||
$actionArgs['oldUserId'] = $this->getOldUserId();
|
||||
$actionArgs['newUserId'] = $rowId;
|
||||
|
||||
// Verify that the old user exists
|
||||
$oldUser = Repo::user()->get((int) $this->getOldUserId(), true);
|
||||
|
||||
// Don't merge a user in itself
|
||||
if ($oldUser && $actionArgs['oldUserId'] != $actionArgs['newUserId']) {
|
||||
$this->addAction(
|
||||
new LinkAction(
|
||||
'mergeUser',
|
||||
new RemoteActionConfirmationModal(
|
||||
$request->getSession(),
|
||||
__('grid.user.mergeUsers.confirm', ['oldUsername' => $oldUser->getUsername(), 'newUsername' => $element->getUsername()]),
|
||||
null,
|
||||
$router->url($request, null, null, 'mergeUsers', null, $actionArgs),
|
||||
'modal_merge_users'
|
||||
),
|
||||
__('grid.user.mergeUsers.mergeIntoUser'),
|
||||
'merge_users'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Otherwise display all the default link actions
|
||||
} else {
|
||||
$this->addAction(
|
||||
new LinkAction(
|
||||
'email',
|
||||
new AjaxModal(
|
||||
$router->url($request, null, null, 'editEmail', null, $actionArgs),
|
||||
__('grid.user.email'),
|
||||
'modal_email',
|
||||
true
|
||||
),
|
||||
__('grid.user.email'),
|
||||
'notify'
|
||||
)
|
||||
);
|
||||
$this->addAction(
|
||||
new LinkAction(
|
||||
'edit',
|
||||
new AjaxModal(
|
||||
$router->url($request, null, null, 'editUser', null, $actionArgs),
|
||||
__('grid.user.edit'),
|
||||
'modal_edit',
|
||||
true
|
||||
),
|
||||
__('grid.user.edit'),
|
||||
'edit'
|
||||
)
|
||||
);
|
||||
if ($element->getDisabled()) {
|
||||
$actionArgs['enable'] = true;
|
||||
$this->addAction(
|
||||
new LinkAction(
|
||||
'enable',
|
||||
new AjaxModal(
|
||||
$router->url($request, null, null, 'editDisableUser', null, $actionArgs),
|
||||
__('common.enable'),
|
||||
'enable',
|
||||
true
|
||||
),
|
||||
__('common.enable'),
|
||||
'enable'
|
||||
)
|
||||
);
|
||||
} else {
|
||||
$actionArgs['enable'] = false;
|
||||
$this->addAction(
|
||||
new LinkAction(
|
||||
'disable',
|
||||
new AjaxModal(
|
||||
$router->url($request, null, null, 'editDisableUser', null, $actionArgs),
|
||||
__('grid.user.disable'),
|
||||
'disable',
|
||||
true
|
||||
),
|
||||
__('grid.user.disable'),
|
||||
'disable'
|
||||
)
|
||||
);
|
||||
}
|
||||
$this->addAction(
|
||||
new LinkAction(
|
||||
'remove',
|
||||
new RemoteActionConfirmationModal(
|
||||
$request->getSession(),
|
||||
__('manager.people.confirmRemove'),
|
||||
__('common.remove'),
|
||||
$router->url($request, null, null, 'removeUser', null, $actionArgs),
|
||||
'modal_delete'
|
||||
),
|
||||
__('grid.action.remove'),
|
||||
'delete'
|
||||
)
|
||||
);
|
||||
|
||||
$canAdminister = Validation::getAdministrationLevel($this->getId(), $request->getUser()->getId()) === Validation::ADMINISTRATION_FULL;
|
||||
if (
|
||||
!Validation::loggedInAs() &&
|
||||
$request->getUser()->getId() != $this->getId() &&
|
||||
$canAdminister
|
||||
) {
|
||||
$dispatcher = $router->getDispatcher();
|
||||
$this->addAction(
|
||||
new LinkAction(
|
||||
'logInAs',
|
||||
new RedirectConfirmationModal(
|
||||
__('grid.user.confirmLogInAs'),
|
||||
__('grid.action.logInAs'),
|
||||
$dispatcher->url($request, PKPApplication::ROUTE_PAGE, null, 'login', 'signInAsUser', $this->getId())
|
||||
),
|
||||
__('grid.action.logInAs'),
|
||||
'enroll_user'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// do not allow the deletion of your own account.
|
||||
if (
|
||||
$request->getUser()->getId() != $this->getId() and
|
||||
$canAdminister
|
||||
) {
|
||||
$this->addAction(
|
||||
new LinkAction(
|
||||
'mergeUser',
|
||||
new AjaxModal(
|
||||
$router->url($request, null, null, 'mergeUsers', null, ['oldUserId' => $rowId]),
|
||||
__('grid.user.mergeUsers.mergeUser'),
|
||||
'modal_merge_users',
|
||||
true
|
||||
),
|
||||
__('grid.user.mergeUsers.mergeUser'),
|
||||
'merge_users'
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the stored user id of the user to be removed.
|
||||
*
|
||||
* @return int the user id.
|
||||
*/
|
||||
public function getOldUserId()
|
||||
{
|
||||
return $this->_oldUserId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,406 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/settings/user/form/UserDetailsForm.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 UserDetailsForm
|
||||
*
|
||||
* @ingroup controllers_grid_settings_user_form
|
||||
*
|
||||
* @brief Form for editing user profiles.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\settings\user\form;
|
||||
|
||||
use APP\author\Author;
|
||||
use APP\core\Application;
|
||||
use APP\facades\Repo;
|
||||
use APP\notification\NotificationManager;
|
||||
use APP\template\TemplateManager;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use PKP\core\Core;
|
||||
use PKP\core\PKPRequest;
|
||||
use PKP\core\PKPString;
|
||||
use PKP\facades\Locale;
|
||||
use PKP\identity\Identity;
|
||||
use PKP\mail\mailables\UserCreated;
|
||||
use PKP\notification\PKPNotification;
|
||||
use PKP\security\Validation;
|
||||
use PKP\session\SessionManager;
|
||||
use PKP\user\InterestManager;
|
||||
use PKP\user\User;
|
||||
use Symfony\Component\Mailer\Exception\TransportException;
|
||||
|
||||
class UserDetailsForm extends UserForm
|
||||
{
|
||||
/** @var User */
|
||||
public $user;
|
||||
|
||||
/** @var Author An optional author to base this user on */
|
||||
public $author;
|
||||
|
||||
/** @var bool An internal use flag that allows to determine the update only for user group */
|
||||
protected bool $userGroupUpdateOnly = false;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param PKPRequest $request
|
||||
* @param int $userId optional
|
||||
* @param Author $author optional
|
||||
*/
|
||||
public function __construct($request, $userId = null, $author = null)
|
||||
{
|
||||
parent::__construct('controllers/grid/settings/user/form/userDetailsForm.tpl', $userId);
|
||||
|
||||
if (isset($author)) {
|
||||
$this->author = & $author;
|
||||
} else {
|
||||
$this->author = null;
|
||||
}
|
||||
|
||||
// the users register for the site, thus
|
||||
// the site primary locale is the required default locale
|
||||
$this->addSupportedFormLocale($request->getSite()->getPrimaryLocale());
|
||||
|
||||
if ($userId !== null) {
|
||||
$this->user = Repo::user()->get($userId, true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attach the validation checks for this form
|
||||
*
|
||||
* @param PKPRequest|null $request
|
||||
*/
|
||||
public function attachValidationChecks($request = null): self
|
||||
{
|
||||
$request ??= Application::get()->getRequest();
|
||||
$site = $request->getSite();
|
||||
$form = $this;
|
||||
|
||||
if (!$this->user) {
|
||||
$this->addCheck(new \PKP\form\validation\FormValidator($this, 'username', 'required', 'user.profile.form.usernameRequired'));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorCustom($this, 'username', 'required', 'user.register.form.usernameExists', function ($username, $userId) {
|
||||
$user = Repo::user()->getByUsername($username, true);
|
||||
return !$user || $user->getId() == $userId;
|
||||
}, [$this->userId]));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorUsername($this, 'username', 'required', 'user.register.form.usernameAlphaNumeric'));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidator($this, 'password', 'required', 'user.profile.form.passwordRequired'));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorCustom($this, 'password', 'required', 'user.register.form.passwordLengthRestriction', function ($password) use ($form, $site) {
|
||||
return $form->getData('generatePassword') || PKPString::strlen($password) >= $site->getMinPasswordLength();
|
||||
}, [], false, ['length' => $site->getMinPasswordLength()]));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorCustom($this, 'password', 'required', 'user.register.form.passwordsDoNotMatch', function ($password) use ($form) {
|
||||
return $password == $form->getData('password2');
|
||||
}));
|
||||
} else {
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorCustom($this, 'password', 'optional', 'user.register.form.passwordLengthRestriction', function ($password) use ($form, $site) {
|
||||
return $form->getData('generatePassword') || PKPString::strlen($password) >= $site->getMinPasswordLength();
|
||||
}, [], false, ['length' => $site->getMinPasswordLength()]));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorCustom($this, 'password', 'optional', 'user.register.form.passwordsDoNotMatch', function ($password) use ($form) {
|
||||
return $password == $form->getData('password2');
|
||||
}));
|
||||
}
|
||||
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorLocale($this, 'givenName', 'required', 'user.profile.form.givenNameRequired', $site->getPrimaryLocale()));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorCustom($this, 'familyName', 'optional', 'user.profile.form.givenNameRequired.locale', function ($familyName) use ($form) {
|
||||
$givenNames = $form->getData('givenName');
|
||||
foreach ($familyName as $locale => $value) {
|
||||
if (!empty($value) && empty($givenNames[$locale])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorUrl($this, 'userUrl', 'optional', 'user.profile.form.urlInvalid'));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorEmail($this, 'email', 'required', 'user.profile.form.emailRequired'));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorCustom($this, 'email', 'required', 'user.register.form.emailExists', function ($email, $currentUserId) {
|
||||
$user = Repo::user()->getByEmail($email, true);
|
||||
return !$user || $user->getId() == $currentUserId;
|
||||
}, [$this->userId]));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorORCID($this, 'orcid', 'optional', 'user.orcid.orcidInvalid'));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorPost($this));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorCSRF($this));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the update only for user's user group
|
||||
*
|
||||
*/
|
||||
public function applyUserGroupUpdateOnly(): self
|
||||
{
|
||||
$this->userGroupUpdateOnly = true;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize form data from current user profile.
|
||||
*/
|
||||
public function initData()
|
||||
{
|
||||
$request = Application::get()->getRequest();
|
||||
$templateMgr = TemplateManager::getManager($request);
|
||||
|
||||
$templateMgr->assign('site', $request->getSite());
|
||||
|
||||
$data = [];
|
||||
|
||||
if (isset($this->user)) {
|
||||
$user = $this->user;
|
||||
$templateMgr->assign('user', $user);
|
||||
$interestManager = new InterestManager();
|
||||
|
||||
$data = [
|
||||
'username' => $user->getUsername(),
|
||||
'givenName' => $user->getGivenName(null), // Localized
|
||||
'familyName' => $user->getFamilyName(null), // Localized
|
||||
'preferredPublicName' => $user->getPreferredPublicName(null), // Localized
|
||||
'signature' => $user->getSignature(null), // Localized
|
||||
'affiliation' => $user->getAffiliation(null), // Localized
|
||||
'email' => $user->getEmail(),
|
||||
'userUrl' => $user->getUrl(),
|
||||
'phone' => $user->getPhone(),
|
||||
'orcid' => $user->getOrcid(),
|
||||
'mailingAddress' => $user->getMailingAddress(),
|
||||
'country' => $user->getCountry(),
|
||||
'biography' => $user->getBiography(null), // Localized
|
||||
'interests' => $interestManager->getInterestsForUser($user),
|
||||
'locales' => $user->getLocales(),
|
||||
];
|
||||
$data['canCurrentUserGossip'] = Repo::user()->canCurrentUserGossip($user->getId());
|
||||
if ($data['canCurrentUserGossip']) {
|
||||
$data['gossip'] = $user->getGossip();
|
||||
}
|
||||
} elseif (isset($this->author)) {
|
||||
$author = $this->author;
|
||||
$templateMgr->assign('user', $author);
|
||||
$data = [
|
||||
'givenName' => $author->getGivenName(null), // Localized
|
||||
'familyName' => $author->getFamilyName(null), // Localized
|
||||
'affiliation' => $author->getAffiliation(null), // Localized
|
||||
'preferredPublicName' => $author->getPreferredPublicName(null), // Localized
|
||||
'email' => $author->getEmail(),
|
||||
'userUrl' => $author->getUrl(),
|
||||
'orcid' => $author->getOrcid(),
|
||||
'country' => $author->getCountry(),
|
||||
'biography' => $author->getBiography(null), // Localized
|
||||
];
|
||||
} else {
|
||||
$data = [
|
||||
'mustChangePassword' => true,
|
||||
];
|
||||
}
|
||||
foreach ($data as $key => $value) {
|
||||
$this->setData($key, $value);
|
||||
}
|
||||
|
||||
parent::initData();
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc UserForm::display
|
||||
*
|
||||
* @param null|mixed $request
|
||||
* @param null|mixed $template
|
||||
*/
|
||||
public function display($request = null, $template = null)
|
||||
{
|
||||
$site = $request->getSite();
|
||||
$countries = [];
|
||||
foreach (Locale::getCountries() as $country) {
|
||||
$countries[$country->getAlpha2()] = $country->getLocalName();
|
||||
}
|
||||
asort($countries);
|
||||
$templateMgr = TemplateManager::getManager($request);
|
||||
|
||||
$templateMgr->assign([
|
||||
'minPasswordLength' => $site->getMinPasswordLength(),
|
||||
'source' => $request->getUserVar('source'),
|
||||
'userId' => $this->userId,
|
||||
'sitePrimaryLocale' => $site->getPrimaryLocale(),
|
||||
'availableLocales' => $site->getSupportedLocaleNames(),
|
||||
'countries' => $countries,
|
||||
'userGroupUpdateOnly' => $this->userGroupUpdateOnly,
|
||||
]);
|
||||
|
||||
if (isset($this->user)) {
|
||||
$templateMgr->assign('username', $this->user->getUsername());
|
||||
}
|
||||
|
||||
return parent::display($request, $template);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Assign form data to user-submitted data.
|
||||
*
|
||||
* @see Form::readInputData()
|
||||
*/
|
||||
public function readInputData()
|
||||
{
|
||||
parent::readInputData();
|
||||
|
||||
// if doing only a partial update that includes only updating user's user group
|
||||
if ($this->userGroupUpdateOnly) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->readUserVars([
|
||||
'password',
|
||||
'password2',
|
||||
'givenName',
|
||||
'familyName',
|
||||
'preferredPublicName',
|
||||
'signature',
|
||||
'affiliation',
|
||||
'email',
|
||||
'userUrl',
|
||||
'phone',
|
||||
'orcid',
|
||||
'mailingAddress',
|
||||
'country',
|
||||
'biography',
|
||||
'gossip',
|
||||
'interests',
|
||||
'locales',
|
||||
'generatePassword',
|
||||
'sendNotify',
|
||||
'mustChangePassword'
|
||||
]);
|
||||
if ($this->userId == null) {
|
||||
$this->readUserVars(['username']);
|
||||
}
|
||||
|
||||
if ($this->getData('locales') == null || !is_array($this->getData('locales'))) {
|
||||
$this->setData('locales', []);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all locale field names
|
||||
*/
|
||||
public function getLocaleFieldNames()
|
||||
{
|
||||
return ['biography', 'signature', 'affiliation', Identity::IDENTITY_SETTING_GIVENNAME, Identity::IDENTITY_SETTING_FAMILYNAME, 'preferredPublicName'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Create or update a user.
|
||||
*/
|
||||
public function execute(...$functionParams)
|
||||
{
|
||||
$request = Application::get()->getRequest();
|
||||
$context = $request->getContext();
|
||||
|
||||
if (!isset($this->user)) {
|
||||
$this->user = Repo::user()->newDataObject();
|
||||
$this->user->setInlineHelp(1); // default new users to having inline help visible
|
||||
}
|
||||
|
||||
//save the user's user group assignment
|
||||
$this->saveUserGroupAssignments($request);
|
||||
|
||||
// if doing only a partial update that includes only updating user's user group
|
||||
if ($this->userGroupUpdateOnly) {
|
||||
parent::execute(...$functionParams);
|
||||
return $this->user;
|
||||
}
|
||||
|
||||
$this->user->setGivenName($this->getData('givenName'), null); // Localized
|
||||
$this->user->setFamilyName($this->getData('familyName'), null); // Localized
|
||||
$this->user->setPreferredPublicName($this->getData('preferredPublicName'), null); // Localized
|
||||
$this->user->setAffiliation($this->getData('affiliation'), null); // Localized
|
||||
$this->user->setSignature($this->getData('signature'), null); // Localized
|
||||
$this->user->setEmail($this->getData('email'));
|
||||
$this->user->setUrl($this->getData('userUrl'));
|
||||
$this->user->setPhone($this->getData('phone'));
|
||||
$this->user->setOrcid($this->getData('orcid'));
|
||||
$this->user->setMailingAddress($this->getData('mailingAddress'));
|
||||
$this->user->setCountry($this->getData('country'));
|
||||
$this->user->setBiography($this->getData('biography'), null); // Localized
|
||||
$this->user->setMustChangePassword($this->getData('mustChangePassword') ? 1 : 0);
|
||||
|
||||
// Users can never view/edit their own gossip fields
|
||||
if (Repo::user()->canCurrentUserGossip($this->user->getId())) {
|
||||
$this->user->setGossip($this->getData('gossip'));
|
||||
}
|
||||
|
||||
$site = $request->getSite();
|
||||
$availableLocales = $site->getSupportedLocales();
|
||||
|
||||
$locales = [];
|
||||
foreach ($this->getData('locales') as $locale) {
|
||||
if (Locale::isLocaleValid($locale) && in_array($locale, $availableLocales)) {
|
||||
array_push($locales, $locale);
|
||||
}
|
||||
}
|
||||
$this->user->setLocales($locales);
|
||||
|
||||
parent::execute(...$functionParams);
|
||||
|
||||
if ($this->user->getId() != null) {
|
||||
if ($this->getData('password') !== '') {
|
||||
$this->user->setPassword(Validation::encryptCredentials($this->user->getUsername(), $this->getData('password')));
|
||||
|
||||
$sessionManager = SessionManager::getManager();
|
||||
$sessionManager->invalidateSessions(
|
||||
$this->user->getId(),
|
||||
(int) $this->user->getId() === (int) $request->getUser()->getId()
|
||||
? $sessionManager->getUserSession()->getId()
|
||||
: null
|
||||
);
|
||||
}
|
||||
|
||||
Repo::user()->edit($this->user);
|
||||
} else {
|
||||
$this->user->setUsername($this->getData('username'));
|
||||
if ($this->getData('generatePassword')) {
|
||||
$password = Validation::generatePassword();
|
||||
$sendNotify = true;
|
||||
} else {
|
||||
$password = $this->getData('password');
|
||||
$sendNotify = $this->getData('sendNotify');
|
||||
}
|
||||
|
||||
$this->user->setPassword(Validation::encryptCredentials($this->getData('username'), $password));
|
||||
|
||||
$this->user->setDateRegistered(Core::getCurrentDate());
|
||||
Repo::user()->add($this->user);
|
||||
|
||||
if ($sendNotify) {
|
||||
// Send welcome email to user
|
||||
$mailable = new UserCreated($context, $password);
|
||||
$mailable->recipients($this->user);
|
||||
$mailable->sender($request->getUser());
|
||||
$mailable->replyTo($context->getData('contactEmail'), $context->getData('contactName'));
|
||||
$template = Repo::emailTemplate()->getByKey($context->getId(), UserCreated::getEmailTemplateKey());
|
||||
$mailable->body($template->getLocalizedData('body'));
|
||||
$mailable->subject($template->getLocalizedData('subject'));
|
||||
|
||||
try {
|
||||
Mail::send($mailable);
|
||||
} catch (TransportException $e) {
|
||||
$notificationMgr = new NotificationManager();
|
||||
$notificationMgr->createTrivialNotification(
|
||||
$request->getUser()->getId(),
|
||||
PKPNotification::NOTIFICATION_TYPE_ERROR,
|
||||
['contents' => __('email.compose.error')]
|
||||
);
|
||||
error_log($e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$interestManager = new InterestManager();
|
||||
$interestManager->setInterestsForUser($this->user, $this->getData('interests'));
|
||||
|
||||
return $this->user;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/settings/user/form/UserDisableForm.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 UserDisableForm
|
||||
*
|
||||
* @ingroup controllers_grid_settings_user_form
|
||||
*
|
||||
* @brief Form for enabling/disabling a user
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\settings\user\form;
|
||||
|
||||
use APP\facades\Repo;
|
||||
use APP\template\TemplateManager;
|
||||
use PKP\form\Form;
|
||||
use PKP\db\DAORegistry;
|
||||
|
||||
class UserDisableForm extends Form
|
||||
{
|
||||
/** @var int The user id of user to enable/disable */
|
||||
public $_userId;
|
||||
|
||||
/** @var bool Whether to enable or disable the user */
|
||||
public $_enable;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct($userId, $enable = false)
|
||||
{
|
||||
parent::__construct('controllers/grid/settings/user/form/userDisableForm.tpl');
|
||||
|
||||
$this->_userId = (int) $userId;
|
||||
$this->_enable = (bool) $enable;
|
||||
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorPost($this));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorCSRF($this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize form data.
|
||||
*/
|
||||
public function initData()
|
||||
{
|
||||
if ($this->_userId) {
|
||||
$user = Repo::user()->get($this->_userId, true);
|
||||
|
||||
if ($user) {
|
||||
$this->_data = [
|
||||
'disableReason' => $user->getDisabledReason()
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign form data to user-submitted data.
|
||||
*
|
||||
* @see Form::readInputData()
|
||||
*/
|
||||
public function readInputData()
|
||||
{
|
||||
$this->readUserVars(
|
||||
[
|
||||
'disableReason',
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::display
|
||||
*
|
||||
* @param null|mixed $request
|
||||
* @param null|mixed $template
|
||||
*/
|
||||
public function display($request = null, $template = null)
|
||||
{
|
||||
$templateMgr = TemplateManager::getManager($request);
|
||||
$templateMgr->assign([
|
||||
'userId' => $this->_userId,
|
||||
'enable' => $this->_enable,
|
||||
]);
|
||||
return $this->fetch($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::execute()
|
||||
*/
|
||||
public function execute(...$functionArgs)
|
||||
{
|
||||
$user = Repo::user()->get($this->_userId, true);
|
||||
|
||||
if ($user) {
|
||||
$user->setDisabled($this->_enable ? false : true);
|
||||
$user->setDisabledReason($this->getData('disableReason'));
|
||||
Repo::user()->edit($user);
|
||||
if ($user->getDisabled()) {
|
||||
$sessionDao = DAORegistry::getDAO('SessionDAO');
|
||||
$sessionDao->deleteByUserId($user->getId());
|
||||
}
|
||||
}
|
||||
parent::execute(...$functionArgs);
|
||||
return $user;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/settings/user/form/UserEmailForm.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 UserEmailForm
|
||||
*
|
||||
* @ingroup controllers_grid_settings_user_form
|
||||
*
|
||||
* @brief Form for sending an email to a user
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\settings\user\form;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\facades\Repo;
|
||||
use APP\notification\NotificationManager;
|
||||
use APP\template\TemplateManager;
|
||||
use Exception;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use PKP\form\Form;
|
||||
use PKP\mail\Mailable;
|
||||
use PKP\notification\PKPNotification;
|
||||
|
||||
class UserEmailForm extends Form
|
||||
{
|
||||
/** @var int The user id of user to send email to */
|
||||
public $userId;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param int $userId User ID to contact.
|
||||
*/
|
||||
public function __construct($userId)
|
||||
{
|
||||
parent::__construct('controllers/grid/settings/user/form/userEmailForm.tpl');
|
||||
|
||||
$this->userId = (int) $userId;
|
||||
|
||||
$this->addCheck(new \PKP\form\validation\FormValidator($this, 'subject', 'required', 'email.subjectRequired'));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidator($this, 'message', 'required', 'email.bodyRequired'));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorPost($this));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorCSRF($this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign form data to user-submitted data.
|
||||
*
|
||||
* @see Form::readInputData()
|
||||
*/
|
||||
public function readInputData()
|
||||
{
|
||||
$this->readUserVars([
|
||||
'subject',
|
||||
'message',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::Fetch
|
||||
*
|
||||
* @param null|mixed $template
|
||||
*/
|
||||
public function fetch($request, $template = null, $display = false)
|
||||
{
|
||||
$user = Repo::user()->get($this->userId);
|
||||
|
||||
$templateMgr = TemplateManager::getManager($request);
|
||||
$templateMgr->assign([
|
||||
'userId' => $this->userId,
|
||||
'userFullName' => $user->getFullName(),
|
||||
'userEmail' => $user->getEmail(),
|
||||
]);
|
||||
|
||||
return parent::fetch($request, $template, $display);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the email
|
||||
*
|
||||
* @copydoc Form::execute()
|
||||
*/
|
||||
public function execute(...$functionArgs)
|
||||
{
|
||||
$toUser = Repo::user()->get($this->userId);
|
||||
$request = Application::get()->getRequest();
|
||||
$fromUser = $request->getUser();
|
||||
|
||||
$mailable = new Mailable();
|
||||
$mailable
|
||||
->from($fromUser->getEmail(), $fromUser->getFullName())
|
||||
->to($toUser->getEmail(), $toUser->getFullName())
|
||||
->subject($this->getData('subject'))
|
||||
->body($this->getData('message'));
|
||||
|
||||
parent::execute(...$functionArgs);
|
||||
|
||||
try {
|
||||
Mail::send($mailable);
|
||||
} catch (Exception $e) {
|
||||
$notificationMgr = new NotificationManager();
|
||||
$notificationMgr->createTrivialNotification(
|
||||
$request->getUser()->getId(),
|
||||
PKPNotification::NOTIFICATION_TYPE_ERROR,
|
||||
['contents' => __('email.compose.error')]
|
||||
);
|
||||
error_log($e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/settings/user/form/UserForm.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 UserForm
|
||||
*
|
||||
* @ingroup controllers_grid_settings_user_form
|
||||
*
|
||||
* @brief Base class for user forms.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\settings\user\form;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\core\Request;
|
||||
use APP\facades\Repo;
|
||||
use APP\template\TemplateManager;
|
||||
use PKP\form\Form;
|
||||
|
||||
class UserForm extends Form
|
||||
{
|
||||
/** @var int Id of the user being edited */
|
||||
public $userId;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param int $userId optional
|
||||
*/
|
||||
public function __construct($template, $userId = null)
|
||||
{
|
||||
parent::__construct($template);
|
||||
|
||||
$this->userId = isset($userId) ? (int) $userId : null;
|
||||
|
||||
if (!is_null($userId)) {
|
||||
$this->addCheck(new \PKP\form\validation\FormValidator($this, 'userGroupIds', 'required', 'manager.users.roleRequired'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize form data from current user profile.
|
||||
*/
|
||||
public function initData()
|
||||
{
|
||||
$userGroupIds = [];
|
||||
|
||||
if (!is_null($this->userId)) {
|
||||
$userGroups = Repo::userGroup()->userUserGroups($this->userId);
|
||||
|
||||
foreach ($userGroups as $userGroup) {
|
||||
$userGroupIds[] = $userGroup->getId();
|
||||
}
|
||||
}
|
||||
|
||||
$this->setData('userGroupIds', $userGroupIds);
|
||||
|
||||
|
||||
parent::initData();
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::readInputData()
|
||||
*/
|
||||
public function readInputData()
|
||||
{
|
||||
$this->readUserVars(['userGroupIds']);
|
||||
parent::readInputData();
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::display
|
||||
*
|
||||
* @param null|mixed $request
|
||||
* @param null|mixed $template
|
||||
*/
|
||||
public function display($request = null, $template = null)
|
||||
{
|
||||
$context = $request->getContext();
|
||||
$contextId = $context ? $context->getId() : \PKP\core\PKPApplication::CONTEXT_ID_NONE;
|
||||
$templateMgr = TemplateManager::getManager($request);
|
||||
|
||||
$allUserGroups = [];
|
||||
|
||||
$userGroups = Repo::userGroup()->getCollector()
|
||||
->filterByContextIds([$contextId])
|
||||
->getMany();
|
||||
|
||||
foreach ($userGroups as $userGroup) {
|
||||
$allUserGroups[(int) $userGroup->getId()] = $userGroup->getLocalizedName();
|
||||
}
|
||||
|
||||
$templateMgr->assign([
|
||||
'allUserGroups' => $allUserGroups,
|
||||
'assignedUserGroups' => array_map('intval', $this->getData('userGroupIds')),
|
||||
]);
|
||||
|
||||
return $this->fetch($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc Form::execute()
|
||||
*/
|
||||
public function execute(...$functionArgs)
|
||||
{
|
||||
parent::execute(...$functionArgs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the user group assignments
|
||||
*/
|
||||
public function saveUserGroupAssignments(Request $request): void
|
||||
{
|
||||
if (!isset($this->userId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Repo::userGroup()
|
||||
->deleteAssignmentsByContextId(
|
||||
Application::get()->getRequest()->getContext()->getId(),
|
||||
$this->userId
|
||||
);
|
||||
|
||||
|
||||
if ($this->getData('userGroupIds')) {
|
||||
$contextId = $request->getContext()->getId();
|
||||
|
||||
collect($this->getData('userGroupIds'))
|
||||
->each(
|
||||
fn ($userGroupId) =>
|
||||
Repo::userGroup()->contextHasGroup($contextId, $userGroupId)
|
||||
? Repo::userGroup()->assignUserToGroup($this->userId, $userGroupId)
|
||||
: null
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file controllers/grid/settings/user/form/UserRoleForm.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 UserRoleForm
|
||||
*
|
||||
* @ingroup controllers_grid_settings_user_form
|
||||
*
|
||||
* @brief Form for managing roles for a newly created user.
|
||||
*/
|
||||
|
||||
namespace PKP\controllers\grid\settings\user\form;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\facades\Repo;
|
||||
use APP\template\TemplateManager;
|
||||
|
||||
class UserRoleForm extends UserForm
|
||||
{
|
||||
/** @var string User full name */
|
||||
public $_userFullName;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param int $userId
|
||||
* @param string $userFullName
|
||||
*/
|
||||
public function __construct($userId, $userFullName)
|
||||
{
|
||||
parent::__construct('controllers/grid/settings/user/form/userRoleForm.tpl', $userId);
|
||||
|
||||
$this->_userFullName = $userFullName;
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorPost($this));
|
||||
$this->addCheck(new \PKP\form\validation\FormValidatorCSRF($this));
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc UserForm::display
|
||||
*
|
||||
* @param null|mixed $request
|
||||
* @param null|mixed $template
|
||||
*/
|
||||
public function display($request = null, $template = null)
|
||||
{
|
||||
$templateMgr = TemplateManager::getManager($request);
|
||||
$templateMgr->assign([
|
||||
'userId' => $this->userId,
|
||||
'userFullName' => $this->_userFullName,
|
||||
]);
|
||||
return parent::display($request, $template);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update user's roles.
|
||||
*/
|
||||
public function execute(...$functionParams)
|
||||
{
|
||||
$request = Application::get()->getRequest();
|
||||
|
||||
//save the user's user group assignment
|
||||
$this->saveUserGroupAssignments($request);
|
||||
|
||||
parent::execute(...$functionParams);
|
||||
|
||||
// Role management handled by parent form, just return user.
|
||||
return Repo::user()->get($this->userId);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user