Por fin después de mucho luchar hemos dado con la respuesta de este atascamiento que tantos usuarios de nuestro espacio presentan. Si quieres compartir algo más puedes aportar tu comentario.
Solución:
La primera consulta le brinda una lista de usuarios que están inscritos en el curso, independientemente del rol que les hayan asignado (es posible estar inscrito en un curso y no tener ningún rol asignado).
La segunda consulta muestra todos los usuarios que tienen asignado el rol 5 en el nivel del curso. Es posible (aunque inusual) tener un rol asignado en el nivel del curso, sin estar realmente inscrito en el curso mismo.
Sin embargo, ambas consultas son defectuosas.
La primera consulta podría arrojar resultados duplicados si el usuario se inscribió en un curso a través de más de un método de inscripción (algo inusual, pero posible). Tampoco tiene en cuenta lo siguiente:
- El complemento de inscripción puede estar deshabilitado a nivel del sitio
- El complemento de inscripción puede estar deshabilitado en el nivel del curso (verifique ‘e.status = 0’ para encontrar solo complementos de inscripción activos)
- La inscripción puede tener un límite de tiempo; es posible que la inscripción del usuario haya vencido (verifique ‘ue.timeend = 0 OR ue.timeend > NOW()’ para encontrar solo inscripciones que no hayan vencido)
La segunda consulta asume que el rol de estudiante es id 5 (y también que no hay otros roles, basados en el rol de estudiante, que estén en uso). Normalmente usaría una consulta adicional para verificar la identificación del rol ‘estudiante’ en la tabla ‘mdl_role’ y luego usaría ese valor, o cambiaría las últimas líneas a lo siguiente:
ÚNASE a mdl_role r EN r.id = ra.roleid Y r.shortname = ‘estudiante’.
La segunda consulta tampoco verifica el ‘nivel de contexto’: es posible tener múltiples contextos con la misma identificación de instancia (como es posible tener la identificación del curso 5, la identificación de la categoría del curso 5, la identificación del usuario 5, etc.) – así que debe verificar que el contexto encontrado sea un contexto de ‘curso’ (contextlevel = 50).
Tampoco consulta los controles de usuarios suspendidos o eliminados (aunque, en el caso de los usuarios eliminados, deberían haberse dado de baja automáticamente de todos los cursos en el momento en que fueron eliminados).
Una solución completamente completa (posiblemente demasiado compleja para la mayoría de las situaciones) combinaría ambas consultas para verificar que el usuario se inscribió y se le asignó el rol de estudiante y no se suspendió:
SELECT DISTINCT u.id AS userid, c.id AS courseid
FROM mdl_user u
JOIN mdl_user_enrolments ue ON ue.userid = u.id
JOIN mdl_enrol e ON e.id = ue.enrolid
JOIN mdl_role_assignments ra ON ra.userid = u.id
JOIN mdl_context ct ON ct.id = ra.contextid AND ct.contextlevel = 50
JOIN mdl_course c ON c.id = ct.instanceid AND e.courseid = c.id
JOIN mdl_role r ON r.id = ra.roleid AND r.shortname = 'student'
WHERE e.status = 0 AND u.suspended = 0 AND u.deleted = 0
AND (ue.timeend = 0 OR ue.timeend > UNIX_TIMESTAMP(NOW())) AND ue.status = 0
(Tenga en cuenta que no he verificado minuciosamente esa consulta; se ejecuta, pero deberá hacer una referencia cruzada cuidadosa con las inscripciones reales para verificar que no me haya perdido nada).
El siguiente código genera una lista de todos sus cursos junto con cuántos estudiantes están inscritos en cada uno. Útil para saber si tienes algún curso sin nadie matriculado.
Mi respuesta :
SELECT cr.SHORTNAME,
cr.FULLNAME,
COUNT(ra.ID) AS enrolled
FROM `MDL_COURSE` cr
JOIN `MDL_CONTEXT` ct
ON ( ct.INSTANCEID = cr.ID )
LEFT JOIN `MDL_ROLE_ASSIGNMENTS` ra
ON ( ra.CONTEXTID = ct.ID )
WHERE ct.CONTEXTLEVEL = 50
AND ra.ROLEID = 5
GROUP BY cr.SHORTNAME,
cr.FULLNAME
ORDER BY `ENROLLED` ASC
En caso de necesidad el conteo de los alumnos matriculados en un curso. Puede lograrse simplemente usando el API de inscripción. El secreto key aquí está suministrando withcapability
parámetro a la count_enrolled_users()
función que sólo el Student
papel tiene. Por ejemplo:
$context = context_COURSE::instance($course->id);
count_enrolled_users($context,'mod/assignment:submit')
Aquí mod/assignment:submit
es una capacidad que solo el estudiante puede hacer, por lo que el número int devuelto no incluirá otros roles comunes, como los profesores inscritos en el curso.
He usado el código anterior para Moodle 3.1 en el tema renderer.php
para mostrar el número de estudiantes inscritos para cada curso en la lista de cursos en la página principal.