Manipulação de Usuários no Moodle (via SQL)
Autor: Blog do Dieval | Publicado: 2012-03-12T07:50:00-07:00

O conceito básico da organização do moodle é apresentado pela figura a seguir.



Essa ideia tem uma grande desvantagem, principalmente para quem usar um banco de dados como o MySQL (MyISAM), que não possui integridade referencial... a base pode ficar com problemas de integridade nas relações.

No meu caso, a situação foi observada, seguindo a seguinte trilha:

select * from mdl_role;
Onde se obtém os role_ids dos perfil desejados, no meu caso, Tutor/Professor (id=3)
Para verificar quem tem uma regra específica, podemo verificar na tabela _role_assignments. Nessa tabela, temos a associação dos usuários com os contextos e com as regras

+--------------+---------------------+------+-----+---------+----------------+
| Field        | Type                | Null | Key | Default | Extra          |
+--------------+---------------------+------+-----+---------+----------------+
| id           | bigint(10) unsigned | NO   | PRI | NULL    | auto_increment |
| roleid       | bigint(10) unsigned | NO   | MUL | 0       |                |
| contextid    | bigint(10) unsigned | NO   | MUL | 0       |                |
| userid       | bigint(10) unsigned | NO   | MUL | 0       |                |
| hidden       | tinyint(1) unsigned | NO   |     | 0       |                |
| timestart    | bigint(10) unsigned | NO   |     | 0       |                |
| timeend      | bigint(10) unsigned | NO   |     | 0       |                |
| timemodified | bigint(10) unsigned | NO   |     | 0       |                |
| modifierid   | bigint(10) unsigned | NO   |     | 0       |                |
| enrol        | varchar(20)         | NO   |     |         |                |
| sortorder    | bigint(10) unsigned | NO   | MUL | 0       |                |
+--------------+---------------------+------+-----+---------+----------------+

Logo, se precisamos listar os usuários de um determinado perfil, podemos usar a query a seguir:
select id,username,lastname,email from mdl_user where id in (select userid as id from mdl_role_assignments where roleid=3);
Mas o problema que verifiquei (no meu caso) e não sei exatamente quando isso ocorreu, foi o usuário não ter um registro em _role_assignments mas ter o vinculo ao curso na tabela context. Para entender o problema, a tabela possui esses campos:

+--------------+---------------------+------+-----+---------+----------------+
| Field        | Type                | Null | Key | Default | Extra          |
+--------------+---------------------+------+-----+---------+----------------+
| id           | bigint(10) unsigned | NO   | PRI | NULL    | auto_increment |
| contextlevel | bigint(10) unsigned | NO   | MUL | 0       |                |
| instanceid   | bigint(10) unsigned | NO   | MUL | 0       |                |
| path         | varchar(255)        | YES  | MUL | NULL    |                |
| depth        | tinyint(2) unsigned | NO   |     | 0       |                |
+--------------+---------------------+------+-----+---------+----------------+

Os valores contextlevel são definidos no código php, eu os encontrei em accesslib.php dentro da pasta lib do moodle. Os valores são:

// context definitions
define('CONTEXT_SYSTEM', 10);
define('CONTEXT_USER', 30);
define('CONTEXT_COURSECAT', 40);
define('CONTEXT_COURSE', 50);
define('CONTEXT_MODULE', 70);
define('CONTEXT_BLOCK', 80);

No path, encontramos uma string que indica categoria,curso,bloco etc... a inconsistência estava aqui, o usuário não estava associado ao curso pela tabela _role_assignments, mas tinha no seu contexto as informações do curso.

Para saber mais sobre o assunto:

Roles and permissions
Context