first commit
This commit is contained in:
@@ -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