Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/CoreBundle/DataFixtures/PermissionFixtures.php
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ public static function getPermissions(): array
public static function getRoles(): array
{
return [
'ROLE_ANONYMOUS' => 'ANO',
'ROLE_INVITEE' => 'INV',
'ROLE_STUDENT' => 'STU',
'ROLE_TEACHER' => 'TEA',
Expand Down
14 changes: 7 additions & 7 deletions src/CoreBundle/DataFixtures/RoleFixtures.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@ class RoleFixtures extends Fixture
public function load(ObjectManager $manager): void
{
$roles = [
[
'code' => 'ANONYMOUS',
'constantValue' => 0,
'title' => 'Anonymous',
'description' => 'Unauthenticated users',
'systemRole' => true,
],
[
'code' => 'INVITEE',
'constantValue' => 1,
Expand Down Expand Up @@ -43,13 +50,6 @@ public function load(ObjectManager $manager): void
'description' => 'Platform administrators',
'systemRole' => true,
],
[
'code' => 'SUPER_ADMIN',
'constantValue' => 5,
'title' => 'Super Administrator',
'description' => 'Super admin users',
'systemRole' => true,
],
[
'code' => 'GLOBAL_ADMIN',
'constantValue' => 6,
Expand Down
12 changes: 9 additions & 3 deletions src/CoreBundle/Helpers/PermissionHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,21 @@ public function __construct(
) {}

/**
* Returns the list of role codes currently stored in the 'role' table.
* Returns the list of role codes currently stored in the 'role' table,
* excluding internal roles like ANONYMOUS (not assignable).
*
* @return string[]
*/
public function getUserRoles(): array
{
$roles = $this->roleRepository->findAll();
$qb = $this->roleRepository->createQueryBuilder('r')
->where('r.code <> :anon')
->setParameter('anon', 'ANONYMOUS')
->orderBy('r.constantValue', 'ASC');

return array_map(fn ($r) => $r->getCode(), $roles);
$roles = $qb->getQuery()->getResult();

return array_map(static fn ($r) => $r->getCode(), $roles);
}

/**
Expand Down
92 changes: 92 additions & 0 deletions src/CoreBundle/Migrations/Schema/V200/Version20251015073500.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<?php

/* For licensing terms, see /license.txt */

declare(strict_types=1);

namespace Chamilo\CoreBundle\Migrations\Schema\V200;

use Chamilo\CoreBundle\Migrations\AbstractMigrationChamilo;
use Doctrine\DBAL\Schema\Schema;

final class Version20251015073500 extends AbstractMigrationChamilo
{
public function getDescription(): string
{
return 'Clean role table: ensure ANONYMOUS exists, drop SUPER_ADMIN, and keep only canonical roles.';
}

public function up(Schema $schema): void
{
$canonical = [
'ANONYMOUS',
'INVITEE',
'STUDENT',
'TEACHER',
'ADMIN',
'GLOBAL_ADMIN',
'HR',
'QUESTION_MANAGER',
'SESSION_MANAGER',
'STUDENT_BOSS',
];
$inList = "'" . implode("','", array_map('addslashes', $canonical)) . "'";

$this->addSql("
INSERT INTO role (code, constant_value, title, description, system_role, created_at)
SELECT 'ANONYMOUS', 0, 'Anonymous', 'Unauthenticated users', 1, NOW()
FROM DUAL
WHERE NOT EXISTS (SELECT 1 FROM role WHERE code = 'ANONYMOUS')
");
$this->write('Ensured ANONYMOUS role exists.');

$this->addSql("
DELETE prr FROM permission_rel_role prr
INNER JOIN role r ON r.id = prr.role_id
WHERE r.code = 'SUPER_ADMIN'
");
$this->addSql("DELETE FROM role WHERE code = 'SUPER_ADMIN'");
$this->write('Removed SUPER_ADMIN and related PRR rows.');

$this->addSql("
DELETE prr FROM permission_rel_role prr
INNER JOIN role r ON r.id = prr.role_id
WHERE r.code NOT IN ($inList)
");
$this->addSql("DELETE FROM role WHERE code NOT IN ($inList)");
$this->write('Removed non-canonical roles and related PRR rows.');

$defaults = [
'INVITEE' => [1, 'Invitee', 'Invited users', 1],
'STUDENT' => [2, 'Student', 'Students of courses or sessions', 1],
'TEACHER' => [3, 'Teacher', 'Teachers of courses or sessions', 1],
'ADMIN' => [4, 'Administrator', 'Platform administrators', 1],
'GLOBAL_ADMIN' => [6, 'Global Administrator', 'Global admin users', 1],
'HR' => [7, 'HR Manager', 'Human resources managers', 0],
'QUESTION_MANAGER' => [8, 'Question Bank Manager', 'Manages the question bank across courses', 0],
'SESSION_MANAGER' => [9, 'Session Manager', 'Manages sessions and session content', 0],
'STUDENT_BOSS' => [10, 'Student Boss', 'Manages groups of students', 0],
];

foreach ($defaults as $code => [$const, $title, $desc, $sys]) {
$this->addSql("
INSERT INTO role (code, constant_value, title, description, system_role, created_at)
SELECT '$code', $const, '".addslashes($title)."', '".addslashes($desc)."', $sys, NOW()
FROM DUAL
WHERE NOT EXISTS (SELECT 1 FROM role WHERE code = '$code')
");
}
$this->write('Ensured all canonical roles exist.');
}

public function down(Schema $schema): void
{
$this->addSql("
INSERT INTO role (code, constant_value, title, description, system_role, created_at)
SELECT 'SUPER_ADMIN', 5, 'Super Administrator', 'Super admin users', 1, NOW()
FROM DUAL
WHERE NOT EXISTS (SELECT 1 FROM role WHERE code = 'SUPER_ADMIN')
");
$this->addSql("DELETE FROM role WHERE code = 'ANONYMOUS'");
}
}
Loading