diff --git a/admin/tool/log/store/standard/classes/privacy/provider.php b/admin/tool/log/store/standard/classes/privacy/provider.php index 1994e29f5bc..2761ca26c64 100644 --- a/admin/tool/log/store/standard/classes/privacy/provider.php +++ b/admin/tool/log/store/standard/classes/privacy/provider.php @@ -74,10 +74,8 @@ class provider implements */ public static function add_contexts_for_userid(contextlist $contextlist, $userid) { $sql = " - SELECT ctx.id - FROM {context} ctx - JOIN {logstore_standard_log} l - ON l.contextid = ctx.id + SELECT l.contextid + FROM {logstore_standard_log} l WHERE l.userid = :userid1 OR l.relateduserid = :userid2 OR l.realuserid = :userid3"; diff --git a/admin/tool/monitor/classes/privacy/provider.php b/admin/tool/monitor/classes/privacy/provider.php index 9b481d3dbea..b2174ef3a51 100644 --- a/admin/tool/monitor/classes/privacy/provider.php +++ b/admin/tool/monitor/classes/privacy/provider.php @@ -91,8 +91,10 @@ class provider implements \core_privacy\local\metadata\provider, \core_privacy\l $sql = "SELECT DISTINCT ctx.id FROM {context} ctx LEFT JOIN {tool_monitor_rules} mr ON ctx.instanceid = mr.userid AND ctx.contextlevel = :contextuserrule + AND mr.userid = :useridsubscriptions LEFT JOIN {tool_monitor_subscriptions} ms ON ctx.instanceid = ms.userid AND ctx.contextlevel = :contextusersub - WHERE (ms.userid = :useridrules OR mr.userid = :useridsubscriptions)"; + AND ms.userid = :useridrules + WHERE ms.id IS NOT NULL OR mr.id IS NOT NULL"; $contextlist = new contextlist(); $contextlist->add_from_sql($sql, $params); diff --git a/auth/oauth2/classes/privacy/provider.php b/auth/oauth2/classes/privacy/provider.php index 2ab7ff01aa5..5a3476a6572 100644 --- a/auth/oauth2/classes/privacy/provider.php +++ b/auth/oauth2/classes/privacy/provider.php @@ -75,8 +75,7 @@ class provider implements public static function get_contexts_for_userid(int $userid) : contextlist { $sql = "SELECT ctx.id FROM {auth_oauth2_linked_login} ao - JOIN {user} u ON ao.userid = u.id - JOIN {context} ctx ON ctx.instanceid = u.id AND ctx.contextlevel = :contextlevel + JOIN {context} ctx ON ctx.instanceid = ao.userid AND ctx.contextlevel = :contextlevel WHERE ao.userid = :userid"; $params = ['userid' => $userid, 'contextlevel' => CONTEXT_USER]; $contextlist = new contextlist(); diff --git a/competency/classes/privacy/provider.php b/competency/classes/privacy/provider.php index 686d6a3a91b..39ff45c5048 100644 --- a/competency/classes/privacy/provider.php +++ b/competency/classes/privacy/provider.php @@ -250,11 +250,13 @@ class provider implements ON tpl.contextid = ctx.id LEFT JOIN {" . template_cohort::TABLE . "} tch ON tch.templateid = tpl.id + AND tch.usermodified = :userid2 LEFT JOIN {" . template_competency::TABLE . "} tc ON tc.templateid = tpl.id + AND tc.usermodified = :userid3 WHERE tpl.usermodified = :userid1 - OR tch.usermodified = :userid2 - OR tc.usermodified = :userid3"; + OR tch.id IS NOT NULL + OR tc.id IS NOT NULL"; $params = ['userid1' => $userid, 'userid2' => $userid, 'userid3' => $userid]; $contextlist->add_from_sql($sql, $params); @@ -309,12 +311,14 @@ class provider implements AND ctx.contextlevel = :userlevel LEFT JOIN {" . plan_competency::TABLE . "} pc ON pc.planid = p.id + AND pc.usermodified = :userid3 LEFT JOIN {" . user_competency_plan::TABLE . "} upc ON upc.planid = p.id + AND upc.usermodified = :userid4 WHERE p.usermodified = :userid1 OR p.reviewerid = :userid2 - OR pc.usermodified = :userid3 - OR upc.usermodified = :userid4"; + OR pc.id IS NOT NULL + OR upc.id IS NOT NULL"; $params = [ 'userlevel' => CONTEXT_USER, 'userid1' => $userid, @@ -333,17 +337,19 @@ class provider implements AND ctx.contextlevel = :userlevel1 LEFT JOIN {" . evidence::TABLE . "} e ON e.usercompetencyid = uc.id + AND (e.usermodified = :userid3 OR e.actionuserid = :userid4) LEFT JOIN {" . user_evidence::TABLE . "} ue ON ue.userid = ctx.instanceid AND ctx.contextlevel = :userlevel2 + AND ue.usermodified = :userid5 LEFT JOIN {" . user_evidence_competency::TABLE . "} uec ON uec.userevidenceid = ue.id + AND uec.usermodified = :userid6 WHERE uc.usermodified = :userid1 OR uc.reviewerid = :userid2 - OR e.usermodified = :userid3 - OR e.actionuserid = :userid4 - OR ue.usermodified = :userid5 - OR uec.usermodified = :userid6"; + OR e.id IS NOT NULL + OR ue.id IS NOT NULL + OR uec.id IS NOT NULL"; $params = [ 'userlevel1' => CONTEXT_USER, 'userlevel2' => CONTEXT_USER, @@ -367,15 +373,19 @@ class provider implements LEFT JOIN {" . user_competency::TABLE . "} uc ON uc.userid = ctx.instanceid AND ctx.contextlevel = :userlevel2 + AND uc.userid = :userid2 LEFT JOIN {" . user_evidence::TABLE . "} ue ON ue.userid = ctx.instanceid AND ctx.contextlevel = :userlevel3 + AND ue.userid = :userid3 LEFT JOIN {" . user_competency_course::TABLE . "} ucc - ON ucc.courseid = ctx.instanceid AND ctx.contextlevel = :courselevel + ON ucc.courseid = ctx.instanceid + AND ctx.contextlevel = :courselevel + AND ucc.userid = :userid4 WHERE p.userid = :userid1 - OR uc.userid = :userid2 - OR ue.userid = :userid3 - OR ucc.userid = :userid4"; + OR uc.id IS NOT NULL + OR ue.id IS NOT NULL + OR ucc.id IS NOT NULL"; $params = [ 'userlevel1' => CONTEXT_USER, 'userlevel2' => CONTEXT_USER, diff --git a/completion/classes/privacy/provider.php b/completion/classes/privacy/provider.php index e8d2f9e1fa7..0be20a2d893 100644 --- a/completion/classes/privacy/provider.php +++ b/completion/classes/privacy/provider.php @@ -89,8 +89,10 @@ class provider implements \core_privacy\local\metadata\provider, \core_privacy\l $join = "JOIN {course_completion_criteria} {$cccalias} ON {$joinfield} = {$cccalias}.course LEFT JOIN {course_modules_completion} {$cmcalias} ON {$cccalias}.moduleinstance = {$cmcalias}.coursemoduleid - LEFT JOIN {course_completion_crit_compl} {$ccccalias} ON {$ccccalias}.criteriaid = {$cccalias}.id"; - $where = "{$cmcalias}.userid = :{$prefix}_moduleuserid OR {$ccccalias}.userid = :{$prefix}_courseuserid"; + AND {$cmcalias}.userid = :{$prefix}_moduleuserid + LEFT JOIN {course_completion_crit_compl} {$ccccalias} ON {$ccccalias}.criteriaid = {$cccalias}.id + AND {$ccccalias}.userid = :{$prefix}_courseuserid"; + $where = "{$cmcalias}.id IS NOT NULL OR {$ccccalias}.id IS NOT NULL"; $params = ["{$prefix}_moduleuserid" => $userid, "{$prefix}_courseuserid" => $userid]; return [$join, $where, $params]; diff --git a/completion/tests/fixtures/completion_creation.php b/completion/tests/fixtures/completion_creation.php index b064d5a4515..30ff3918ffb 100644 --- a/completion/tests/fixtures/completion_creation.php +++ b/completion/tests/fixtures/completion_creation.php @@ -103,8 +103,9 @@ trait completion_creation { * Complete some of the course completion criteria. * * @param stdClass $user The user object + * @param bool $modulecompletion If true will complete the activity module completion thing. */ - public function complete_course($user) { + public function complete_course($user, $modulecompletion = true) { $this->getDataGenerator()->enrol_user($user->id, $this->course->id, 'student'); $completion = new \completion_info($this->course); $criteriacompletions = $completion->get_completions($user->id, COMPLETION_CRITERIA_TYPE_ROLE); @@ -112,7 +113,9 @@ trait completion_creation { foreach ($criteriacompletions as $ccompletion) { $criteria->complete($ccompletion); } - // Set activity as complete. - $completion->update_state($this->cm, COMPLETION_COMPLETE, $user->id); + if ($modulecompletion) { + // Set activity as complete. + $completion->update_state($this->cm, COMPLETION_COMPLETE, $user->id); + } } } diff --git a/completion/tests/privacy_test.php b/completion/tests/privacy_test.php index 7e1939ad7b4..d41863abe6e 100644 --- a/completion/tests/privacy_test.php +++ b/completion/tests/privacy_test.php @@ -47,7 +47,7 @@ class core_completion_privacy_test extends \core_privacy\tests\provider_testcase $this->resetAfterTest(); $user = $this->getDataGenerator()->create_user(); $this->create_course_completion(); - $this->complete_course($user); + $this->complete_course($user, false); list($join, $where, $params) = \core_completion\privacy\provider::get_course_completion_join_sql($user->id, 'comp', 'c.id'); $sql = "SELECT DISTINCT c.id diff --git a/grade/classes/privacy/provider.php b/grade/classes/privacy/provider.php index 497650405fc..282253a8f5a 100644 --- a/grade/classes/privacy/provider.php +++ b/grade/classes/privacy/provider.php @@ -127,18 +127,21 @@ class provider implements $sql = " SELECT DISTINCT ctx.id FROM {context} ctx - LEFT JOIN {grade_outcomes_history} goh - ON (goh.courseid > 0 AND goh.courseid = ctx.instanceid AND ctx.contextlevel = :courselevel1) + LEFT JOIN {grade_outcomes_history} goh ON goh.loggeduser = :userid1 AND ( + (goh.courseid > 0 AND goh.courseid = ctx.instanceid AND ctx.contextlevel = :courselevel1) OR ((goh.courseid IS NULL OR goh.courseid < 1) AND ctx.id = :syscontextid) - LEFT JOIN {grade_categories_history} gch - ON gch.courseid = ctx.instanceid + ) + LEFT JOIN {grade_categories_history} gch ON gch.loggeduser = :userid2 AND ( + gch.courseid = ctx.instanceid AND ctx.contextlevel = :courselevel2 - LEFT JOIN {grade_items_history} gih - ON gih.courseid = ctx.instanceid + ) + LEFT JOIN {grade_items_history} gih ON gih.loggeduser = :userid3 AND ( + gih.courseid = ctx.instanceid AND ctx.contextlevel = :courselevel3 - WHERE goh.loggeduser = :userid1 - OR gch.loggeduser = :userid2 - OR gih.loggeduser = :userid3"; + ) + WHERE goh.id IS NOT NULL + OR gch.id IS NOT NULL + OR gih.id IS NOT NULL"; $params = [ 'syscontextid' => SYSCONTEXTID, 'courselevel1' => CONTEXT_COURSE, @@ -159,13 +162,16 @@ class provider implements AND ctx.contextlevel = :courselevel LEFT JOIN {grade_grades} gg ON gg.itemid = gi.id + AND (gg.userid = :userid1 OR gg.usermodified = :userid2) LEFT JOIN {grade_grades_history} ggh ON ggh.itemid = gi.id - WHERE gg.userid = :userid1 - OR gg.usermodified = :userid2 - OR ggh.userid = :userid3 + AND ( + ggh.userid = :userid3 OR ggh.loggeduser = :userid4 - OR ggh.usermodified = :userid5"; + OR ggh.usermodified = :userid5 + ) + WHERE gg.id IS NOT NULL + OR ggh.id IS NOT NULL"; $params = [ 'courselevel' => CONTEXT_COURSE, 'userid1' => $userid, @@ -184,14 +190,14 @@ class provider implements JOIN {grade_grades_history} ggh ON ctx.contextlevel = :userlevel AND ggh.userid = ctx.instanceid - LEFT JOIN {grade_items} gi - ON ggh.itemid = gi.id - WHERE gi.id IS NULL AND ( ggh.userid = :userid1 OR ggh.usermodified = :userid2 OR ggh.loggeduser = :userid3 - )"; + ) + LEFT JOIN {grade_items} gi + ON ggh.itemid = gi.id + WHERE gi.id IS NULL"; $params = [ 'userlevel' => CONTEXT_USER, 'userid1' => $userid, diff --git a/mod/assign/classes/privacy/provider.php b/mod/assign/classes/privacy/provider.php index c706711901b..a99868f1bee 100644 --- a/mod/assign/classes/privacy/provider.php +++ b/mod/assign/classes/privacy/provider.php @@ -139,15 +139,53 @@ class provider implements metadataprovider, pluginprovider, preference_provider JOIN {modules} m ON cm.module = m.id AND m.name = :modulename JOIN {assign} a ON cm.instance = a.id JOIN {context} ctx ON cm.id = ctx.instanceid AND ctx.contextlevel = :contextlevel - LEFT JOIN {assign_grades} ag ON a.id = ag.assignment - LEFT JOIN {assign_overrides} ao ON a.id = ao.assignid - LEFT JOIN {assign_submission} asn ON a.id = asn.assignment - LEFT JOIN {assign_user_flags} auf ON a.id = auf.assignment - LEFT JOIN {assign_user_mapping} aum ON a.id = aum.assignment - WHERE ag.userid = :userid OR ag.grader = :graderid OR ao.userid = :aouserid - OR asn.userid = :asnuserid OR auf.userid = :aufuserid OR aum.userid = :aumuserid"; + JOIN {assign_grades} ag ON a.id = ag.assignment AND (ag.userid = :userid OR ag.grader = :graderid)"; + + global $DB; + $contextlist = new contextlist(); $contextlist->add_from_sql($sql, $params); + + $sql = "SELECT ctx.id + FROM {course_modules} cm + JOIN {modules} m ON cm.module = m.id AND m.name = :modulename + JOIN {assign} a ON cm.instance = a.id + JOIN {context} ctx ON cm.id = ctx.instanceid AND ctx.contextlevel = :contextlevel + JOIN {assign_overrides} ao ON a.id = ao.assignid + WHERE ao.userid = :aouserid"; + + $contextlist->add_from_sql($sql, $params); + + $sql = "SELECT ctx.id + FROM {course_modules} cm + JOIN {modules} m ON cm.module = m.id AND m.name = :modulename + JOIN {assign} a ON cm.instance = a.id + JOIN {context} ctx ON cm.id = ctx.instanceid AND ctx.contextlevel = :contextlevel + JOIN {assign_submission} asn ON a.id = asn.assignment + WHERE asn.userid = :asnuserid"; + + $contextlist->add_from_sql($sql, $params); + + $sql = "SELECT ctx.id + FROM {course_modules} cm + JOIN {modules} m ON cm.module = m.id AND m.name = :modulename + JOIN {assign} a ON cm.instance = a.id + JOIN {context} ctx ON cm.id = ctx.instanceid AND ctx.contextlevel = :contextlevel + JOIN {assign_user_flags} auf ON a.id = auf.assignment + WHERE auf.userid = :aufuserid"; + + $contextlist->add_from_sql($sql, $params); + + $sql = "SELECT ctx.id + FROM {course_modules} cm + JOIN {modules} m ON cm.module = m.id AND m.name = :modulename + JOIN {assign} a ON cm.instance = a.id + JOIN {context} ctx ON cm.id = ctx.instanceid AND ctx.contextlevel = :contextlevel + JOIN {assign_user_mapping} aum ON a.id = aum.assignment + WHERE aum.userid = :aumuserid"; + + $contextlist->add_from_sql($sql, $params); + manager::plugintype_class_callback('assignfeedback', self::ASSIGNFEEDBACK_INTERFACE, 'get_context_for_userid_within_feedback', [$userid, $contextlist]); manager::plugintype_class_callback('assignsubmission', self::ASSIGNSUBMISSION_INTERFACE, diff --git a/mod/data/classes/privacy/provider.php b/mod/data/classes/privacy/provider.php index e07665bbf7a..b2c36a8c3a3 100644 --- a/mod/data/classes/privacy/provider.php +++ b/mod/data/classes/privacy/provider.php @@ -105,9 +105,10 @@ class provider implements INNER JOIN {modules} m ON m.id = cm.module AND m.name = :modname INNER JOIN {data} d ON d.id = cm.instance INNER JOIN {data_records} dr ON dr.dataid = d.id - LEFT JOIN {comments} com ON com.commentarea=:commentarea and com.itemid = dr.id - LEFT JOIN {rating} r ON r.contextid = c.id AND r.itemid = dr.id AND r.component = :moddata AND r.ratingarea = :ratingarea - WHERE dr.userid = :userid OR com.userid = :userid1 OR r.userid = :userid2"; + LEFT JOIN {comments} com ON com.commentarea=:commentarea and com.itemid = dr.id AND com.userid = :userid1 + LEFT JOIN {rating} r ON r.contextid = c.id AND r.itemid = dr.id AND r.component = :moddata + AND r.ratingarea = :ratingarea AND r.userid = :userid2 + WHERE dr.userid = :userid OR com.id IS NOT NULL OR r.id IS NOT NULL"; $params = [ 'modname' => 'data', diff --git a/mod/lesson/classes/privacy/provider.php b/mod/lesson/classes/privacy/provider.php index a2b07060a63..afb6417f334 100644 --- a/mod/lesson/classes/privacy/provider.php +++ b/mod/lesson/classes/privacy/provider.php @@ -133,19 +133,24 @@ class provider implements AND ctx.contextlevel = :modulelevel LEFT JOIN {lesson_attempts} la ON la.lessonid = l.id + AND la.userid = :userid1 LEFT JOIN {lesson_branch} lb ON lb.lessonid = l.id + AND lb.userid = :userid2 LEFT JOIN {lesson_grades} lg ON lg.lessonid = l.id + AND lg.userid = :userid3 LEFT JOIN {lesson_overrides} lo ON lo.lessonid = l.id + AND lo.userid = :userid4 LEFT JOIN {lesson_timer} lt ON lt.lessonid = l.id - WHERE la.userid = :userid1 - OR lb.userid = :userid2 - OR lg.userid = :userid3 - OR lt.userid = :userid4 - OR lo.userid = :userid5"; + AND lt.userid = :userid5 + WHERE la.id IS NOT NULL + OR lb.id IS NOT NULL + OR lg.id IS NOT NULL + OR lo.id IS NOT NULL + OR lt.id IS NOT NULL"; $params = [ 'lesson' => 'lesson', diff --git a/mod/quiz/classes/privacy/provider.php b/mod/quiz/classes/privacy/provider.php index 81f3be1d949..d93badeb02d 100644 --- a/mod/quiz/classes/privacy/provider.php +++ b/mod/quiz/classes/privacy/provider.php @@ -148,7 +148,8 @@ class provider implements " . $qubaid->from . " WHERE ( qa.userid = :qauserid OR - " . $qubaid->where() . " + " . $qubaid->where() . " OR + qo.id IS NOT NULL ) AND qa.preview = 0 "; diff --git a/rating/classes/privacy/provider.php b/rating/classes/privacy/provider.php index 1bab73b54d9..4237ea28518 100644 --- a/rating/classes/privacy/provider.php +++ b/rating/classes/privacy/provider.php @@ -139,12 +139,13 @@ class provider implements // Join the rating table with the specified alias and the relevant join params. $join = "LEFT JOIN {rating} {$alias} ON "; + $join .= "{$alias}.userid = :ratinguserid{$count} AND "; $join .= "{$alias}.component = :ratingcomponent{$count} AND "; $join .= "{$alias}.ratingarea = :ratingarea{$count} AND "; $join .= "{$alias}.itemid = {$itemidjoin}"; // Match against the specified user. - $userwhere = "{$alias}.userid = :ratinguserid{$count}"; + $userwhere = "{$alias}.id IS NOT NULL"; $params = [ 'ratingcomponent' . $count => $component,