diff --git a/mod/forum/classes/privacy/provider.php b/mod/forum/classes/privacy/provider.php index 06466e67df7..a7c96873cad 100644 --- a/mod/forum/classes/privacy/provider.php +++ b/mod/forum/classes/privacy/provider.php @@ -37,6 +37,8 @@ use tool_dataprivacy\context_instance; defined('MOODLE_INTERNAL') || die(); +require_once($CFG->dirroot . '/grade/grading/lib.php'); + /** * Implementation of the privacy subsystem plugin provider for the forum activity module. * @@ -690,35 +692,44 @@ class provider implements protected static function export_all_posts(int $userid, array $mappings) { global $DB; - // Find all of the posts, and post subscriptions for this forum. - list($foruminsql, $forumparams) = $DB->get_in_or_equal(array_keys($mappings), SQL_PARAMS_NAMED); - $ratingsql = \core_rating\privacy\provider::get_sql_join('rat', 'mod_forum', 'post', 'p.id', $userid); - $sql = "SELECT - p.discussion AS id, - f.id AS forumid, - d.name, - d.groupid - FROM {forum} f - JOIN {forum_discussions} d ON d.forum = f.id - JOIN {forum_posts} p ON p.discussion = d.id - LEFT JOIN {forum_read} fr ON fr.postid = p.id AND fr.userid = :readuserid - {$ratingsql->join} - WHERE f.id ${foruminsql} AND - ( - p.userid = :postuserid OR - p.privatereplyto = :privatereplyrecipient OR - fr.id IS NOT NULL OR - {$ratingsql->userwhere} - ) - GROUP BY f.id, p.discussion, d.name, d.groupid - "; + $commonsql = "SELECT p.discussion AS id, f.id AS forumid, d.name, d.groupid + FROM {forum} f + JOIN {forum_discussions} d ON d.forum = f.id + JOIN {forum_posts} p ON p.discussion = d.id"; + + // All discussions with posts authored by the user or containing private replies to the user. + list($foruminsql1, $forumparams1) = $DB->get_in_or_equal(array_keys($mappings), SQL_PARAMS_NAMED); + $sql1 = "{$commonsql} + WHERE f.id {$foruminsql1} + AND (p.userid = :postuserid OR p.privatereplyto = :privatereplyrecipient)"; + + // All discussions with the posts marked as read by the user. + list($foruminsql2, $forumparams2) = $DB->get_in_or_equal(array_keys($mappings), SQL_PARAMS_NAMED); + $sql2 = "{$commonsql} + JOIN {forum_read} fr ON fr.postid = p.id + WHERE f.id {$foruminsql2} + AND fr.userid = :readuserid"; + + // All discussions with ratings provided by the user. + list($foruminsql3, $forumparams3) = $DB->get_in_or_equal(array_keys($mappings), SQL_PARAMS_NAMED); + $ratingsql = \core_rating\privacy\provider::get_sql_join('rat', 'mod_forum', 'post', 'p.id', $userid, true); + $sql3 = "{$commonsql} + {$ratingsql->join} + WHERE f.id {$foruminsql3} + AND {$ratingsql->userwhere}"; + + $sql = "SELECT * + FROM ({$sql1} UNION {$sql2} UNION {$sql3}) united + GROUP BY id, forumid, name, groupid"; $params = [ - 'postuserid' => $userid, - 'readuserid' => $userid, + 'postuserid' => $userid, + 'readuserid' => $userid, 'privatereplyrecipient' => $userid, ]; - $params += $forumparams; + $params += $forumparams1; + $params += $forumparams2; + $params += $forumparams3; $params += $ratingsql->params; $discussions = $DB->get_records_sql($sql, $params); diff --git a/mod/forum/db/install.xml b/mod/forum/db/install.xml index ef7545dce73..bbda97aba99 100644 --- a/mod/forum/db/install.xml +++ b/mod/forum/db/install.xml @@ -1,5 +1,5 @@ - @@ -99,6 +99,7 @@ + diff --git a/mod/forum/db/upgrade.php b/mod/forum/db/upgrade.php index 7d36e0413b4..5f709bd6bfa 100644 --- a/mod/forum/db/upgrade.php +++ b/mod/forum/db/upgrade.php @@ -246,5 +246,17 @@ function xmldb_forum_upgrade($oldversion) { // Automatically generated Moodle v3.9.0 release upgrade line. // Put any upgrade step following this. + if ($oldversion < 2020072100) { + // Add index privatereplyto (not unique) to the forum_posts table. + $table = new xmldb_table('forum_posts'); + $index = new xmldb_index('privatereplyto', XMLDB_INDEX_NOTUNIQUE, ['privatereplyto']); + + if (!$dbman->index_exists($table, $index)) { + $dbman->add_index($table, $index); + } + + upgrade_mod_savepoint(true, 2020072100, 'forum'); + } + return true; } diff --git a/mod/forum/version.php b/mod/forum/version.php index 7eddcd86571..11f48d60362 100644 --- a/mod/forum/version.php +++ b/mod/forum/version.php @@ -24,6 +24,6 @@ defined('MOODLE_INTERNAL') || die(); -$plugin->version = 2020061500; // The current module version (Date: YYYYMMDDXX) +$plugin->version = 2020072100; // The current module version (Date: YYYYMMDDXX) $plugin->requires = 2020060900; // Requires this Moodle version $plugin->component = 'mod_forum'; // Full name of the plugin (used for diagnostics)