One Hat Cyber Team
Your IP :
216.73.216.182
Server IP :
203.175.9.166
Server :
Linux tanggamus.iixcp.rumahweb.net 5.14.0-427.28.1.el9_4.x86_64 #1 SMP PREEMPT_DYNAMIC Fri Aug 2 03:44:10 EDT 2024 x86_64
Server Software :
LiteSpeed
PHP Version :
7.4.33
Buat File
|
Buat Folder
Eksekusi
Dir :
~
/
home
/
cite5577
/
www
/
lib
/
pkp
/
classes
/
security
/
View File Name :
UserGroupDAO.inc.php
<?php /** * @file classes/security/UserGroupDAO.inc.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 UserGroupDAO * @ingroup security * @see UserGroup * * @brief Operations for retrieving and modifying User Groups and user group assignments */ import('lib.pkp.classes.security.UserGroup'); import('lib.pkp.classes.workflow.WorkflowStageDAO'); import('lib.pkp.classes.xml.PKPXMLParser'); use Illuminate\Database\Capsule\Manager as Capsule; use Illuminate\Database\Query\Builder; use Illuminate\Database\MySqlConnection; use Illuminate\Database\PostgresConnection; use Illuminate\Support\Collection; class UserGroupDAO extends DAO { /** @var a shortcut to get the UserDAO **/ var $userDao; /** @var a shortcut to get the UserGroupAssignmentDAO **/ var $userGroupAssignmentDao; /** * Constructor. */ function __construct() { parent::__construct(); $this->userDao = DAORegistry::getDAO('UserDAO'); $this->userGroupAssignmentDao = DAORegistry::getDAO('UserGroupAssignmentDAO'); } /** * create new data object * (allows DAO to be subclassed) */ function newDataObject() { return new UserGroup(); } /** * Internal function to return a UserGroup object from a row. * @param $row array * @return UserGroup */ function _returnFromRow($row) { $userGroup = $this->newDataObject(); $userGroup->setId($row['user_group_id']); $userGroup->setRoleId($row['role_id']); $userGroup->setContextId($row['context_id']); $userGroup->setDefault($row['is_default']); $userGroup->setShowTitle($row['show_title']); $userGroup->setPermitSelfRegistration($row['permit_self_registration']); $userGroup->setPermitMetadataEdit($row['permit_metadata_edit']); $this->getDataObjectSettings('user_group_settings', 'user_group_id', $row['user_group_id'], $userGroup); HookRegistry::call('UserGroupDAO::_returnFromRow', array(&$userGroup, &$row)); return $userGroup; } /** * Insert a user group. * @param $userGroup UserGroup * @return int Inserted user group ID */ function insertObject($userGroup) { $this->update( 'INSERT INTO user_groups (role_id, context_id, is_default, show_title, permit_self_registration, permit_metadata_edit) VALUES (?, ?, ?, ?, ?, ?)', [ (int) $userGroup->getRoleId(), (int) $userGroup->getContextId(), $userGroup->getDefault()?1:0, $userGroup->getShowTitle()?1:0, $userGroup->getPermitSelfRegistration()?1:0, $userGroup->getPermitMetadataEdit()?1:0, ] ); $userGroup->setId($this->getInsertId()); $this->updateLocaleFields($userGroup); return $userGroup->getId(); } /** * Update a user group. * @param $userGroup UserGroup */ function updateObject($userGroup) { $this->update( 'UPDATE user_groups SET role_id = ?, context_id = ?, is_default = ?, show_title = ?, permit_self_registration = ?, permit_metadata_edit = ? WHERE user_group_id = ?', [ (int) $userGroup->getRoleId(), (int) $userGroup->getContextId(), $userGroup->getDefault()?1:0, $userGroup->getShowTitle()?1:0, $userGroup->getPermitSelfRegistration()?1:0, $userGroup->getPermitMetadataEdit()?1:0, (int) $userGroup->getId(), ] ); $this->updateLocaleFields($userGroup); } /** * Delete a user group by its id * will also delete related settings and all the assignments to this group * @param $contextId int * @param $userGroupId int */ function deleteById($contextId, $userGroupId) { $this->userGroupAssignmentDao->deleteAssignmentsByUserGroupId($userGroupId); $this->update('DELETE FROM user_group_settings WHERE user_group_id = ?', [(int) $userGroupId]); $this->update('DELETE FROM user_groups WHERE user_group_id = ?', [(int) $userGroupId]); $this->removeAllStagesFromGroup($contextId, $userGroupId); } /** * Delete a user group. * will also delete related settings and all the assignments to this group * @param $userGroup UserGroup */ function deleteObject($userGroup) { $this->deleteById($userGroup->getContextId(), $userGroup->getId()); } /** * Delete a user group by its context id * @param $contextId int */ function deleteByContextId($contextId) { $result = $this->retrieve('SELECT user_group_id FROM user_groups WHERE context_id = ?', [(int) $contextId]); for ($i=1; $row = (array) $result->current(); $i++) { $this->update('DELETE FROM user_group_stage WHERE user_group_id = ?', [(int) $row['user_group_id']]); $this->update('DELETE FROM user_group_settings WHERE user_group_id = ?', [(int) $row['user_group_id']]); $this->update('DELETE FROM user_groups WHERE user_group_id = ?', [(int) $row['user_group_id']]); $result->next(); } } /** * Get the ID of the last inserted user group. * @return int */ function getInsertId() { return $this->_getInsertId('user_groups', 'user_group_id'); } /** * Get field names for which data is localized. * @return array */ function getLocaleFieldNames() { return ['name', 'abbrev']; } /** * @copydoc DAO::getAdditionalFieldNames() */ function getAdditionalFieldNames() { return array_merge(parent::getAdditionalFieldNames(), ['recommendOnly']); } /** * Update the localized data for this object * @param $author object */ function updateLocaleFields($userGroup) { $this->updateDataObjectSettings('user_group_settings', $userGroup, [ 'user_group_id' => (int) $userGroup->getId() ]); } /** * Get an individual user group * @param $userGroupId int User group ID * @param $contextId int Optional context ID to use for validation */ function getById($userGroupId, $contextId = null) { $params = [(int) $userGroupId]; if ($contextId !== null) $params[] = (int) $contextId; $result = $this->retrieve( 'SELECT * FROM user_groups WHERE user_group_id = ?' . ($contextId !== null?' AND context_id = ?':''), $params ); $row = (array) $result->current(); return $row?$this->_returnFromRow($row):null; } /** * Get a single default user group with a particular roleId * @param $contextId int Context ID * @param $roleId int ROLE_ID_... * @return UserGroup|false */ function getDefaultByRoleId($contextId, $roleId) { $allDefaults = $this->getByRoleId($contextId, $roleId, true); return $allDefaults->next() ?? false; } /** * Check whether the passed user group id is default or not. * @param $userGroupId Integer * @return boolean */ function isDefault($userGroupId) { $result = $this->retrieve( 'SELECT is_default FROM user_groups WHERE user_group_id = ?', [(int) $userGroupId] ); $row = $result->current(); return $row && $row->is_default; } /** * Get all user groups belonging to a role * @param Integer $contextId * @param Integer $roleId * @param boolean $default (optional) * @param DBResultRange $dbResultRange (optional) * @return DAOResultFactory */ function getByRoleId($contextId, $roleId, $default = false, $dbResultRange = null) { $params = [(int) $contextId, (int) $roleId]; if ($default) $params[] = 1; // true $result = $this->retrieveRange( $sql = 'SELECT * FROM user_groups WHERE context_id = ? AND role_id = ? ' . ($default?' AND is_default = ?':'') . ' ORDER BY user_group_id', $params, $dbResultRange ); return new DAOResultFactory($result, $this, '_returnFromRow', [], $sql, $params, $dbResultRange); } /** * Get an array of user group ids belonging to a given role * @param $roleId int ROLE_ID_... * @param $contextId int Context ID */ function getUserGroupIdsByRoleId($roleId, $contextId = null) { $params = [(int) $roleId]; if ($contextId) $params[] = (int) $contextId; $result = $this->retrieve( 'SELECT user_group_id FROM user_groups WHERE role_id = ? ' . ($contextId?' AND context_id = ?':''), $params ); $userGroupIds = []; foreach ($result as $row) { $userGroupIds[] = (int) $row->user_group_id; } return $userGroupIds; } /** * Check if a user is in a particular user group * @param $contextId int * @param $userId int * @param $userGroupId int * @return boolean */ function userInGroup($userId, $userGroupId) { $result = $this->retrieve( 'SELECT count(*) AS row_count FROM user_groups ug JOIN user_user_groups uug ON ug.user_group_id = uug.user_group_id WHERE uug.user_id = ? AND ug.user_group_id = ?', [(int) $userId, (int) $userGroupId] ); $row = $result->current(); return $row ? (boolean) $row->row_count : false; } /** * Check if a user is in any user group * @param $userId int * @param $contextId int optional * @return boolean */ function userInAnyGroup($userId, $contextId = null) { $params = [(int) $userId]; if ($contextId) $params[] = (int) $contextId; $result = $this->retrieve( 'SELECT count(*) AS row_count FROM user_groups ug JOIN user_user_groups uug ON ug.user_group_id = uug.user_group_id WHERE uug.user_id = ? ' . ($contextId?' AND ug.context_id = ?':''), $params ); $row = $result->current(); return $row ? (boolean) $row->row_count : false; } /** * Retrieve user groups to which a user is assigned. * @param $userId int * @param $contextId int * @return DAOResultFactory */ function getByUserId($userId, $contextId = null) { $params = [(int) $userId]; if ($contextId) $params[] = (int) $contextId; $result = $this->retrieve( 'SELECT ug.* FROM user_groups ug JOIN user_user_groups uug ON ug.user_group_id = uug.user_group_id WHERE uug.user_id = ? ' . ($contextId?' AND ug.context_id = ?':''), $params ); return new DAOResultFactory($result, $this, '_returnFromRow'); } /** * Validation check to see if user group exists for a given context * @param $contextId * @param $userGroupId * @return bool */ function contextHasGroup($contextId, $userGroupId) { $result = $this->retrieve( 'SELECT count(*) AS row_count FROM user_groups ug WHERE ug.user_group_id = ? AND ug.context_id = ?', [(int) $userGroupId, (int) $contextId] ); $row = (array) $result->current(); return $row && $row['row_count'] != 0; } /** * Retrieve user groups for a given context (all contexts if null) * @param Integer $contextId (optional) * @param DBResultRange $dbResultRange (optional) * @return DAOResultFactory */ function getByContextId($contextId = null, $dbResultRange = null) { $params = []; if ($contextId) $params[] = (int) $contextId; $result = $this->retrieveRange( $sql = 'SELECT ug.* FROM user_groups ug' . ($contextId?' WHERE ug.context_id = ?':''), $params, $dbResultRange ); return new DAOResultFactory($result, $this, '_returnFromRow', [], $sql, $params, $dbResultRange); } /** * Retrieves a keyed Collection (key = user_group_id, value = count) with the amount of active users for each user group */ public function getUserCountByContextId(int $contextId = null): Collection { return Capsule::table('user_groups', 'ug') ->join('user_user_groups AS uug', 'uug.user_group_id', '=', 'ug.user_group_id') ->join('users AS u', 'u.user_id', '=', 'uug.user_id') ->when($contextId, function (Builder $query) use ($contextId): void { $query->where('ug.context_id', '=', $contextId); }) ->where('u.disabled', '=', 0) ->groupBy('ug.user_group_id') ->select('ug.user_group_id') ->selectRaw('COUNT(0) AS count') ->pluck('count', 'user_group_id'); } /** * Retrieve the number of users associated with the specified context. * @param $contextId int * @return int */ function getContextUsersCount($contextId, $userGroupId = null, $roleId = null) { $params = [(int) $contextId]; if ($userGroupId) $params[] = (int) $userGroupId; if ($roleId) $params[] = (int) $roleId; $result = $this->retrieve( 'SELECT COUNT(DISTINCT(uug.user_id)) AS row_count FROM user_groups ug JOIN user_user_groups uug ON ug.user_group_id = uug.user_group_id WHERE ug.context_id = ?' . ($userGroupId?' AND ug.user_group_id = ?':'') . ($roleId?' AND ug.role_id = ?':''), $params ); $row = (array) $result->current(); return $row?$row['row_count']:0; } /** * return an Iterator of User objects given the search parameters * @param int $contextId * @param string $searchType * @param string $search * @param string $searchMatch * @param DBResultRange $dbResultRange * @return DAOResultFactory */ function getUsersByContextId($contextId, $searchType = null, $search = null, $searchMatch = null, $dbResultRange = null) { return $this->getUsersById(null, $contextId, $searchType, $search, $searchMatch, $dbResultRange); } /** * Find users that don't have a given role * @param $roleId ROLE_ID_... int (const) * @param $contextId int Optional context ID * @param $search string Optional search string * @param $rangeInfo RangeInfo Optional range info * @return DAOResultFactory */ function getUsersNotInRole($roleId, $contextId = null, $search = null, $rangeInfo = null) { $params = isset($search) ? [IDENTITY_SETTING_GIVENNAME, IDENTITY_SETTING_FAMILYNAME] : []; $params[] = (int) $roleId; if ($contextId) $params[] = (int) $contextId; if(isset($search)) $params = array_merge($params, array_pad(array(), 4, '%' . $search . '%')); $result = $this->retrieveRange( 'SELECT DISTINCT u.* FROM users u ' .(isset($search) ? ' LEFT JOIN user_settings usgs ON (usgs.user_id = u.user_id AND usgs.setting_name = ?) LEFT JOIN user_settings usfs ON (usfs.user_id = u.user_id AND usfs.setting_name = ?) ':'') .' WHERE u.user_id NOT IN ( SELECT DISTINCT u.user_id FROM users u, user_user_groups uug, user_groups ug WHERE u.user_id = uug.user_id AND ug.user_group_id = uug.user_group_id AND ug.role_id = ?' . ($contextId ? ' AND ug.context_id = ?' : '') . ')' . (isset($search) ? ' AND (usgs.setting_value LIKE ? OR usfs.setting_value LIKE ? OR u.email LIKE ? OR u.username LIKE ?)' : ''), $params, $rangeInfo ); return new DAOResultFactory($result, $this->userDao, '_returnUserFromRowWithData'); } /** * return an Iterator of User objects given the search parameters * @param int $userGroupId optional * @param int $contextId optional * @param string $searchType * @param string $search * @param string $searchMatch * @param DBResultRange $dbResultRange * @return DAOResultFactory */ function getUsersById($userGroupId = null, $contextId = null, $searchType = null, $search = null, $searchMatch = null, $dbResultRange = null) { $locale = AppLocale::getLocale(); // The users register for the site, thus the site primary locale should be the default locale $site = Application::get()->getRequest()->getSite(); $primaryLocale = $site->getPrimaryLocale(); $settingValue = "( SELECT us.setting_value FROM user_settings AS us WHERE us.user_id = u.user_id AND us.setting_name = ? AND us.locale IN (?, ?) -- First non-null/empty values, then give preference to the current locale ORDER BY COALESCE(us.setting_value, '') = '', us.locale <> ? LIMIT 1 )"; $params = [ IDENTITY_SETTING_GIVENNAME, $locale, $primaryLocale, $locale, IDENTITY_SETTING_FAMILYNAME, $locale, $primaryLocale, $locale ]; $sql = "SELECT u.*, $settingValue AS user_given, $settingValue AS user_family FROM users AS u WHERE 1 = 1"; // Has user group if ($contextId || $userGroupId) { if ($contextId) { $params[] = (int) $contextId; } if ($userGroupId) { $params[] = (int) $userGroupId; } $sql .= ' AND EXISTS ( SELECT 0 FROM user_user_groups uug INNER JOIN user_groups ug ON ug.user_group_id = uug.user_group_id WHERE uug.user_id = u.user_id ' . ($contextId ? 'AND ug.context_id = ?' : '') . ' ' . ($userGroupId ? 'AND ug.user_group_id = ?' : '') . ' )'; } $sql .= ' ' . $this->_getSearchSql($searchType, $search, $searchMatch, $params); // Get the result set $result = $this->retrieveRange($sql, $params, $dbResultRange); return new DAOResultFactory($result, $this->userDao, '_returnUserFromRowWithData', [], $sql, $params, $dbResultRange); } // // UserGroupAssignment related // /** * Delete all user group assignments for a given userId * @param int $userId */ function deleteAssignmentsByUserId($userId, $userGroupId = null) { $this->userGroupAssignmentDao->deleteByUserId($userId, $userGroupId); } /** * Delete all assignments to a given user group * @param unknown_type $userGroupId */ function deleteAssignmentsByUserGroupId($userGroupId) { $this->userGroupAssignmentDao->deleteAssignmentsByUserGroupId($userGroupId); } /** * Remove all user group assignments for a given user in a context * @param int $contextId * @param int $userId */ function deleteAssignmentsByContextId($contextId, $userId = null) { $this->userGroupAssignmentDao->deleteAssignmentsByContextId($contextId, $userId); } /** * Assign a given user to a given user group * @param int $userId * @param int $groupId */ function assignUserToGroup($userId, $groupId) { $assignment = $this->userGroupAssignmentDao->newDataObject(); $assignment->setUserId($userId); $assignment->setUserGroupId($groupId); $this->userGroupAssignmentDao->insertObject($assignment); } /** * remove a given user from a given user group * @param $userId int * @param $groupId int * @param $contextId int */ function removeUserFromGroup($userId, $groupId, $contextId) { $assignments = $this->userGroupAssignmentDao->getByUserId($userId, $contextId); while ($assignment = $assignments->next()) { if ($assignment->getUserGroupId() == $groupId) { $this->userGroupAssignmentDao->deleteAssignment($assignment); } } } /** * Delete all stage assignments in a user group. * @param $contextId int * @param $userGroupId int */ function removeAllStagesFromGroup($contextId, $userGroupId) { $assignedStages = $this->getAssignedStagesByUserGroupId($contextId, $userGroupId); foreach($assignedStages as $stageId => $stageLocaleKey) { $this->removeGroupFromStage($contextId, $userGroupId, $stageId); } } /** * Assign a user group to a stage * @param $contextId int * @param $userGroupId int * @param $stageId int */ function assignGroupToStage($contextId, $userGroupId, $stageId) { $this->update( 'INSERT INTO user_group_stage (context_id, user_group_id, stage_id) VALUES (?, ?, ?)', [(int) $contextId, (int) $userGroupId, (int) $stageId] ); } /** * Remove a user group from a stage * @param $contextId int * @param $userGroupId int * @param $stageId int */ function removeGroupFromStage($contextId, $userGroupId, $stageId) { $this->update( 'DELETE FROM user_group_stage WHERE context_id = ? AND user_group_id = ? AND stage_id = ?', [(int) $contextId, (int) $userGroupId, (int) $stageId] ); } // // Extra settings (not handled by rest of Dao) // /** * Method for updatea userGroup setting * @param $userGroupId int * @param $name string * @param $value mixed * @param $type string data type of the setting. If omitted, type will be guessed * @param $isLocalized boolean */ function updateSetting($userGroupId, $name, $value, $type = null, $isLocalized = false) { $keyFields = ['setting_name', 'locale', 'user_group_id']; if (!$isLocalized) { $value = $this->convertToDB($value, $type); $this->replace('user_group_settings', [ 'user_group_id' => (int) $userGroupId, 'setting_name' => $name, 'setting_value' => $value, 'setting_type' => $type, 'locale' => '' ], $keyFields ); } else { if (is_array($value)) foreach ($value as $locale => $localeValue) { $this->update('DELETE FROM user_group_settings WHERE user_group_id = ? AND setting_name = ? AND locale = ?', [(int) $userGroupId, $name, $locale]); if (empty($localeValue)) continue; $type = null; $this->update('INSERT INTO user_group_settings (user_group_id, setting_name, setting_value, setting_type, locale) VALUES (?, ?, ?, ?, ?)', [$userGroupId, $name, $this->convertToDB($localeValue, $type), $type, $locale] ); } } } /** * Retrieve a context setting value. * @param $userGroupId int * @param $name string * @param $locale string optional * @return mixed */ function getSetting($userGroupId, $name, $locale = null) { $params = [(int) $userGroupId, $name]; if ($locale) $params[] = $locale; $result = $this->retrieve( 'SELECT setting_name, setting_value, setting_type, locale FROM user_group_settings WHERE user_group_id = ? AND setting_name = ?' . ($locale?' AND locale = ?':''), $params ); $returner = false; if ($row = $result->current()) { return $this->convertFromDB($row->setting_value, $row->setting_type); } $returner = []; foreach ($result as $row) { $returner[$row->locale] = $this->convertFromDB($row->setting_value, $row->setting_type); } return count($returner) ? $returner : false; } // // Install/Defaults with settings // /** * Load the XML file and move the settings to the DB * @param $contextId * @param $filename * @return boolean true === success */ function installSettings($contextId, $filename) { $xmlParser = new PKPXMLParser(); $tree = $xmlParser->parse($filename); $siteDao = DAORegistry::getDAO('SiteDAO'); /* @var $siteDao SiteDAO */ $site = $siteDao->getSite(); $installedLocales = $site->getInstalledLocales(); if (!$tree) return false; foreach ($tree->getChildren() as $setting) { $roleId = hexdec($setting->getAttribute('roleId')); $nameKey = $setting->getAttribute('name'); $abbrevKey = $setting->getAttribute('abbrev'); $permitSelfRegistration = $setting->getAttribute('permitSelfRegistration'); $permitMetadataEdit = $setting->getAttribute('permitMetadataEdit'); // If has manager role then permitMetadataEdit can't be overriden if (in_array($roleId, array(ROLE_ID_MANAGER))) { $permitMetadataEdit = $setting->getAttribute('permitMetadataEdit'); } $defaultStages = explode(',', $setting->getAttribute('stages') ?? ''); // create a role associated with this user group $userGroup = $this->newDataObject(); $userGroup->setRoleId($roleId); $userGroup->setContextId($contextId); $userGroup->setPermitSelfRegistration($permitSelfRegistration); $userGroup->setPermitMetadataEdit($permitMetadataEdit); $userGroup->setDefault(true); // insert the group into the DB $userGroupId = $this->insertObject($userGroup); // Install default groups for each stage if (is_array($defaultStages)) { // test for groups with no stage assignments foreach ($defaultStages as $stageId) { if (!empty($stageId) && $stageId <= WORKFLOW_STAGE_ID_PRODUCTION && $stageId >= WORKFLOW_STAGE_ID_SUBMISSION) { $this->assignGroupToStage($contextId, $userGroupId, $stageId); } } } // add the i18n keys to the settings table so that they // can be used when a new locale is added/reloaded $this->updateSetting($userGroup->getId(), 'nameLocaleKey', $nameKey); $this->updateSetting($userGroup->getId(), 'abbrevLocaleKey', $abbrevKey); // install the settings in the current locale for this context foreach ($installedLocales as $locale) { $this->installLocale($locale, $contextId); } } return true; } /** * use the locale keys stored in the settings table to install the locale settings * @param $locale * @param $contextId */ function installLocale($locale, $contextId = null) { $userGroups = $this->getByContextId($contextId); while ($userGroup = $userGroups->next()) { $nameKey = $this->getSetting($userGroup->getId(), 'nameLocaleKey'); $this->updateSetting($userGroup->getId(), 'name', [$locale => __($nameKey, null, $locale)], 'string', $locale, true ); $abbrevKey = $this->getSetting($userGroup->getId(), 'abbrevLocaleKey'); $this->updateSetting($userGroup->getId(), 'abbrev', [$locale => __($abbrevKey, null, $locale)], 'string', $locale, true ); } } /** * Remove all settings associated with a locale * @param $locale */ function deleteSettingsByLocale($locale) { return $this->update('DELETE FROM user_group_settings WHERE locale = ?', [$locale]); } /** * private function to assemble the SQL for searching users. * @param string $searchType the field to search on. * @param string $search the keywords to search for. * @param string $searchMatch where to match (is, contains, startsWith). * @param array $params SQL parameter array reference * @return string SQL search snippet */ function _getSearchSql($searchType, $search, $searchMatch, &$params) { $hasUserSetting = "EXISTS( SELECT 0 FROM user_settings WHERE user_id = u.user_id AND setting_name = '%s' AND LOWER(setting_value) LIKE LOWER(?) )"; $searchTypeMap = [ IDENTITY_SETTING_GIVENNAME => sprintf($hasUserSetting, IDENTITY_SETTING_GIVENNAME), IDENTITY_SETTING_FAMILYNAME => sprintf($hasUserSetting, IDENTITY_SETTING_FAMILYNAME), USER_FIELD_USERNAME => 'LOWER(u.username) LIKE LOWER(?)', USER_FIELD_EMAIL => 'LOWER(u.email) LIKE LOWER(?)', USER_FIELD_AFFILIATION => sprintf($hasUserSetting, USER_FIELD_AFFILIATION) ]; $searchSql = ''; $search = trim($search ?? ''); if (!empty($search)) { if (!isset($searchTypeMap[$searchType])) { $terms = array_map(function ($term) { return "%$term%"; }, PKPString::regexp_split('/\s+/', $search)); $filters = []; switch (get_class(Capsule::connection())) { case MySqlConnection::class: $concatSettingValue = "GROUP_CONCAT(setting_value SEPARATOR '')"; break; case PostgresConnection::class: $concatSettingValue = "STRING_AGG(setting_value, '')"; break; default: throw new DomainException('Unrecognized database'); } $userSetting = "COALESCE(( SELECT $concatSettingValue FROM user_settings WHERE user_id = u.user_id AND setting_name = '%s' ), '')"; // Concat key user fields to search $filters[] = '(1 = 1' . str_repeat(' AND LOWER(' . $this->concat( sprintf($userSetting, IDENTITY_SETTING_GIVENNAME), sprintf($userSetting, IDENTITY_SETTING_FAMILYNAME), 'u.email', sprintf($userSetting, USER_FIELD_AFFILIATION), 'u.username' ) . ') LIKE LOWER(?)', count($terms)) . ')'; array_push($params, ...$terms); // Search the user interests $filters[] = ' EXISTS( SELECT 0 FROM user_interests ui INNER JOIN controlled_vocab_entry_settings cves ON ui.controlled_vocab_entry_id = cves.controlled_vocab_entry_id WHERE u.user_id = ui.user_id ' . str_repeat(' AND LOWER(cves.setting_value) LIKE LOWER(?)', count($terms)) . ' )'; array_push($params, ...$terms); $searchSql .= 'AND (' . implode(' OR ', $filters) . ') '; } else { $filter = $searchTypeMap[$searchType]; $searchSql = "AND $filter"; switch ($searchMatch) { case 'is': $params[] = $search; break; case 'contains': $params[] = '%' . $search . '%'; break; case 'startsWith': $params[] = $search . '%'; break; } } } else { switch ($searchType) { case USER_FIELD_USERID: $searchSql = 'AND u.user_id = ?'; break; } } $searchSql .= $this->userDao->getOrderBy(); // FIXME Add "sort field" parameter? return $searchSql; } // // Public helper methods // /** * Get the user groups assigned to each stage. * @param int $contextId Context ID * @param int $stageId WORKFLOW_STAGE_ID_... * @param int $roleId Optional ROLE_ID_... to filter results by * @param DBResultRange (optional) $dbResultRange * @return DAOResultFactory */ function getUserGroupsByStage($contextId, $stageId, $roleId = null, $dbResultRange = null) { $params = [(int) $contextId, (int) $stageId]; if ($roleId) $params[] = (int) $roleId; return new DAOResultFactory( $this->retrieveRange( $sql = 'SELECT ug.* FROM user_groups ug JOIN user_group_stage ugs ON (ug.user_group_id = ugs.user_group_id AND ug.context_id = ugs.context_id) WHERE ugs.context_id = ? AND ugs.stage_id = ? ' . ($roleId?'AND ug.role_id = ?':'') . ' ORDER BY ug.role_id ASC', $params, $dbResultRange ), $this, '_returnFromRow', [], $sql, $params, $dbResultRange ); } /** * Get all stages assigned to one user group in one context. * @param $contextId int The context ID. * @param $userGroupId int The user group ID * @return array */ function getAssignedStagesByUserGroupId($contextId, $userGroupId) { $result = $this->retrieve( 'SELECT stage_id FROM user_group_stage WHERE context_id = ? AND user_group_id = ?', [(int) $contextId, (int) $userGroupId] ); $returner = []; foreach ($result as $row) { $returner[$row->stage_id] = WorkflowStageDAO::getTranslationKeyFromId($row->stage_id); } return $returner; } /** * Check if a user group is assigned to a stage * @param int $userGroupId * @param int $stageId * @return bool */ function userGroupAssignedToStage($userGroupId, $stageId) { $result = $this->retrieve( 'SELECT COUNT(*) AS row_count FROM user_group_stage WHERE user_group_id = ? AND stage_id = ?', [(int) $userGroupId, (int) $stageId] ); $row = $result->current(); return $row ? (boolean) $row->row_count : false; } /** * Check to see whether a user is assigned to a stage ID via a user group. * @param $contextId int * @param $userId int * @param $staeId int * @return boolean */ function userAssignmentExists($contextId, $userId, $stageId) { $result = $this->retrieve( 'SELECT COUNT(*) AS row_count FROM user_group_stage ugs, user_user_groups uug WHERE ugs.user_group_id = uug.user_group_id AND ugs.context_id = ? AND uug.user_id = ? AND ugs.stage_id = ?', [(int) $contextId, (int) $userId, (int) $stageId] ); $row = $result->current(); return $row ? (boolean) $row->row_count : false; } /** * Get all user group IDs with recommendOnly option enabled. * @param $contextId integer * @param $roleId integer (optional) * @return array */ function getRecommendOnlyGroupIds($contextId, $roleId = null) { $params = [(int) $contextId]; if ($roleId) $params[] = (int) $roleId; $result = $this->retrieve( 'SELECT ug.user_group_id AS user_group_id FROM user_groups ug JOIN user_group_settings ugs ON (ugs.user_group_id = ug.user_group_id AND ugs.setting_name = \'recommendOnly\' AND ugs.setting_value = \'1\') WHERE ug.context_id = ? ' . ($roleId?' AND ug.role_id = ?':''), $params ); $userGroupIds = []; foreach ($result as $row) { $userGroupIds[] = (int) $row->user_group_id; } return $userGroupIds; } /** * Get all user group IDs with permit_metadata_edit option enabled. * @param $contextId integer * @param $roleId integer (optional) * @return array */ function getPermitMetadataEditGroupIds($contextId, $roleId = null) { $params = [(int) $contextId]; if ($roleId) $params[] = (int) $roleId; $result = $this->retrieve( 'SELECT ug.user_group_id AS user_group_id FROM user_groups ug WHERE permit_metadata_edit = 1 AND ug.context_id = ? ' . ($roleId?' AND ug.role_id = ?':''), $params ); $userGroupIds = []; foreach ($result as $row) { $userGroupIds[] = (int) $row->user_group_id; } return $userGroupIds; } /** * Get a list of roles not able to change submissionMetadataEdit permission option. * @return array */ static function getNotChangeMetadataEditPermissionRoles() { return [ROLE_ID_MANAGER]; } }