Passed
Push — master ( 8b1102...ea5665 )
by Yannick
08:48 queued 15s
created

Version20250706105000::getRoleTitle()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 16
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 12
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 16
rs 9.8666
1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
declare(strict_types=1);
6
7
namespace Chamilo\CoreBundle\Migrations\Schema\V200;
8
9
use Chamilo\CoreBundle\DataFixtures\PermissionFixtures;
10
use Chamilo\CoreBundle\Migrations\AbstractMigrationChamilo;
11
use Doctrine\DBAL\Schema\Schema;
12
13
final class Version20250706105000 extends AbstractMigrationChamilo
14
{
15
    public function getDescription(): string
16
    {
17
        return 'Creates role table, populates it, and migrates permission_rel_role from role_code to role_id.';
18
    }
19
20
    public function up(Schema $schema): void
21
    {
22
        // 1. Create table role
23
        $this->addSql("
24
            CREATE TABLE role (
25
                id INT UNSIGNED AUTO_INCREMENT NOT NULL,
26
                code VARCHAR(50) NOT NULL,
27
                constant_value INT NOT NULL,
28
                title VARCHAR(255) NOT NULL,
29
                description LONGTEXT DEFAULT NULL,
30
                system_role TINYINT(1) NOT NULL,
31
                created_at DATETIME DEFAULT NULL COMMENT '(DC2Type:datetime)',
32
                created_by INT UNSIGNED DEFAULT NULL,
33
                updated_at DATETIME DEFAULT NULL COMMENT '(DC2Type:datetime)',
34
                updated_by INT UNSIGNED DEFAULT NULL,
35
                UNIQUE INDEX UNIQ_57698A6A77153098 (code),
36
                PRIMARY KEY(id)
37
            ) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB ROW_FORMAT = DYNAMIC
38
        ");
39
        $this->write("Created table role.");
40
41
        // 2. Populate role table
42
        $roles = PermissionFixtures::getRoles();
43
        $values = [];
44
        $id = 1;
45
46
        foreach ($roles as $roleName => $shortCode) {
47
            $code = substr($roleName, 5);
48
            $constantValue = $this->getRoleConstantValue($code);
49
            $title = $this->getRoleTitle($code);
50
            $description = $this->getRoleDescription($code);
51
52
            $values[] = sprintf(
53
                "(%d, '%s', %d, '%s', '%s', %d, NOW())",
54
                $id,
55
                $code,
56
                $constantValue,
57
                addslashes($title),
58
                addslashes($description),
59
                1
60
            );
61
62
            $id++;
63
        }
64
65
        if (!empty($values)) {
66
            $this->addSql("
67
                INSERT INTO role
68
                    (id, code, constant_value, title, description, system_role, created_at)
69
                VALUES " . implode(", ", $values)
70
            );
71
            $this->write("Inserted role data from fixtures.");
72
        }
73
74
        // 3. Add nullable role_id
75
        $this->addSql("
76
            ALTER TABLE permission_rel_role
77
                ADD role_id INT UNSIGNED DEFAULT NULL
78
        ");
79
        $this->write("Added role_id column as nullable.");
80
81
        // 4. Migrate existing data
82
        $this->addSql("
83
            UPDATE permission_rel_role prr
84
            JOIN role r ON r.code = SUBSTRING(prr.role_code, 6)
85
            SET prr.role_id = r.id
86
        ");
87
        $this->write("Migrated data from role_code to role_id.");
88
89
        // 5. Drop old role_code
90
        $schemaManager = $this->connection->createSchemaManager();
91
        $columns = $schemaManager->listTableColumns('permission_rel_role');
92
        if (isset($columns['role_code'])) {
93
            $this->addSql("
94
                ALTER TABLE permission_rel_role DROP COLUMN role_code
95
            ");
96
            $this->write("Dropped column role_code.");
97
        }
98
99
        // 6. Set role_id NOT NULL
100
        $this->addSql("
101
            ALTER TABLE permission_rel_role
102
                MODIFY role_id INT UNSIGNED NOT NULL
103
        ");
104
        $this->write("Set role_id column to NOT NULL.");
105
106
        // 7. Add FK and index
107
        $this->addSql("
108
            ALTER TABLE permission_rel_role
109
                ADD CONSTRAINT FK_14B93D3DD60322AC FOREIGN KEY (role_id) REFERENCES role (id)
110
        ");
111
        $this->addSql("
112
            CREATE INDEX IDX_14B93D3DD60322AC ON permission_rel_role (role_id)
113
        ");
114
        $this->write("Added FK constraint and index for role_id.");
115
    }
116
117
    public function down(Schema $schema): void
118
    {
119
        // Drop FK and index if exists
120
        $schemaManager = $this->connection->createSchemaManager();
121
        if ($schemaManager->tablesExist(['permission_rel_role'])) {
122
            $foreignKeys = $schemaManager->listTableForeignKeys('permission_rel_role');
123
            foreach ($foreignKeys as $fk) {
124
                if ($fk->getForeignTableName() === 'role') {
125
                    $this->addSql(sprintf(
126
                        "ALTER TABLE permission_rel_role DROP FOREIGN KEY %s",
127
                        $fk->getName()
128
                    ));
129
                }
130
            }
131
            $this->addSql("DROP INDEX IF EXISTS IDX_14B93D3DD60322AC ON permission_rel_role");
132
            $columns = $schemaManager->listTableColumns('permission_rel_role');
133
            if (isset($columns['role_id'])) {
134
                $this->addSql("ALTER TABLE permission_rel_role DROP COLUMN role_id");
135
            }
136
        }
137
138
        $this->addSql("DROP TABLE IF EXISTS role");
139
        $this->write("Rolled back migration: dropped role table and role_id column.");
140
    }
141
142
    private function getRoleConstantValue(string $code): int
143
    {
144
        $map = [
145
            'INVITEE' => 1,
146
            'STUDENT' => 5,
147
            'TEACHER' => 10,
148
            'ADMIN' => 15,
149
            'SUPER_ADMIN' => 20,
150
            'GLOBAL_ADMIN' => 25,
151
            'HR' => 30,
152
            'QUESTION_MANAGER' => 35,
153
            'SESSION_MANAGER' => 40,
154
            'STUDENT_BOSS' => 45,
155
        ];
156
157
        return $map[$code] ?? 0;
158
    }
159
160
    private function getRoleTitle(string $code): string
161
    {
162
        $map = [
163
            'INVITEE' => 'Invitee',
164
            'STUDENT' => 'Student',
165
            'TEACHER' => 'Teacher',
166
            'ADMIN' => 'Administrator',
167
            'SUPER_ADMIN' => 'Super Administrator',
168
            'GLOBAL_ADMIN' => 'Global Administrator',
169
            'HR' => 'Human Resources',
170
            'QUESTION_MANAGER' => 'Question Manager',
171
            'SESSION_MANAGER' => 'Session Manager',
172
            'STUDENT_BOSS' => 'Student Boss',
173
        ];
174
175
        return $map[$code] ?? $code;
176
    }
177
178
    private function getRoleDescription(string $code): string
179
    {
180
        $map = [
181
            'INVITEE' => 'User invited with limited rights',
182
            'STUDENT' => 'Regular student user',
183
            'TEACHER' => 'User with teaching rights',
184
            'ADMIN' => 'Platform administrator',
185
            'SUPER_ADMIN' => 'Full platform administrator',
186
            'GLOBAL_ADMIN' => 'Global admin user',
187
            'HR' => 'HR manager',
188
            'QUESTION_MANAGER' => 'Manages question banks',
189
            'SESSION_MANAGER' => 'Manages sessions',
190
            'STUDENT_BOSS' => 'Special student role',
191
        ];
192
193
        return $map[$code] ?? '';
194
    }
195
}
196