segunda-feira, 25 de outubro de 2010

Explorar Mensagem do Moodle com Comando SQL

A Plataforma Moodle tem um sistema de envio de mensagem interna. Caso você precise explorar   esse sistema sem usar a interface do Moodle, será necessário escrever comando SQL para comunicar diretamente com a base de dados.

    Através do comando SQL você pode:
  • Consultar histórico de mensagens enviadas; 
  • Pesquisar conteúdo das mensagens;

  • Apagar mensagens que ainda não foram lidas;
  • Pesquisar usuário que mais enviaram ou receberam mensagens.

As mensagens do Moodle são organizadas em duas tabelas:
  • mdl_message – Tabela que registra as mensagens enviadas
  • mdl_message_read - Tabela que registra as mensagens lidas. Armazena o histórico das mensagens.

    Quando uma mensagem é enviada, é armazenada na tabela mdl_message. Quando o destinatário recebe, ou seja, visualiza  na tela, a mensagem é transferida para a tabela mdl_message_read. Na tabela    mdl_message  só ficam  as mensagens que ainda não foram lidas. Já a  tabela mdl_message_read  só ficam as mensagens que já foram lidas.


Agora que já entendeu como funciona as tabelas, vamos ver os comandos SQL.

1- Consultar todas as mensagens enviadas que ainda não foram lidas.
SELECT m.id,m.timecreated, r.firstname, r.lastname,d.firstname, d.lastname, m.message FROM mdl_user r INNER JOIN mdl_message m ON r.id=m.useridfrom INNER JOIN mdl_user d ON d.id=m.useridto

Essa consultar retorna os seguintes campos:
  • m.id  - Id da mensagem
  • m.timecreated – Data do envio da mensagem
  • r.firstname e r.lastname – Nome do remitente
  • d.firstname e d.lastname – Nome do destinatário
  • m.message – Texto da mensagem

2- Consultar todas as mensagens lidas – Histórico de mensagens.


SELECT m.id,m.timecreated, m.timeread,r.firstname, r.lastname,d.firstname,d.lastname, m.message,m.mailed FROM mdl_user r INNER JOIN mdl_message_read m ON r.id=m.useridfrom INNER JOIN mdl_user d ON d.id=m.useridto

Essa consultar retorna os seguintes campos:
  • m.id  - Id da mensagem
  • m.timecreated – Data do envio da mensagem
  • m.timeread – Data da leitura da mensagem
  • r.firstname e r.lastname – Nome do remitente
  • d.firstname e d.lastname – Nome do destinatário
  • m.message – Texto da mensagem
  • m.mailed – Controle de envio de mensagem por e-mail

3 - Monitorar as mensagens enviadas por um determinado usuário que ainda não foram  lidas

SELECT m.id,m.timecreated, d.firstname, d.lastname, m.message FROM mdl_message m  INNER JOIN mdl_user d ON d.id=m.useridto WHERE m.useridfrom=?

Passe o parâmetro id do usuário em  m.useridfrom=?

Essa consultar retorna os seguintes campos:
  • m.id  - Id da mensagem
  • m.timecreated – Data do envio da mensagem
  • d.firstname e d.lastname – Nome do destinatário
  • m.message – Texto da mensagem

4 - Monitorar histórico das  mensagens enviadas por um determinado usuário. Mensagens lidas pelos destinatários.

SELECT m.id,m.timecreated, m.timeread, d.firstname, d.lastname, m.message, m.mailed  FROM mdl_message_read m  INNER JOIN mdl_user d ON d.id=m.useridto WHERE m.useridfrom=?

Passe o parâmetro id do usuário em  m.useridfrom=?


Essa consultar retorna os seguintes campos:
  • m.id  - Id da mensagem
  • m.timecreated – Data do envio da mensagem
  • m.timeread – Data da leitura da mensagem
  • d.firstname e d.lastname – Nome do destinatário
  • m.message – Texto da mensagem
  • m.mailed – Controle de envio de mensagem por e-mail

5- Pesquisar o conteúdo das mensagens enviadas no histórico das mensagens pela palavra-chave


SELECT m.id,m.timecreated, m.timeread,r.firstname, r.lastname,d.firstname,d.lastname, m.message,m.mailed FROM mdl_user r INNER JOIN mdl_message_read m ON r.id=m.useridfrom INNER JOIN mdl_user d ON d.id=m.useridto WHERE m.message LIKE '%texto da pesquisa%'

Passe o texto a ser pesquisado no comando  LIKE '%texto da pesquisa%'
Essa consultar retorna os mesmos campos da pesquisa do item 2.

6- Lista de usuários que mais enviarem  as mensagens
SELECT r.firstname, r.lastname,d.firstname, COUNT(m.useridfrom)  FROM mdl_user r INNER JOIN mdl_message_read m ON r.id=m.useridfrom INNER JOIN mdl_user d ON d.id=m.useridto GROUP BY r.firstname, r.lastname,d.firstname ORDER BY COUNT(m.useridfrom) DESC

Essa consulta retorna uma lista de usuários  (remetentes) e quantidade de mensagens enviadas pela ordem decrescente.  Lista os usuários que mais enviaram as mensagens.

Essa consulta é feita no histórico de mensagens. Para efetuá-la nas mensagens recentes, ou seja,  ainda não lidas, basta substituir a tabela  mdl_message_read para  mdl_message e mantar o restante de código inalterado.


7- Lista de usuários que mais receberam mensagens

SELECT d.firstname, d.lastname,d.firstname, COUNT(m.useridto)  FROM mdl_user d INNER JOIN mdl_message_read m ON  d.id=m.useridto GROUP BY d.firstname, d.lastname,d.firstname ORDER BY COUNT(m.useridto) DESC

Essa consulta retorna uma lista de usuários  (destinatários) e quantidade de mensagem recebidas pela ordem decrescente.  Lista os usuários que mais receberam as mensagens.

Essa consulta é feita no histórico de mensagens. Para efetuá-la nas mensagens recentes, ou seja,  ainda não lida, basta substituir a tabela  mdl_message_read para  mdl_message e mantar o restante de código inalterado.

8 – Apagar as mensagens enviada que ainda não foram lidas

DELETE  FROM mdl_message

9 – Apagar  o histórico das mensagens. Mensagens lidas

DELETE  FROM mdl_message_read

    Essas dicas ajudam você a desvendar como é organizado as mensagens no Moodle na camada de base de dados. Isso é tudo que você precisa para mapear erros ou falha do Moodle e também para para planejar integração com outros sistemas.

sexta-feira, 22 de outubro de 2010

Consultar os Tópicos do Fórum mais Acessados no Moodle com Comando SQL

Se você trabalha na pate de TI já deve ter recebido alguma solicitação do tutor ou coordenador do curso para montar um gráfico ou tabela com os típicos mais acessados do fórum.

    Ao receber essa demanda, você fuça um pouco o Moodle e percebe que não existe essa opção de relatório. Mesmo assim a equipe pedagógica fica no seu cangote esperando uma solução.

    Neste caso, você não tem outra alternativa que não seja extrair esses dados diretamente da base de dados do Moodle com comando SQL. Para aliviar a sua barra,  facilitando algumas dias ou semanas  de pesquisa vai aí  o macete.
Para consultar os tópicos mais acessados é necessário fazer a junção das seguintes tabelas:

  • mdl_forum – Tabela de fórum
  • mdl_forum_discussions – Tabela de tópicos
  • mdl_modules – Tabela de atividades do curso
  • mdl_log – Tabela de log
SQL para MySql

SELECT d.id,d.name,COUNT(l.info) FROM  mdl_forum_discussions d INNER JOIN mdl_forum f on f.id=d.forum  INNER JOIN mdl_course_modules cm ON f.id=cm.instance INNER JOIN mdl_modules m  ON cm.module=m.id INNER JOIN mdl_log l ON l.cmid=cm.id WHERE f.id=? AND m.name='forum' AND l.module='forum' AND l.action LIKE '%discussion%' AND l.info=d.id GROUP BY d.id,d.name ORDER BY COUNT(l.cmid) DESC

SQL para PostgreSQL


SELECT d.id,d.name,COUNT(l.info) FROM  mdl_forum_discussions d INNER JOIN mdl_forum f on f.id=d.forum  INNER JOIN mdl_course_modules cm ON f.id=cm.instance INNER JOIN mdl_modules m  ON cm.module=m.id INNER JOIN mdl_log l ON l.cmid=cm.id WHERE f.id=? AND m.name='forum' AND l.module='forum' AND l.action LIKE '%discussion%' AND l.info=CAST(d.id as varchar) GROUP BY d.id,d.name ORDER BY COUNT(l.cmid) DESC

O que diferencie os dois comandos SQL é que na  consulta para PostgreSQL há conversão d.id para texto com comando CAST: l.info=CAST(d.id as varchar).  Isso  porque o PostgreSQL não compara campo numérico com texto. Já MySQL é mais tolerante. Tirando isso, o restante do comando é igual.

Essa consulta extrai uma lista com os seguintes campos:

  • d.id – Id do tópico
  • d.name – Nome do tópico
  • COUNT(l.info) – Quantidade de acesso (click) no tópico

Você precisa especificar o id do fórum passando parâmetro em  f.id=? logo após o comando WHERE.
Caso não souber o id do fórum, localize na base de dados pelo nome do fórum com o seguinte comando SQL:

SELECT id FROM mdl_forum WHERE name='Nome do Fórum'

Bem, agora que você tem o comando SQL, só falta implementar isso numa linguagem de programação ou então executar a consulta no banco  e copiar o dados para excel para montar um gráfico bonito. Assim você dá solução à demanda de forma rápida e ninguém fica no seu cangote.

domingo, 17 de outubro de 2010

Apagar Nota, Atividades e Log do Aluno no Curso do Moodle com Comando SQL

Ao cancelar a inscrição de um aluno no curso no ambiente Moodle, os registros de na base de dados (atividades realizadas, nota e log) vinculado à matricula   não serão excluídos automaticamente, ou seja, em efeito cascata.  Uma das alternativas para remover os registros órfãos é executar o comando SQL diretamente na base de dados.
  
Para excluir os dados órfãos de uma matricula  no curso  é necessário dois parâmetros:

  • id do curso – Chave de identificação do curso na tabela mdl_course
  • id do usuário - Chave de identificação do curso na tabela mdl_user
Há uma postagem no blogue que explique isso. Clique aqui para ler.


Tendo os parâmetros da chave do curso e do usuário, só resta   apagar os registro com comando DELETE passando os parâmetros da chave do usuário e curso.
Passe o parâmetro da chave do curso em course=?   ou courseid =? e do usuário em userid=?


Apagar Log

DELETE FROM mdl_log WHERE course=? AND userid=?
   
Apagar Notas
DELETE FROM mdl_grade_grades WHERE  userid=? and itemid IN  (SELECT id FROM mdl_grade_items WHERE courseid=?)

    A sub consulta apaga apenas as notas de um determinado curso.
A tabela mdl_grade_grades é o repositório final de notas.


Apagar Atividades

Apagar nota do fórum
DELETE FROM mdl_forum_ratings WHERE post IN (SELECT p.id FROM mdl_forum_posts p INNER JOIN mdl_forum_discussions d ON p.discussion=p.id  WHERE p.userid=? AND d.course=?)

Apagar os comentários

DELETE FROM mdl_forum_posts WHERE userid=?  AND  discussion IN (SELECT id FROM mdl_forum_discussions WHERE course=?)

Não é recomendável apagar os comentários já que os comentários aninhados ficarão órfãos, ou seja, as respostas das respostas.

Apagar tópicos
DELETE  FROM mdl_forum_discussions WHERE userid=? AND course=?

Não é recomendável apagar os tópicos já que os comentários aninhados ficarão órfãos.

Apagar Tarefas

DELETE FROM mdl_assignment_submissions WHERE userid =? AND assignment IN (SELECT id FROM mdl_assignment WHERE course =?)

Ao remover as tarefas, as notas serão removidas automaticamente.


Apagar questionário

Apagar nota final
DELETE FROM mdl_quiz_grades WHERE userid =?  AND quiz IN (SELECT id FROM mdl_quiz WHERE course =?)

Apagar Tentativas de Respostas
DELETE FROM mdl_question_states WHERE  attempt IN (SELECT t.id FROM mdl_quiz_attempts t INNER JOIN  mdl_quiz q  ON t.quiz=q.id WHERE t.userid= ? AND course =?)

Apagar cada tentativa (inclusive a nota final)
DELETE FROM mdl_quiz_attempts WHERE userid =?  AND quiz IN (SELECT id FROM mdl_quiz WHERE course =?)

Para fazer limpeza total, os dados do aluno devem ser removida de todas de todas as atividades instanciadas no curso. Os comandos SQL acima demostrados se restringiram em remover as atividades do fórum, tarefa e questionário.  Para as demais atividades, siga a mesma lógica. Identifica as tabelas e apague os dados.
Feito isso, todo o histórico do aluno será removida da base de dados. Ao ser reinscrito no curso,  não terá nenhuma nota e nem log de acesso.

Extrair id do Usuário e do Curso no Moodle com Comando SQL


Id é  o parâmetro de identificação do registro na base de dados.


Id do Usuário

Comandos SQL que  recuperam  o id do usuário

Por -Email:
SELECT id FROM mdl_user WHERE email='e-mail'
 
Por login:
SELECT id FROM mdl_user WHERE username='login'

Por login e senha:
SELECT id FROM mdl_user WHERE username='login' AND password=MD5('senha')

Parâmetro GET do URL do Moodle com Id do usuário

URL do perfil do usuário:
http://[enderco do domininio]/user/view.php?id=21&course=3
O parâmetro id=21  é  a chave de identificação do usuário


Id do Curso
Comandos SQL que  recuperam o id do curso


Por nome
SELECT id FROM mdl_course WHERE fullname='Nome do Curso'

Pela Abreviatura
SELECT id FROM mdl_course WHERE shortname='Abreviatura'

Parâmetro GET do URL do Moodle com id do curso

URL do curso
http://[endereco dominico ]/course/view.php?id=3
O parâmetro id=3 é  a chave de identificação do curso.

domingo, 19 de setembro de 2010

Criar Curso no Moodle com Comando SQL


    Se você estiver fazendo migração de dados ou integração de um sistema acadêmico com a  Plataforma  Moodle, certamente vai precisar criar curso no Moodle diretamente no banco de  dados sem usar a interface do Moodle.

      Isso implica conhecer a estrutura das tabelas da base de dados do Moodle e fazer INSERT nas tabelas certas. Bem, isso me custou muitas horas de pesquisa. No final descobri que é necessário fazer apenas 4 INSERT básicos. Bem, vamos lá. São  três passos. 

Os comandos SQL foram testados na versão 1.9.3 do Moodle. Devem funcionar para qualquer versão 1.9.x e não para versão inferior a 1.9.
1º Passo – Criar o Curso
    Essa parte é mais moleza. Basta fazer um INSERT na tabela mdl_course com o seguinte comando SQL:

INSERT INTO mdl_course (category,fullname,shortname) VALUES (1,'Curso1','C1')   

Embora a tabela  mdl_course tenha muitas colunas, nesse exemplo foram usadas os mais importantes:
  • category -  Chave estrangeira da tabela de categoria de curso - mdl_course_categories 
  • fullname – Nome complete do curso 
  • shortname – Abreviatura do curso
No comando INSERT, foi criado um curso denominado Curso1 na categoria de curso padrão do Moodle, cujo id é 1. 
Após executar o INSERT, recupera o id do curso gerado automaticamente pelo banco de dados. No MySQL use o comando LAST_INSERT_ID().

2º Passo – Criar Contexto do Curso
    Com o curso criado, agora é necessário criar contexto do curso na tabela mdl_context com o seguinte comando SQL:

INSERT INTO mdl_context (contextlevel,instanceid) VALUES (50,?)
O campo contextlevel define o nível do contexto. Para curso 50 é o valor padrão da tabela de domínio. O campo instanceid é a instância do curso. Preencha esse campo com o valor do Id do curso gerado automaticamente no 1º passo.

    Ao executar o comando SQL, recupere o id do contexto gerado automaticamente. Use esse id para atualizar duas colunas:  path e depth. Para isso, execute o seguinte comando SQL:

UPDATE  mdl_context SET path='/1/3/$ID_CONTEXT', depth=3 WHERE id=$ID_CONTEXT

    Você precisa substituir a variável $ID_CONTEXT pelo id gerado automaticamente do INSERT anterior, ao executar o comando  para criar o contexto do curso. Se o id for 10,  o comando SQL de atualização será:

UPDATE  mdl_context SET path='/1/3/10', depth=3 WHERE id=10
Nesse momento você deve estar perguntando por que o campo path recebe  '/1/3/$ID_CONTEXT' como valor padrão  e o  campo  depth o número 3. Ainda não encontrei a resposta. Assim como você, eu também estou perguntando. Só sei que demorei três semanas mudando de variável até que funcionou. Se não preencher esses campos,  nenhum usuário consegue entrar no curso.  Se você encontrar alguma explicação  não esqueça de me avisar.

3º Passo – Criar tópico/seção padrão do curso 

Ao criar o curso no 1º passo, não foi definido o formato. Por padrão, será criado curso em formato de tópico.  Assim, é necessário cria um primeiro tópico, o tópico número zero,  do curso. Para isso, execute o seguinte comando SQL:

 INSERT INTO mdl_course_sections (course,section) VALUES (?,0)
Na coluna course o valor do parâmetro é o id do curso gerado automaticamente no 1º passo. A segunda coluna, a section define a ordem do tópico. Por se tratar do primeiro tópico, deixe zero como está.
    Há outras colunas na tabela mdl_course_sections. No entanto, para efeito de simplificação, se restringiu aos mais importantes.
    Ao finalizar o 3º passo, o curso já está criado no Moodle. Há muitas configurações do curso que não foram abordado nesse poste. Você pode fazer isso preenchendo todos as outras colunas das tabelas mdl_course ,  mdl_course_sections  e entre outros. Agora que o curso já está criado, acesse o ambiente Moodle com a senha do admin,  ative a edição e adicione o bloco de administração. Daí, faça o restante das configurações.

    Os comandos SQL foram testados apenas na versão 1.9.3. Deve funcionar em qualquer versão 1.9.x  já a estrutura das tabelas são as mesmas.  Não deve funcionar para as versões anteriores a 1.9.  Mas lógica é muito parecida. Não custa testar e fazer os ajustes necessários.  Agora boa programação, ou melhor, boa sorte na jornada de integração do Moodle com o seu sistema acadêmico.


Veja Também
Matricular Usuário no Curso do Moodle com Comando SQL

segunda-feira, 13 de setembro de 2010

Verificar a Senha do Usuário do Moodle com Comando SQL


    É muito comum no Moodle a senha do usuário não funcionar. Isso pode ocorrer após a importação da base de dados de usuário, cadastro de novo usuário, recuperação de curso  etc. O fato é que, de repente,  as senhas deixam de funcionar. Ao logar, mesmo usando o login e a senha corretos não funciona.  

    Quando isso acontece, as causas podem ser diversas. Para eliminar a hipótese que você esteja passando o login e a senha erradas ou que a tabela do banco que armazena a senha não foi corrompida,  é necessário fazer uma consulta SQL diretamente na base de dados. Nessa consulta, verifique se a combinação de login e senha existem. Para isso, execute o seguinte comando SQL:

SELECT COUNT(id) FROM   mdl_user WHERE username='joao' AND password=MD5('silva')
Se o resultado da consulta retornar 0 (zero)  significa que não existe nenhum usuário cadastrado com login João e senha silva. Caso retorna 1 (um) significa que o cadastro.

    Se a combinação do login e da senha funcionarem no comando SQL deve funcionar também ao logar no Moodle.  Se não funcionar no Moodle, é sinal que problema é outro e não da senha. Neste caso, você eliminou uma hipótese. Então, passe para próxima hipótese da lista e boa sorte.

Veja Também:
Recuperar Senha do Administrador do Moodle com Comando SQL

quinta-feira, 9 de setembro de 2010

Padronização das tabelas do Banco de Dados do Moodle


    A Plataforma Moodle é um sistema modular, ou seja, é um ambiente de gerenciamento de vários módulos voltado para gerenciamento de cursos.  A estrutura da base de dados reflete muito bem isso.

Padrão de Nome das  Tabelas

    As tabelas no banco de dados são compostas pelo prefixo e nome do módulo. mdl_ é o prefixo padrão. Isso pode ser alterado no momento de instalação.  Por exemplo, a tabela do módulo fórum é mdl_forum. Sendo mdl_ é o prefixo e forum é o nome do módulo. Todos os módulos seguem esse padrão.

Módulos que não são do Núcleo do Sistema
Os módulos que não compões o núcleo do sistema  ficam registradas na tabela mdl_modules. Para visualizar esses módulos,  basta fazer uma consulta na  tabela mdl_modules, usando o seguinte comando SQL:

SELECT id,name FROM mdl_modules
Resultado da pesquisa:
Id    name
1      assignment
2      chat
3      choice
4      data
5      forum
6      glossary
7      hotpot
8      journal
9      label
10      lams
11      lesson
12      quiz
13      resource
14      scorm
15      survey
16      wiki
17      workshop  

    Essa consulta foi feita nas versões 1.9.3 e 1.9.7 do Moodle. Isso já é padrão da versão 1.9+ A consulta lista os módulos que vêm na distribuição padrão do Moodle. A consulta traz os campos id (chave de identificação) e name (nome do módulo).

Tabela Principal e Secundária do Módulo
    A tabela principal de cada modulo é  prefixo + nome do módulo. Em cada módulo há outras tabelas, ou seja, tabelas secundárias. Por exemplo, a tabela principal do fórum é mdl_forum (prefixo + nome do módulo). O fórum é  composta por tópicos de discussões de comentários. Pois, as tabelas secundárias são:
  • mdl_forum_discussions – Tabela dos tópicos de discussão do fórum
  • mdl_forum_posts    - Tabela de comentários do fórum
  • mdl_forum_ratings    - Tabela de nota do fórum
    Nas tabelas secundárias dá para notar que o padrão do nome é prefixo + nome do módulo + funcionalidade do módulo.
    Embora tomamos como exemplo a tabela do fórum, esse padrão se aplica a todos os módulos.

Colunas Padrão nas Principais  Tabelas que não são do Núcleo do Sistema
    Até agora deu para entender a estrutura das tabelas dos módulos. Em cada tabela do módulo que não seja do núcleo do sistema, por padrão, deve as seguintes colunas:
  • id – Chave de identificação de cada registro da instância do módulo.
  • name – Nome  do registro da instância do módulo.
  • course – Id do curso  em que o módulo está vinculado. É a chave estrangeira da tabela mdl_course. Isso significa que cada registro da instancia de um módulo deve estar obrigatoriamente vinculado a um determinado curso.
Com esse padrão, torna possível montar uma rotina que faz leitura automática de todos os módulos. Para tornar isso mais claro, vamos ver um exemplo.
O comando SQL  abaixo faz uma consulta dos campos padrões do módulo fórum.

SELECT id, name, course FROM mdl_forum
Resultado da pesquisa:
id    name        course
1    Fórum Teste I     2
2    Fórum Teste II    2
3    Dúvidas Gerais    3
    A consulta retorna três registros de fórum. A coluna course indica que os fóruns registrados pertencem aos cursos cujo id são 2 e 3. A  mesma pesquisa pode ser aplicada a qualquer módulo, basta substituir a parte do nome da tabela após o prefixo pelo nome do outro módulo. Para pesquisar no módulo do questionário, o comando SQL seria:

SELECT id, name, course FROM mdl_quiz
    Isso não se aplica aos módulos que compões ao núcleo  do sistema tais como usuário, curso, log etc.

Tabelas dos módulos do sistema

mdl_user – Tabela principal do módulo do usuário
mdl_course  - Tabela principal do módulo do curso
mdl_log - Tabela principal do módulo de log
etc.
 
    Bem, você já deve ter sacado como é o padrão e a estrutura das tabelas do Moodle. Caso queira  explorar mais afundo isso, clique aqui, e acesse um arquivo com dump, ou seja, um backup da estrutura de todas as tabelas do Moodle 1.9.3 e com dados reais sobre curso. Estudar banco de dados não é uma tarefa muito mole, por isso lhe desejo boa sorte e muita paciência.