Skip to content

Commit

Permalink
MDL-64652 mod_forum: Performance improvement for provider
Browse files Browse the repository at this point in the history
There are possibly some further improvements that can be made to:
- export_discussion_data
- export_all_posts
  • Loading branch information
andrewnicols committed Mar 5, 2019
1 parent 89d1238 commit ab45aa7
Showing 1 changed file with 161 additions and 55 deletions.
216 changes: 161 additions & 55 deletions mod/forum/classes/privacy/provider.php
Original file line number Diff line number Diff line change
Expand Up @@ -152,46 +152,105 @@ public static function get_metadata(collection $items) : collection {
* @return contextlist $contextlist The contextlist containing the list of contexts used in this plugin.
*/
public static function get_contexts_for_userid(int $userid) : \core_privacy\local\request\contextlist {
$contextlist = new \core_privacy\local\request\contextlist();

$params = [
'modname' => 'forum',
'contextlevel' => CONTEXT_MODULE,
'userid' => $userid,
];

// Discussion creators.
$sql = "SELECT c.id
FROM {context} c
JOIN {course_modules} cm ON cm.id = c.instanceid AND c.contextlevel = :contextlevel
JOIN {modules} m ON m.id = cm.module AND m.name = :modname
JOIN {forum} f ON f.id = cm.instance
JOIN {forum_discussions} d ON d.forum = f.id
WHERE d.userid = :userid
";
$contextlist->add_from_sql($sql, $params);

// Post authors.
$sql = "SELECT c.id
FROM {context} c
JOIN {course_modules} cm ON cm.id = c.instanceid AND c.contextlevel = :contextlevel
JOIN {modules} m ON m.id = cm.module AND m.name = :modname
JOIN {forum} f ON f.id = cm.instance
JOIN {forum_discussions} d ON d.forum = f.id
JOIN {forum_posts} p ON p.discussion = d.id
WHERE p.userid = :userid
";
$contextlist->add_from_sql($sql, $params);

// Forum digest records.
$sql = "SELECT c.id
FROM {context} c
JOIN {course_modules} cm ON cm.id = c.instanceid AND c.contextlevel = :contextlevel
JOIN {modules} m ON m.id = cm.module AND m.name = :modname
JOIN {forum} f ON f.id = cm.instance
JOIN {forum_digests} dig ON dig.forum = f.id
WHERE dig.userid = :userid
";
$contextlist->add_from_sql($sql, $params);

// Forum subscriptions.
$sql = "SELECT c.id
FROM {context} c
JOIN {course_modules} cm ON cm.id = c.instanceid AND c.contextlevel = :contextlevel
JOIN {modules} m ON m.id = cm.module AND m.name = :modname
JOIN {forum} f ON f.id = cm.instance
JOIN {forum_subscriptions} sub ON sub.forum = f.id
WHERE sub.userid = :userid
";
$contextlist->add_from_sql($sql, $params);

// Discussion subscriptions.
$sql = "SELECT c.id
FROM {context} c
JOIN {course_modules} cm ON cm.id = c.instanceid AND c.contextlevel = :contextlevel
JOIN {modules} m ON m.id = cm.module AND m.name = :modname
JOIN {forum} f ON f.id = cm.instance
JOIN {forum_discussion_subs} dsub ON dsub.forum = f.id
WHERE dsub.userid = :userid
";
$contextlist->add_from_sql($sql, $params);

// Discussion tracking preferences.
$sql = "SELECT c.id
FROM {context} c
JOIN {course_modules} cm ON cm.id = c.instanceid AND c.contextlevel = :contextlevel
JOIN {modules} m ON m.id = cm.module AND m.name = :modname
JOIN {forum} f ON f.id = cm.instance
JOIN {forum_track_prefs} pref ON pref.forumid = f.id
WHERE pref.userid = :userid
";
$contextlist->add_from_sql($sql, $params);

// Discussion read records.
$sql = "SELECT c.id
FROM {context} c
JOIN {course_modules} cm ON cm.id = c.instanceid AND c.contextlevel = :contextlevel
JOIN {modules} m ON m.id = cm.module AND m.name = :modname
JOIN {forum} f ON f.id = cm.instance
JOIN {forum_read} hasread ON hasread.forumid = f.id
WHERE hasread.userid = :userid
";
$contextlist->add_from_sql($sql, $params);

// Rating authors.
$ratingsql = \core_rating\privacy\provider::get_sql_join('rat', 'mod_forum', 'post', 'p.id', $userid);
// Fetch all forum discussions, and forum posts.
$sql = "SELECT c.id
FROM {context} c
JOIN {course_modules} cm ON cm.id = c.instanceid AND c.contextlevel = :contextlevel
JOIN {modules} m ON m.id = cm.module AND m.name = :modname
JOIN {forum} f ON f.id = cm.instance
LEFT JOIN {forum_discussions} d ON d.forum = f.id
LEFT JOIN {forum_posts} p ON p.discussion = d.id
LEFT JOIN {forum_digests} dig ON dig.forum = f.id AND dig.userid = :digestuserid
LEFT JOIN {forum_subscriptions} sub ON sub.forum = f.id AND sub.userid = :subuserid
LEFT JOIN {forum_track_prefs} pref ON pref.forumid = f.id AND pref.userid = :prefuserid
LEFT JOIN {forum_read} hasread ON hasread.forumid = f.id AND hasread.userid = :hasreaduserid
LEFT JOIN {forum_discussion_subs} dsub ON dsub.forum = f.id AND dsub.userid = :dsubuserid
{$ratingsql->join}
WHERE (
p.userid = :postuserid OR
d.userid = :discussionuserid OR
dig.id IS NOT NULL OR
sub.id IS NOT NULL OR
pref.id IS NOT NULL OR
hasread.id IS NOT NULL OR
dsub.id IS NOT NULL OR
{$ratingsql->userwhere}
)
JOIN {forum_discussions} d ON d.forum = f.id
JOIN {forum_posts} p ON p.discussion = d.id
{$ratingsql->join}
WHERE {$ratingsql->userwhere}
";
$params = [
'modname' => 'forum',
'contextlevel' => CONTEXT_MODULE,
'postuserid' => $userid,
'discussionuserid' => $userid,
'digestuserid' => $userid,
'subuserid' => $userid,
'prefuserid' => $userid,
'hasreaduserid' => $userid,
'dsubuserid' => $userid,
];
$params += $ratingsql->params;

$contextlist = new \core_privacy\local\request\contextlist();
$contextlist->add_from_sql($sql, $params);

return $contextlist;
Expand Down Expand Up @@ -365,30 +424,68 @@ public static function export_user_data(approved_contextlist $contextlist) {
$userid = $user->id;

list($contextsql, $contextparams) = $DB->get_in_or_equal($contextlist->get_contextids(), SQL_PARAMS_NAMED);
$params = $contextparams;

// Digested forums.
$sql = "SELECT
c.id AS contextid,
dig.maildigest AS maildigest
FROM {context} c
JOIN {course_modules} cm ON cm.id = c.instanceid
JOIN {forum} f ON f.id = cm.instance
JOIN {forum_digests} dig ON dig.forum = f.id
WHERE (
dig.userid = :userid AND
c.id {$contextsql}
)
";
$params['userid'] = $userid;
$digests = $DB->get_records_sql_menu($sql, $params);

// Forum subscriptions.
$sql = "SELECT
c.id AS contextid,
sub.userid AS subscribed
FROM {context} c
JOIN {course_modules} cm ON cm.id = c.instanceid
JOIN {forum} f ON f.id = cm.instance
JOIN {forum_subscriptions} sub ON sub.forum = f.id
WHERE (
sub.userid = :userid AND
c.id {$contextsql}
)
";
$params['userid'] = $userid;
$subscriptions = $DB->get_records_sql_menu($sql, $params);

// Tracked forums.
$sql = "SELECT
c.id AS contextid,
f.*,
cm.id AS cmid,
dig.maildigest,
sub.userid AS subscribed,
pref.userid AS tracked
FROM {context} c
JOIN {course_modules} cm ON cm.id = c.instanceid
JOIN {forum} f ON f.id = cm.instance
LEFT JOIN {forum_digests} dig ON dig.forum = f.id AND dig.userid = :digestuserid
LEFT JOIN {forum_subscriptions} sub ON sub.forum = f.id AND sub.userid = :subuserid
LEFT JOIN {forum_track_prefs} pref ON pref.forumid = f.id AND pref.userid = :prefuserid
JOIN {forum_track_prefs} pref ON pref.forumid = f.id
WHERE (
pref.userid = :userid AND
c.id {$contextsql}
)
";
$params['userid'] = $userid;
$tracked = $DB->get_records_sql_menu($sql, $params);

$sql = "SELECT
c.id AS contextid,
f.*,
cm.id AS cmid
FROM {context} c
JOIN {course_modules} cm ON cm.id = c.instanceid
JOIN {forum} f ON f.id = cm.instance
WHERE (
c.id {$contextsql}
)
";

$params = [
'digestuserid' => $userid,
'subuserid' => $userid,
'prefuserid' => $userid,
];
$params += $contextparams;

// Keep a mapping of forumid to contextid.
Expand All @@ -407,9 +504,15 @@ public static function export_user_data(approved_contextlist $contextlist) {
request_helper::export_context_files($context, $user);

// Store relevant metadata about this forum instance.
static::export_digest_data($userid, $forum);
static::export_subscription_data($userid, $forum);
static::export_tracking_data($userid, $forum);
if (isset($digests[$forum->contextid])) {
static::export_digest_data($userid, $forum, $digests[$forum->contextid]);
}
if (isset($subscriptions[$forum->contextid])) {
static::export_subscription_data($userid, $forum, $subscriptions[$forum->contextid]);
}
if (isset($tracked[$forum->contextid])) {
static::export_tracking_data($userid, $forum, $tracked[$forum->contextid]);
}
}
$forums->close();

Expand Down Expand Up @@ -704,16 +807,17 @@ protected static function export_post_data(int $userid, \context $context, $post
*
* @param int $userid The userid of the user whose data is to be exported.
* @param \stdClass $forum The forum whose data is being exported.
* @param int $maildigest The mail digest setting for this forum.
* @return bool Whether any data was stored.
*/
protected static function export_digest_data(int $userid, \stdClass $forum) {
if (null !== $forum->maildigest) {
protected static function export_digest_data(int $userid, \stdClass $forum, int $maildigest) {
if (null !== $maildigest) {
// The user has a specific maildigest preference for this forum.
$a = (object) [
'forum' => format_string($forum->name, true),
];

switch ($forum->maildigest) {
switch ($maildigest) {
case 0:
$a->type = get_string('emaildigestoffshort', 'mod_forum');
break;
Expand All @@ -726,7 +830,7 @@ protected static function export_digest_data(int $userid, \stdClass $forum) {
}

writer::with_context(\context_module::instance($forum->cmid))
->export_metadata([], 'digestpreference', $forum->maildigest,
->export_metadata([], 'digestpreference', $maildigest,
get_string('privacy:digesttypepreference', 'mod_forum', $a));

return true;
Expand All @@ -740,10 +844,11 @@ protected static function export_digest_data(int $userid, \stdClass $forum) {
*
* @param int $userid The userid of the user whose data is to be exported.
* @param \stdClass $forum The forum whose data is being exported.
* @param int $subscribed if the user is subscribed
* @return bool Whether any data was stored.
*/
protected static function export_subscription_data(int $userid, \stdClass $forum) {
if (null !== $forum->subscribed) {
protected static function export_subscription_data(int $userid, \stdClass $forum, int $subscribed) {
if (null !== $subscribed) {
// The user is subscribed to this forum.
writer::with_context(\context_module::instance($forum->cmid))
->export_metadata([], 'subscriptionpreference', 1, get_string('privacy:subscribedtoforum', 'mod_forum'));
Expand Down Expand Up @@ -798,10 +903,11 @@ protected static function export_discussion_subscription_data(int $userid, \cont
*
* @param int $userid The userid of the user whose data is to be exported.
* @param \stdClass $forum The forum whose data is being exported.
* @param int $tracke if the user is subscribed
* @return bool Whether any data was stored.
*/
protected static function export_tracking_data(int $userid, \stdClass $forum) {
if (null !== $forum->tracked) {
protected static function export_tracking_data(int $userid, \stdClass $forum, int $tracked) {
if (null !== $tracked) {
// The user has a main preference to track all forums, but has opted out of this one.
writer::with_context(\context_module::instance($forum->cmid))
->export_metadata([], 'trackreadpreference', 0, get_string('privacy:readtrackingdisabled', 'mod_forum'));
Expand Down

0 comments on commit ab45aa7

Please sign in to comment.