Moodle Userrole Courseid - moodle

i hope you have nice easterdays....
I need help by a special moodle-problem
I want to create a Table of Moodle-Courses
This works :-)
Now i want to check out the name of the Course-Users.... This works :-)
Now comes the problem:
How can i check out which role the course-user have in the special course?
Special: I need an SQL-Statement which gives me the User-Role (1,2,3...) form the User with the ID = 2 (User-ID) who is enroled in the course which the Id 50 (Course-ID).
Nice Regards

Try this query.
SELECT c.fullname as 'Course Name', concat(u.firstname ,' ',u.lastname) AS 'User Name',
r.shortname as 'Role Name', r.id as 'Role ID'
FROM mdl_role_assignments AS ra
JOIN mdl_role AS r ON r.id = ra.roleid
JOIN mdl_user AS u ON u.id = ra.userid
JOIN mdl_context AS ctx ON (ctx.id = ra.contextid AND ctx.contextlevel = 50)
JOIN mdl_course AS c ON ctx.instanceid = c.id
WHERE u.id = 2 # For specific user ID
AND c.id = 50 # For a specific course, remove it if you need to see all courses.

There's no need to use any sql scripts as Moodle already provides a method for it:
$roles = get_user_roles($context, $USER->id)
Here is the moodle forum discussion on the above: here

Related

Incorrect number of query parameters in Moodle *How to get the external links from course page

My Dear
I tried to run the following ad-hoc database query in Moodle but i got it error
there any way to fix it , thanks
*My target to find all the external links (URL) from course page
SELECT
concat('<a target="_new" href=%%WWWROOT%%/course/view.php?id=',
c.id, '">', c.fullname, '</a>') AS Course
,c.shortname,r.name
,(
SELECT CONCAT(u.firstname,' ', u.lastname) AS Teacher
FROM prefix_role_assignments AS ra
JOIN prefix_context AS ctx ON ra.contextid = ctx.id
JOIN prefix_user AS u ON u.id = ra.userid
WHERE ra.roleid = 3
AND ctx.instanceid = c.id
LIMIT 1
) AS Teacher
,concat('<a target="_new" href="%%WWWROOT%%/mod/resource/view.php?id=',
r.id, '">', r.name, '</a>') AS Resource
FROM prefix_resource AS r
JOIN prefix_course AS c ON r.course = c.id
WHERE r.reference LIKE 'https://stackoverflow.com/%'
Error message :
" Error when executing the query: ERROR: Incorrect number of query
parameters. Expected 2, got 0"
When executing SQL statements in Moodle, any '?' characters are used to indicate placeholders for parameters that need to be provided along with the query.
From the style of your query, I'm assuming you're using report_customsql or block_configurablereports for your query, so you won't have the option of providing such parameters.
If you look at the documentation here: https://docs.moodle.org/en/Custom_SQL_queries_report you will see that the workaround for this is to replace any '?' characters in your query with '%%Q%%'.
So the fixed query should look like:
SELECT concat('<a target="_new" href="%%WWWROOT%%/course/view.php%%Q%%id=',c.id,'">',c.fullname,'</a>') AS Course,
c.shortname,r.name, (SELECT CONCAT(u.firstname,' ', u.lastname) AS Teacher
FROM prefix_role_assignments AS ra
JOIN prefix_context AS ctx ON ra.contextid = ctx.id
JOIN prefix_user AS u ON u.id = ra.userid
WHERE ra.roleid = 3 AND ctx.instanceid = c.id LIMIT 1) AS Teacher,
concat('<a target="_new" href="%%WWWROOT%%/mod/resource/view.php%%Q%%id=',r.id,'">',r.name,'</a>') AS Resource
FROM prefix_resource AS r
JOIN prefix_course AS c ON r.course = c.id
WHERE r.reference LIKE 'https://stackoverflow.com/%'

Randomize students in Moodle

I have a Moodle classroom of about 60 students. All the students have to give a presentation. Is it possible to randomize the students in Moodle to decide the order of presentation?
I can't think of anything in Moodle that will do that.
But you could use SQL - replace xxx with the course id and RANDOM() with the relevant random function for your database
SELECT RANDOM() AS randid, u.id AS userid, u.firstname, u.lastname, u.email
FROM mdl_user u
JOIN (
SELECT DISTINCT ue.userid, e.courseid
FROM mdl_user_enrolments ue
JOIN mdl_enrol e ON e.id = ue.enrolid
) ue ON ue.userid = u.id
JOIN mdl_course c ON c.id = ue.courseid
WHERE c.id = xxx
AND u.deleted = 0
AND u.suspended = 0
ORDER BY 1

Postgresql WHERE clause using conditional sub-queries

I have a situation where each of the clients has users and each user can access to information about one or more branches.
We also have sys admins who can see everything and in database don't have any sites assigned to them. It just says the user is sys admin, so our system does not restrict the access.
I need to make a database query where I extract the list of branches the user has access to, but if the user is sys admin, I want to extract the list of all branches in the system.
I was trying something like this, but it does not work:
Select sites.name, sites.id
FROM sites
WHERE
sites.id IN (
CASE
WHEN (select u.level FROM users "u" WHERE u.username = 'JohnBrown') ='ROLE_SYSTEM_ADMIN'
THEN
(select id FROM sites)
ELSE
(select s2.id FROM users_have_sites uhs2
left join users u2 ON u2.id = uhs2.user_id
left join sites s2 ON s2.id = uhs2.site_id
where u2.username = 'JonhBrown')
END
)
I am getting this error:
ERROR: more than one row returned by a subquery used as an expression
I think something like this would work for you:
SELECT s.name, s.id
FROM sites s
LEFT JOIN users_have_sites uhs ON uhs.site_id = s.id
LEFT JOIN users u ON u.id = uhs.user_id AND u.username = 'JohnBrown'
WHERE (CASE WHEN (SELECT u.level FROM users WHERE u.username = 'JohnBrown') = 'ROLE_SYSTEM_ADMIN'
THEN TRUE ELSE FALSE END
OR u.id IS NOT NULL);
The LEFT JOINs do not filter out records from the sites table like an INNER JOIN would, so any site that meets either of the conditions in the WHERE clause will be in the result. This means that if your subquery shows that the user is a sys admind or if there is a record for that user and site is found in the users_have_sites table, those sites will be in the result set.
EDIT: Another fairly easy to read solution would be something like this:
SELECT s.name, s.id
FROM sites s,
users_have_sites uhs,
users u
WHERE u.username = 'JohnBrown'
AND (u.level = 'ROLE_SYSTEM_ADMIN'
OR (s.id = uhs.site_id AND u.id = uhs.user_id))
GROUP BY s.name, s.id;
The downside of this query is that it uses implicit joins which are not used very much any more. They are generally seen as an older way of doing things and can be less efficient. This will join all rows of on table to all rows of another table and then all of your filtering (and what you would generally think of as join conditions) are all in the WHERE clause. These typed of joins can be less efficient but this one should not be as the WHERE clause makes sure that only 1 result per site.
I think that this does what you want:
select s.name, s.id
from sites s
inner join users u on u.username = 'JohnBrown'
where
u.level = 'ROLE_SYSTEM_ADMIN'
or exists (
select 1
from users_have_sites uhs
where uhs.site_id = s.id and uhs.user_id = u.id
)
Here is another version of the query that you may find easier to follow (I do):
select s.name, s.id
from users u
inner join sites s
on u.level = 'ROLE_SYSTEM_ADMIN'
or exists (
select 1
from users_have_sites uhs
where uhs.site_id = s.id and uhs.user_id = u.id
)
where u.username = 'JohnBrown'

how to get courses created by particular user in moodle 3

Currently I'm working on moodle-3 plug-in development,and I have a user Id who is a course creator and i want to get all courses created by that user,is their any function, I can use or if you can help me with names of tables where I can fetch this data.I tried table called standard log where I can get all events is that only way to do it.
Not sure if this will work but you could try searching for courses that have the coursecreator role assigned.
SELECT r.shortname, u.username, c.fullname AS coursename
FROM mdl_role r
JOIN mdl_role_assignments ra ON ra.roleid = r.id
JOIN mdl_context ctx ON ctx.id = ra.contextid AND ctx.contextlevel = 50
JOIN mdl_course c ON c.id = ctx.instanceid
JOIN mdl_user u ON u.id = ra.userid
WHERE r.shortname = 'coursecreator'

user information and the course name with time spend in a course

Can anybody help me out with the code to get the user's firstname, lastname, the course name and the time spend by the user on that course in moodle 2.6? Using configurable reports doesnot give me the exact solution.
You can use the following sql to find the course participants.
SELECT u.id, u.username, u.firstname, u.lastname FROM mdl_user u JOIN (SELECT DISTINCT eu1_u.id FROM mdl_user eu1_u JOIN mdl_user_enrolments eu1_ue ON eu1_ue.userid = eu1_u.id JOIN mdl_enrol eu1_e ON (eu1_e.id = eu1_ue.enrolid AND eu1_e.courseid = 4) WHERE eu1_u.deleted = 0 AND eu1_u.id <> 1 ) e ON e.id = u.id LEFT JOIN mdl_user_lastaccess ul ON (ul.userid = u.id AND ul.courseid = 4) LEFT JOIN mdl_context ctx ON (ctx.instanceid = u.id AND ctx.contextlevel = 30) ORDER BY u.lastaccess DESC;
There are two ways to find the time spend in a course:
If course completion is enabled and the user has completed the course, then the time spend in the course will be the difference between the timestarted and timecompleted fields in mdl_course_completions table.
You can also calculate the time spent in a course from moodle logs.
hope this helps.