Let us assume we have this valid query for Moodle:
SELECT u.id, u.username, c.fullname
FROM {user} AS u
INNER JOIN {user_enrolments} AS ue ON u.id = ue.userid
INNER JOIN {enrol} AS e ON e.id = ue.enrolid
INNER JOIN {course} AS c ON c.id = e.courseid
WHERE u.deleted = 0
AND
e.enrol = 'manual'
AND
c.id = 8
AND
u.id = 4
I will show you how to transform that into fully parametrized query using Moodle DB API and you can apply the approach to any query.
So in the query above you have these conditions:
- u.deleted is 0
- e.enrol is manual
- c.id is 8
- u.id is 4
So let us prepare those conditions for insertion in the query:
$params = array();
list($udeletedsql , $param) = $DB->get_in_or_equal(0, SQL_PARAMS_NAMED);
$params += $param;
list($enrolsql, $param) = $DB->get_in_or_equal('manual', SQL_PARAMS_NAMED);
$params += $param;
list($coursesql, $param) = $DB->get_in_or_equal(8, SQL_PARAMS_NAMED);
$params += $param;
list($usersql, $param) = $DB->get_in_or_equal($selID, SQL_PARAMS_NAMED);
$params += $param;
// get_in_or_equal returns us part that should be added to SQL and parameter value as array. We add parameters to one main parameter array.
// Than we adjust the query.
$sql = "
SELECT u.id, u.username, c.fullname
FROM {user} AS u
INNER JOIN {user_enrolments} AS ue ON u.id = ue.userid
INNER JOIN {enrol} AS e ON e.id = ue.enrolid
INNER JOIN {course} AS c ON c.id = e.courseid
WHERE u.deleted {$udeletedsql}
AND
e.enrol {$enrolsql}
AND
c.id {$coursesql}
AND
u.id {$usersql}
";
// And finally call the query.
$results = $DB->get_record_sql($sql, $params, MUST_EXIST);
This way all parameters are guaranteed to be cleaned before execution and you are as safe as you can be.