687 lines
21 KiB
PHP
687 lines
21 KiB
PHP
<?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;
|
|
}
|
|
}
|