diff --git a/public/main/admin/user_add.php b/public/main/admin/user_add.php
index 8b59de1e47b..3b509da8f38 100644
--- a/public/main/admin/user_add.php
+++ b/public/main/admin/user_add.php
@@ -244,18 +244,22 @@ function updateStatus(){
$status[STUDENT_BOSS] = get_lang('Student\'s superior');
$status[INVITEE] = get_lang('Invitee');
-$form->addSelect(
- 'status',
- get_lang('Profile'),
- $status,
+$form->addElement(
+ 'select',
+ 'roles',
+ get_lang('Roles'),
+ api_get_roles(),
[
- 'id' => 'status_select',
- 'onchange' => 'javascript: updateStatus();',
+ 'multiple' => 'multiple',
+ 'size' => 8,
]
);
//drh list (display only if student)
-$display = (isset($_POST['status']) && STUDENT == $_POST['status']) || !isset($_POST['status']) ? 'block' : 'none';
+$display = 'none';
+if (isset($_POST['roles']) && is_array($_POST['roles'])) {
+ $display = in_array('ROLE_TEACHER', $_POST['roles']) || in_array('ROLE_SESSION_MANAGER', $_POST['roles']) ? 'block' : 'none';
+}
if (api_is_platform_admin()) {
// Platform admin
@@ -354,7 +358,6 @@ function updateStatus(){
$email = $user['email'];
$phone = $user['phone'];
$username = 'true' !== api_get_setting('login_is_email') ? $user['username'] : '';
- $status = (int) $user['status'];
$language = $user['locale'];
$picture = $_FILES['picture'];
$platform_admin = 0;
@@ -398,6 +401,24 @@ function updateStatus(){
$template = isset($user['email_template_option']) ? $user['email_template_option'] : [];
+ $roles = $user['roles'] ?? [];
+ $priorityRoles = [
+ 'ROLE_SESSION_MANAGER' => SESSIONADMIN,
+ 'ROLE_HR' => DRH,
+ 'ROLE_TEACHER' => COURSEMANAGER,
+ 'ROLE_STUDENT_BOSS' => STUDENT_BOSS,
+ 'ROLE_INVITEE' => INVITEE,
+ 'ROLE_STUDENT' => STUDENT,
+ ];
+
+ $status = STUDENT;
+ foreach ($priorityRoles as $role => $roleStatus) {
+ if (in_array($role, $roles, true)) {
+ $status = $roleStatus;
+ break;
+ }
+ }
+
$user_id = UserManager::create_user(
$firstname,
$lastname,
@@ -456,6 +477,14 @@ function updateStatus(){
);
}
+ $repo = Container::getUserRepository();
+ $userEntity = $repo->find($user_id);
+
+ if ($userEntity) {
+ $userEntity->setRoles($roles);
+ $repo->updateUser($userEntity);
+ }
+
$extraFieldValues = new ExtraFieldValue('user');
$user['item_id'] = $user_id;
$extraFieldValues->saveFieldValues($user);
diff --git a/public/main/admin/user_edit.php b/public/main/admin/user_edit.php
index f7fdb18c651..4301c39330f 100644
--- a/public/main/admin/user_edit.php
+++ b/public/main/admin/user_edit.php
@@ -250,26 +250,21 @@ function confirmation(name) {
$form->addGroup($group, 'password', null, null, false);
$form->addPasswordRule('password', 'password');
-// Status
-$status = [];
-$status[COURSEMANAGER] = get_lang('Trainer');
-$status[STUDENT] = get_lang('Learner');
-$status[DRH] = get_lang('Human Resources Manager');
-$status[SESSIONADMIN] = get_lang('Sessions administrator');
-$status[STUDENT_BOSS] = get_lang('Student\'s superior');
-$status[INVITEE] = get_lang('Invitee');
-
-$form->addSelect(
- 'status',
- get_lang('Profile'),
- $status,
+$form->addElement(
+ 'select',
+ 'roles',
+ get_lang('Roles'),
+ api_get_roles(),
[
- 'id' => 'status_select',
- 'onchange' => 'javascript: display_drh_list();',
+ 'multiple' => 'multiple',
+ 'size' => 8,
]
);
-$display = isset($user_data['status']) && (STUDENT == $user_data['status'] || (isset($_POST['status']) && STUDENT == $_POST['status'])) ? 'block' : 'none';
+$display = 'none';
+if (isset($_POST['roles']) && is_array($_POST['roles'])) {
+ $display = in_array('ROLE_TEACHER', $_POST['roles']) || in_array('ROLE_SESSION_MANAGER', $_POST['roles']) ? 'block' : 'none';
+}
// Platform admin
if (api_is_platform_admin()) {
@@ -403,6 +398,9 @@ function confirmation(name) {
$user_data['expiration_date'] = api_get_local_time($expiration_date);
}
}
+$availableRoles = array_keys(api_get_roles());
+$userRoles = array_intersect($userObj->getRoles(), $availableRoles);
+$user_data['roles'] = $userRoles;
$form->setDefaults($user_data);
$error_drh = false;
@@ -417,8 +415,8 @@ function confirmation(name) {
}
$is_user_subscribed_in_course = CourseManager::is_user_subscribed_in_course($user['user_id']);
-
- if (DRH == $user['status'] && $is_user_subscribed_in_course) {
+ $roles = $user['roles'] ?? [];
+ if (in_array('ROLE_HR', $roles, true) && $is_user_subscribed_in_course) {
$error_drh = true;
} else {
$picture_element = $form->getElement('picture');
@@ -441,12 +439,14 @@ function confirmation(name) {
$lastname = $user['lastname'];
$firstname = $user['firstname'];
$password = $user['password'];
- $auth_source = $user['auth_source'] ?? $userInfo['auth_source'];
+ $auth_source = $user['auth_source'] ?? $userInfo['auth_source'] ?? [];
+ if (!is_array($auth_source)) {
+ $auth_source = [$auth_source];
+ }
$official_code = $user['official_code'];
$email = $user['email'];
$phone = $user['phone'];
$username = $user['username'] ?? $userInfo['username'];
- $status = (int) $user['status'];
$platform_admin = 0;
// Only platform admin can change user status to admin.
if (api_is_platform_admin()) {
@@ -463,17 +463,34 @@ function confirmation(name) {
}
$active = isset($user['active']) ? (int) $user['active'] : USER_SOFT_DELETED;
- //If the user is set to admin the status will be overwrite by COURSEMANAGER = 1
- if (1 == $platform_admin) {
- $status = COURSEMANAGER;
- }
-
if ('true' === api_get_setting('login_is_email')) {
$username = $email;
}
$template = $user['email_template_option'] ?? [];
+ $priorityRoles = [
+ 'ROLE_SESSION_MANAGER' => SESSIONADMIN,
+ 'ROLE_HR' => DRH,
+ 'ROLE_TEACHER' => COURSEMANAGER,
+ 'ROLE_STUDENT_BOSS' => STUDENT_BOSS,
+ 'ROLE_INVITEE' => INVITEE,
+ 'ROLE_STUDENT' => STUDENT,
+ ];
+
+ $status = STUDENT;
+ foreach ($priorityRoles as $role => $roleStatus) {
+ if (in_array($role, $roles, true)) {
+ $status = $roleStatus;
+ break;
+ }
+ }
+
+ //If the user is set to admin the status will be overwrite by COURSEMANAGER = 1
+ if (1 == $platform_admin) {
+ $status = COURSEMANAGER;
+ }
+
UserManager::update_user(
$user_id,
$firstname,
@@ -499,7 +516,7 @@ function confirmation(name) {
$template
);
- $studentBossListSent = isset($user['student_boss']) ? $user['student_boss'] : [];
+ $studentBossListSent = $user['student_boss'] ?? [];
UserManager::subscribeUserToBossList(
$user_id,
$studentBossListSent,
@@ -516,6 +533,13 @@ function confirmation(name) {
}
}
+ $repo = Container::getUserRepository();
+ $userEntity = $repo->find($user_id);
+ if ($userEntity) {
+ $userEntity->setRoles($roles);
+ $repo->updateUser($userEntity);
+ }
+
$extraFieldValue = new ExtraFieldValue('user');
$extraFieldValue->saveFieldValues($user);
$userInfo = api_get_user_info($user_id);
diff --git a/public/main/admin/user_list.php b/public/main/admin/user_list.php
index 635d0eb4b96..1ff58d364f8 100644
--- a/public/main/admin/user_list.php
+++ b/public/main/admin/user_list.php
@@ -3,6 +3,7 @@
/* For licensing terms, see /license.txt */
use Chamilo\CoreBundle\Entity\User;
+use Chamilo\CoreBundle\Framework\Container;
use ChamiloSession as Session;
use Chamilo\CoreBundle\Component\Utils\StateIcon;
@@ -214,7 +215,7 @@ function prepare_user_sql_query(bool $getCount, bool $showDeletedUsers = false):
'keyword_username',
'keyword_email',
'keyword_officialcode',
- 'keyword_status',
+ 'keyword_roles',
'keyword_active',
'keyword_inactive',
'check_easy_passwords',
@@ -230,65 +231,64 @@ function prepare_user_sql_query(bool $getCount, bool $showDeletedUsers = false):
}
}
- if (false == $atLeastOne) {
+ if (!$atLeastOne) {
$keywordListValues = [];
}
if (isset($_GET['keyword']) && !empty($_GET['keyword'])) {
$keywordFiltered = Database::escape_string("%".$_GET['keyword']."%");
$sql .= " WHERE (
- u.firstname LIKE '$keywordFiltered' OR
- u.lastname LIKE '$keywordFiltered' OR
- concat(u.firstname, ' ', u.lastname) LIKE '$keywordFiltered' OR
- concat(u.lastname,' ',u.firstname) LIKE '$keywordFiltered' OR
- u.username LIKE '$keywordFiltered' OR
- u.official_code LIKE '$keywordFiltered' OR
- u.email LIKE '$keywordFiltered'
- )
- ";
- } elseif (isset($keywordListValues) && !empty($keywordListValues)) {
+ u.firstname LIKE '$keywordFiltered' OR
+ u.lastname LIKE '$keywordFiltered' OR
+ concat(u.firstname, ' ', u.lastname) LIKE '$keywordFiltered' OR
+ concat(u.lastname,' ',u.firstname) LIKE '$keywordFiltered' OR
+ u.username LIKE '$keywordFiltered' OR
+ u.official_code LIKE '$keywordFiltered' OR
+ u.email LIKE '$keywordFiltered'
+ )";
+ } elseif (!empty($keywordListValues)) {
$query_admin_table = '';
$keyword_admin = '';
- if (isset($keywordListValues['keyword_status']) &&
- PLATFORM_ADMIN == $keywordListValues['keyword_status']
- ) {
- $query_admin_table = " , $admin_table a ";
- $keyword_admin = ' AND a.user_id = u.id ';
- $keywordListValues['keyword_status'] = '';
+ $roles = [];
+ if (!empty($keywordListValues['keyword_roles'])) {
+ foreach ((array) $keywordListValues['keyword_roles'] as $sub) {
+ $roles = array_merge($roles, (array) $sub);
+ }
}
- if ('%' === $keywordListValues['keyword_status']) {
- $keywordListValues['keyword_status'] = '';
+ if (in_array('ROLE_PLATFORM_ADMIN', $roles, true)) {
+ $query_admin_table = " , $admin_table a ";
+ $keyword_admin = ' AND a.user_id = u.id ';
}
- $keyword_extra_value = '';
- $sql .= " $query_admin_table
- WHERE ( 1 = 1 ";
+ $sql .= " $query_admin_table WHERE (1 = 1 ";
if (!empty($keywordListValues['keyword_firstname'])) {
- $sql .= "AND u.firstname LIKE '".Database::escape_string("%".$keywordListValues['keyword_firstname']."%")."'";
+ $sql .= " AND u.firstname LIKE '".Database::escape_string("%".$keywordListValues['keyword_firstname']."%")."'";
}
- // This block is never executed because $keyword_extra_data never exists
if (!empty($keywordListValues['keyword_lastname'])) {
- $sql .= "AND u.lastname LIKE '".Database::escape_string("%".$keywordListValues['keyword_lastname']."%")."'";
+ $sql .= " AND u.lastname LIKE '".Database::escape_string("%".$keywordListValues['keyword_lastname']."%")."'";
}
if (!empty($keywordListValues['keyword_username'])) {
- $sql .= "AND u.username LIKE '".Database::escape_string("%".$keywordListValues['keyword_username']."%")."'";
+ $sql .= " AND u.username LIKE '".Database::escape_string("%".$keywordListValues['keyword_username']."%")."'";
}
if (!empty($keywordListValues['keyword_email'])) {
- $sql .= "AND u.email LIKE '".Database::escape_string("%".$keywordListValues['keyword_email']."%")."'";
- }
-
- if (!empty($keywordListValues['keyword_status'])) {
- $sql .= "AND u.status = '".Database::escape_string($keywordListValues['keyword_status'])."'";
+ $sql .= " AND u.email LIKE '".Database::escape_string("%".$keywordListValues['keyword_email']."%")."'";
}
if (!empty($keywordListValues['keyword_officialcode'])) {
- $sql .= " AND u.official_code LIKE '".Database::escape_string("%".$keywordListValues['keyword_officialcode']."%")."' ";
+ $sql .= " AND u.official_code LIKE '".Database::escape_string("%".$keywordListValues['keyword_officialcode']."%")."'";
}
- $sql .= " $keyword_admin $keyword_extra_value ";
+ if (!empty($roles)) {
+ $roleConditions = [];
+ foreach ($roles as $role) {
+ $escaped = Database::escape_string($role);
+ $roleConditions[] = "u.roles LIKE '%\"$escaped\"%'";
+ }
+ $sql .= ' AND (' . implode(' OR ', $roleConditions) . ')';
+ }
if (isset($keywordListValues['keyword_active']) &&
!isset($keywordListValues['keyword_inactive'])
@@ -299,27 +299,23 @@ function prepare_user_sql_query(bool $getCount, bool $showDeletedUsers = false):
) {
$sql .= ' AND u.active = 0';
}
- $sql .= ' ) ';
+
+ $sql .= " $keyword_admin )";
}
if ($classId) {
$sql .= " AND ug.usergroup_id = $classId";
}
- $preventSessionAdminsToManageAllUsers = api_get_setting('prevent_session_admins_to_manage_all_users');
-
- $extraConditions = '';
- if (api_is_session_admin() && 'true' === $preventSessionAdminsToManageAllUsers) {
- $extraConditions .= ' AND u.creator_id = '.api_get_user_id();
+ if (api_is_session_admin() && api_get_setting('prevent_session_admins_to_manage_all_users') === 'true') {
+ $sql .= ' AND u.creator_id = '.api_get_user_id();
}
- // adding the filter to see the user's only of the current access_url
if ($isMultipleUrl) {
- $extraConditions .= ' AND url_rel_user.access_url_id = '.$urlId;
+ $sql .= ' AND url_rel_user.access_url_id = '.$urlId;
}
- $sql .= $extraConditions;
-
+ // Extra fields (sin cambios)
$variables = Session::read('variables_to_show', []);
$extraFields = api_get_setting('profile.user_search_on_extra_fields', true);
@@ -338,11 +334,9 @@ function prepare_user_sql_query(bool $getCount, bool $showDeletedUsers = false):
$extraFieldHasData = [];
foreach ($variables as $variable) {
if (isset($_GET['extra_'.$variable])) {
- if (is_array($_GET['extra_'.$variable])) {
- $values = $_GET['extra_'.$variable];
- } else {
- $values = [$_GET['extra_'.$variable]];
- }
+ $values = is_array($_GET['extra_'.$variable])
+ ? $_GET['extra_'.$variable]
+ : [$_GET['extra_'.$variable]];
if (empty($values)) {
continue;
@@ -358,7 +352,7 @@ function prepare_user_sql_query(bool $getCount, bool $showDeletedUsers = false):
if (empty($value)) {
continue;
}
- if (ExtraField::FIELD_TYPE_TAG == $info['value_type']) {
+ if (ExtraField::FIELD_TYPE_TAG === $info['value_type']) {
$result = $extraField->getAllUserPerTag($info['id'], $value);
$result = empty($result) ? [] : array_column($result, 'user_id');
} else {
@@ -373,14 +367,10 @@ function prepare_user_sql_query(bool $getCount, bool $showDeletedUsers = false):
}
}
- $condition = ' AND ';
- // If simple search then use "OR"
- if (isset($_GET['keyword']) && !empty($_GET['keyword'])) {
- $condition = ' OR ';
- }
+ $condition = isset($_GET['keyword']) ? ' OR ' : ' AND ';
if (!empty($extraFieldHasData) && !empty($extraFieldResult)) {
- $sql .= " $condition (u.id IN ('".implode("','", $extraFieldResult)."') $extraConditions ) ";
+ $sql .= " $condition u.id IN ('".implode("','", $extraFieldResult)."')";
}
}
@@ -419,9 +409,6 @@ function get_user_data(int $from, int $number_of_items, int $column, string $dir
if (!in_array($direction, ['ASC', 'DESC'])) {
$direction = 'ASC';
}
- $column = (int) $column;
- $from = (int) $from;
- $number_of_items = (int) $number_of_items;
$sql .= " ORDER BY col$column $direction ";
$sql .= " LIMIT $from, $number_of_items";
@@ -458,7 +445,7 @@ function get_user_data(int $from, int $number_of_items, int $column, string $dir
$user[3],
$user[4], // username
$user[5], // email
- $user[6],
+ $user[0],
$user[7], // active
api_get_local_time($user[8]),
api_get_local_time($user[9], null, null, true),
@@ -568,15 +555,15 @@ function modify_filter($user_id, $url_params, $row): string
{
$_admins_list = Session::read('admin_list', []);
$is_admin = in_array($user_id, $_admins_list);
- $statusname = api_get_status_langvars();
+
+ $repo = Container::getUserRepository();
+ $userEntity = $repo->find($user_id);
+ $userRoles = $userEntity ? $userEntity->getRoles() : [];
+
$currentUserId = api_get_user_id();
- $user_is_anonymous = false;
+ $user_is_anonymous = in_array('ROLE_ANONYMOUS', $userRoles, true);
$current_user_status_label = $row['7'];
-
- if ($current_user_status_label == $statusname[ANONYMOUS]) {
- $user_is_anonymous = true;
- }
$result = '';
if (api_is_platform_admin()) {
@@ -589,16 +576,21 @@ function modify_filter($user_id, $url_params, $row): string
}
}
- // Only allow platform admins to login_as, or session admins only for students (not teachers nor other admins)
- $loginAsStatusForSessionAdmins = [$statusname[STUDENT]];
+ $loginAsRolesForSessionAdmins = ['ROLE_STUDENT'];
- // Except when session.allow_session_admin_login_as_teacher is enabled, then can login_as teachers also
if ('true' === api_get_setting('session.allow_session_admin_login_as_teacher')) {
- $loginAsStatusForSessionAdmins[] = $statusname[COURSEMANAGER];
+ $loginAsRolesForSessionAdmins[] = 'ROLE_TEACHER';
}
- $sessionAdminCanLoginAs = api_is_session_admin() &&
- in_array($current_user_status_label, $loginAsStatusForSessionAdmins);
+ $sessionAdminCanLoginAs = false;
+ if (api_is_session_admin()) {
+ foreach ($loginAsRolesForSessionAdmins as $role) {
+ if (in_array($role, $userRoles, true)) {
+ $sessionAdminCanLoginAs = true;
+ break;
+ }
+ }
+ }
if (api_is_platform_admin() || $sessionAdminCanLoginAs) {
if (!$user_is_anonymous) {
@@ -615,7 +607,7 @@ function modify_filter($user_id, $url_params, $row): string
$result .= Display::getMdiIcon('account-key', 'ch-tool-icon-disabled', null, 22, get_lang('Login as'));
}
- if ($current_user_status_label != $statusname[STUDENT]) {
+ if (!in_array('ROLE_STUDENT', $userRoles, true)) {
$result .= Display::getMdiIcon(
'chart-box',
'ch-tool-icon-disabled',
@@ -807,7 +799,12 @@ function modify_filter($user_id, $url_params, $row): string
// actions for assigning sessions, courses or users
if (!api_is_session_admin()) {
- if ($current_user_status_label == $statusname[SESSIONADMIN]) {
+ $isSessionManager = in_array('ROLE_SESSION_MANAGER', $userRoles, true);
+ $isHR = in_array('ROLE_HR', $userRoles, true);
+ $isStudentBoss = in_array('ROLE_STUDENT_BOSS', $userRoles, true);
+ $isAdmin = UserManager::is_admin($user_id);
+
+ if ($isSessionManager) {
$result .= Display::url(
Display::getMdiIcon(
'google-classroom',
@@ -819,10 +816,7 @@ function modify_filter($user_id, $url_params, $row): string
"dashboard_add_sessions_to_user.php?user={$user_id}"
);
} else {
- if ($current_user_status_label == $statusname[DRH] ||
- UserManager::is_admin($user_id) ||
- $current_user_status_label == $statusname[STUDENT_BOSS]
- ) {
+ if ($isHR || $isAdmin || $isStudentBoss) {
$result .= Display::url(
Display::getMdiIcon(
'account-child',
@@ -836,7 +830,7 @@ function modify_filter($user_id, $url_params, $row): string
);
}
- if ($current_user_status_label == $statusname[DRH] || UserManager::is_admin($user_id)) {
+ if ($isHR || $isAdmin) {
$result .= Display::url(
Display::getMdiIcon(
'book-open-page-variant',
@@ -916,13 +910,25 @@ function active_filter(int $active, string $params, array $row): string
}
/**
- * Instead of displaying the integer of the status, we give a translation for the status.
+ * Returns a list of user roles excluding the default ROLE_USER.
+ *
+ * @param int $userId The user ID.
+ * @return string HTML string with roles separated by
.
*/
-function status_filter(int $status): string
+function roles_filter($userId): string
{
- $name = api_get_status_langvars();
+ $repo = Container::getUserRepository();
+ $user = $repo->find($userId);
+ if (!$user) {
+ return '';
+ }
- return $name[$status];
+ $roles = array_filter(
+ $user->getRoles(),
+ fn ($role) => $role !== 'ROLE_USER'
+ );
+
+ return implode('
', array_map('htmlentities', $roles));
}
if (isset($_GET['keyword']) || isset($_GET['keyword_firstname'])) {
@@ -1183,7 +1189,10 @@ class="btn btn--plain advanced_options" onclick="display_advanced_search_form();
$parameters['keyword_username'] = Security::remove_XSS($_GET['keyword_username']);
$parameters['keyword_email'] = Security::remove_XSS($_GET['keyword_email']);
$parameters['keyword_officialcode'] = Security::remove_XSS($_GET['keyword_officialcode']);
- $parameters['keyword_status'] = Security::remove_XSS($_GET['keyword_status']);
+ if (isset($_GET['keyword_roles'])) {
+ $keywordRoles = is_array($_GET['keyword_roles']) ? $_GET['keyword_roles'] : [$_GET['keyword_roles']];
+ $parameters['keyword_roles'] = implode(',', array_map('Security::remove_XSS', $keywordRoles));
+ }
if (isset($_GET['keyword_active'])) {
$parameters['keyword_active'] = Security::remove_XSS($_GET['keyword_active']);
}
@@ -1230,19 +1239,11 @@ class="btn btn--plain advanced_options" onclick="display_advanced_search_form();
['url' => api_get_path(WEB_AJAX_PATH).'usergroup.ajax.php?a=get_class_by_keyword']
);
-$status_options = [];
-$status_options['%'] = get_lang('All');
-$status_options[STUDENT] = get_lang('Learner');
-$status_options[COURSEMANAGER] = get_lang('Trainer');
-$status_options[DRH] = get_lang('Human Resources Manager');
-$status_options[SESSIONADMIN] = get_lang('Course sessionsAdmin');
-$status_options[PLATFORM_ADMIN] = get_lang('Administrator');
-$status_options[STUDENT_BOSS] = get_lang('RoleStudentBoss');
-
$form->addSelect(
- 'keyword_status',
- get_lang('Profile'),
- $status_options
+ 'keyword_roles',
+ get_lang('Roles'),
+ array_combine(api_get_roles(), api_get_roles()),
+ ['multiple' => true, 'size' => 6]
);
$active_group = [];
@@ -1291,7 +1292,7 @@ function($from, $number_of_items, $column, $direction) use ($showDeletedUsers) {
}
$table->set_header(5, get_lang('Username'));
$table->set_header(6, get_lang('e-mail'));
-$table->set_header(7, get_lang('Profile'));
+$table->set_header(7, get_lang('Roles'));
$table->set_header(8, get_lang('active'), true, 'width="15px"');
$table->set_header(9, get_lang('Registration date'), true, 'width="90px"');
$table->set_header(10, get_lang('Latest login'), true, 'width="90px"');
@@ -1300,7 +1301,7 @@ function($from, $number_of_items, $column, $direction) use ($showDeletedUsers) {
$table->set_column_filter(3, 'user_filter');
$table->set_column_filter(4, 'user_filter');
$table->set_column_filter(6, 'email_filter');
-$table->set_column_filter(7, 'status_filter');
+$table->set_column_filter(7, 'roles_filter');
$table->set_column_filter(8, 'active_filter');
$actionsList = [];
if ($showDeletedUsers) {
diff --git a/public/main/inc/lib/api.lib.php b/public/main/inc/lib/api.lib.php
index 3d935b3f693..7bfaf127ae0 100644
--- a/public/main/inc/lib/api.lib.php
+++ b/public/main/inc/lib/api.lib.php
@@ -3026,21 +3026,12 @@ function api_is_course_session_coach($user_id, $courseId, $session_id)
/**
* Checks whether the current user is a course or session coach.
- *
- * @param int $session_id
- * @param int $courseId
- * @param bool Check whether we are in student view and, if we are, return false
- * @param int $userId
- *
- * @return bool True if current user is a course or session coach
*/
-function api_is_coach($session_id = 0, $courseId = null, $check_student_view = true, $userId = 0)
+function api_is_coach(int $session_id = 0, ?int $courseId = null, bool $check_student_view = true, int $userId = 0): bool
{
- $userId = empty($userId) ? api_get_user_id() : (int) $userId;
+ $userId = empty($userId) ? api_get_user_id() : $userId;
- if (!empty($session_id)) {
- $session_id = (int) $session_id;
- } else {
+ if (empty($session_id)) {
$session_id = api_get_session_id();
}
@@ -3049,9 +3040,7 @@ function api_is_coach($session_id = 0, $courseId = null, $check_student_view = t
return false;
}
- if (!empty($courseId)) {
- $courseId = (int) $courseId;
- } else {
+ if (empty($courseId)) {
$courseId = api_get_course_int_id();
}
@@ -3310,110 +3299,149 @@ function api_display_tool_view_option()
}
/**
- * Function that removes the need to directly use is_courseAdmin global in
- * tool scripts. It returns true or false depending on the user's rights in
- * this particular course.
- * Optionally checking for tutor and coach roles here allows us to use the
- * student_view feature altogether with these roles as well.
- *
- * @param bool Whether to check if the user has the tutor role
- * @param bool Whether to check if the user has the coach role
- * @param bool Whether to check if the user has the session coach role
- * @param bool check the student view or not
+ * Determines whether the current user is allowed to edit the current context.
*
- * @author Roan Embrechts
- * @author Patrick Cool
- * @author Julio Montoya
+ * This includes checks for platform admin, course admin, tutor, coach,
+ * session coach, and optionally verifies if the user is in student view mode.
+ * If not in a course context, it falls back to a role-based permission system.
*
- * @version 1.1, February 2004
+ * @param bool $tutor Allow if the user is a tutor.
+ * @param bool $coach Allow if the user is a coach and setting allows it.
+ * @param bool $session_coach Allow if the user is a session coach.
+ * @param bool $check_student_view Check if student view mode is active.
*
- * @return bool true: the user has the rights to edit, false: he does not
+ * @return bool True if the user is allowed to edit, false otherwise.
*/
function api_is_allowed_to_edit(
- $tutor = false,
- $coach = false,
- $session_coach = false,
- $check_student_view = true
-) {
+ bool $tutor = false,
+ bool $coach = false,
+ bool $session_coach = false,
+ bool $check_student_view = true
+): bool {
$allowSessionAdminEdit = 'true' === api_get_setting('session.session_admins_edit_courses_content');
- // Admins can edit anything.
+ $sessionId = api_get_session_id();
+ $studentView = api_is_student_view_active();
+ $isAllowed = false;
+
+ // If platform admin, allow unless student view is active
if (api_is_platform_admin($allowSessionAdminEdit)) {
- //The student preview was on
- if ($check_student_view && api_is_student_view_active()) {
- return false;
+ if ($check_student_view && $studentView) {
+ $isAllowed = false;
+ } else {
+ return true;
}
-
- return true;
}
- $sessionId = api_get_session_id();
-
+ // Respect session course read-only mode from extra field
if ($sessionId && 'true' === api_get_setting('session.session_courses_read_only_mode')) {
$efv = new ExtraFieldValue('course');
- $lockExrafieldField = $efv->get_values_by_handler_and_field_variable(
+ $lock = $efv->get_values_by_handler_and_field_variable(
api_get_course_int_id(),
'session_courses_read_only_mode'
);
-
- if (!empty($lockExrafieldField['value'])) {
+ if (!empty($lock['value'])) {
return false;
}
}
- $is_allowed_coach_to_edit = api_is_coach(null, null, $check_student_view);
- $session_visibility = api_get_session_visibility($sessionId);
- $is_courseAdmin = api_is_course_admin();
+ $isCourseAdmin = api_is_course_admin();
+ $isCoach = api_is_coach(0, null, $check_student_view);
- if (!$is_courseAdmin && $tutor) {
- // If we also want to check if the user is a tutor...
- $is_courseAdmin = $is_courseAdmin || api_is_course_tutor();
+ if (!$isCourseAdmin && $tutor) {
+ $isCourseAdmin = api_is_course_tutor();
}
- if (!$is_courseAdmin && $coach) {
- // If we also want to check if the user is a coach...';
- // Check if session visibility is read only for coaches.
- if (SESSION_VISIBLE_READ_ONLY == $session_visibility) {
- $is_allowed_coach_to_edit = false;
- }
+ $sessionVisibility = api_get_session_visibility($sessionId);
+ if (!$isCourseAdmin && $coach) {
+ if (SESSION_VISIBLE_READ_ONLY == $sessionVisibility) {
+ $isCoach = false;
+ }
if ('true' === api_get_setting('allow_coach_to_edit_course_session')) {
- // Check if coach is allowed to edit a course.
- $is_courseAdmin = $is_courseAdmin || $is_allowed_coach_to_edit;
+ $isCourseAdmin = $isCoach;
}
}
- if (!$is_courseAdmin && $session_coach) {
- $is_courseAdmin = $is_courseAdmin || $is_allowed_coach_to_edit;
+ if (!$isCourseAdmin && $session_coach) {
+ $isCourseAdmin = $isCoach;
}
- // Check if the student_view is enabled, and if so, if it is activated.
+ // Handle student view mode
if ('true' === api_get_setting('student_view_enabled')) {
- $studentView = api_is_student_view_active();
if (!empty($sessionId)) {
- // Check if session visibility is read only for coaches.
- if (SESSION_VISIBLE_READ_ONLY == $session_visibility) {
- $is_allowed_coach_to_edit = false;
+ if (SESSION_VISIBLE_READ_ONLY == $sessionVisibility) {
+ $isCoach = false;
}
-
- $is_allowed = false;
if ('true' === api_get_setting('allow_coach_to_edit_course_session')) {
- // Check if coach is allowed to edit a course.
- $is_allowed = $is_allowed_coach_to_edit;
+ $isAllowed = $isCoach;
}
+
if ($check_student_view) {
- $is_allowed = $is_allowed && false === $studentView;
+ $isAllowed = $isAllowed && !$studentView;
}
} else {
- $is_allowed = $is_courseAdmin;
+ $isAllowed = $isCourseAdmin;
if ($check_student_view) {
- $is_allowed = $is_courseAdmin && false === $studentView;
+ $isAllowed = $isCourseAdmin && !$studentView;
}
}
- return $is_allowed;
+ if ($isAllowed) {
+ return true;
+ }
} else {
- return $is_courseAdmin;
+ if ($isCourseAdmin) {
+ return true;
+ }
}
+
+ // Final fallback: permission-based system (only if nothing before returned true)
+ $courseId = api_get_course_id();
+ $inCourse = !empty($courseId) && $courseId != -1;
+
+ if (!$inCourse) {
+ $userRoles = api_get_user_roles();
+ $feature = api_detect_feature_context();
+ $permission = $feature.':edit';
+
+ return api_get_permission($permission, $userRoles);
+ }
+
+ return $isAllowed;
+}
+
+/**
+ * Returns the current main feature (module) based on the current script path.
+ * Used to determine permissions for non-course tools.
+ */
+function api_detect_feature_context(): string
+{
+ $script = $_SERVER['SCRIPT_NAME'] ?? '';
+ $script = basename($script);
+
+ $map = [
+ 'user_list.php' => 'user',
+ 'user_add.php' => 'user',
+ 'user_edit.php' => 'user',
+ 'session_list.php' => 'session',
+ 'session_add.php' => 'session',
+ 'session_edit.php' => 'session',
+ 'skill_list.php' => 'skill',
+ 'skill_edit.php' => 'skill',
+ 'badge_list.php' => 'badge',
+ 'settings.php' => 'settings',
+ 'course_list.php' => 'course',
+ ];
+
+ if (isset($map[$script])) {
+ return $map[$script];
+ }
+
+ if (preg_match('#/main/([a-z_]+)/#i', $_SERVER['SCRIPT_NAME'], $matches)) {
+ return $matches[1];
+ }
+
+ return 'unknown';
}
/**
@@ -6348,15 +6376,11 @@ function api_set_default_visibility(
}
}
-function api_get_roles()
+function api_get_roles(): array
{
- $hierarchy = Container::$container->getParameter('security.role_hierarchy.roles');
- $roles = [];
- array_walk_recursive($hierarchy, function ($role) use (&$roles) {
- $roles[$role] = $role;
- });
+ $roles = Container::$container->get(\Chamilo\CoreBundle\ServiceHelper\PermissionServiceHelper::class)->getUserRoles();
- return $roles;
+ return array_combine($roles, $roles);
}
function api_get_user_roles(): array