diff --git a/mod/forum/classes/form/export_form.php b/mod/forum/classes/form/export_form.php index 905e5e63e39..ecff1facb2e 100644 --- a/mod/forum/classes/form/export_form.php +++ b/mod/forum/classes/form/export_form.php @@ -69,6 +69,12 @@ class export_form extends \moodleform { ]; $mform->addElement('autocomplete', 'discussionids', get_string('discussions', 'mod_forum'), $discussions, $options); + // Date fields. + $mform->addElement('date_time_selector', 'from', get_string('postsfrom', 'mod_forum'), + ['optional' => true]); + $mform->addElement('date_time_selector', 'to', get_string('poststo', 'mod_forum'), + ['optional' => true]); + // Export formats. $formats = \core_plugin_manager::instance()->get_plugins_of_type('dataformat'); $options = []; diff --git a/mod/forum/classes/local/vaults/post.php b/mod/forum/classes/local/vaults/post.php index daf5e7fb3d4..88d3663245d 100644 --- a/mod/forum/classes/local/vaults/post.php +++ b/mod/forum/classes/local/vaults/post.php @@ -157,39 +157,70 @@ class post extends db_table_vault { } /** - * The method returns posts made by the supplied users in the supplied discussions. + * The method returns posts based on a set of filters. * * @param stdClass $user Only used when restricting private replies - * @param int[] $discussionids The list of discussion ids to load posts for - * @param int[] $userids Only return posts made by these users + * @param array $filters Export filters, valid filters are: + * + * 'discussionids' => array of discussion ids eg [1,2,3] + * 'userids' => array of user ids eg [1,2,3] + * 'from' => timestamp to filter posts from this date. + * 'to' => timestamp to filter posts till this date. + * * @param bool $canseeprivatereplies Whether this user can see all private replies or not * @param string $orderby Order the results * @return post_entity[] */ - public function get_from_discussion_ids_and_user_ids( + public function get_from_filters( stdClass $user, - array $discussionids, - array $userids, + array $filters, bool $canseeprivatereplies, string $orderby = '' ): array { - if (empty($discussionids) || empty($userids)) { + if (count($filters) == 0) { return []; } - + $wheresql = []; + $params = []; $alias = $this->get_table_alias(); - list($indiscussionssql, $indiscussionsparams) = $this->get_db()->get_in_or_equal($discussionids, SQL_PARAMS_NAMED); - list($inuserssql, $inusersparams) = $this->get_db()->get_in_or_equal($userids, SQL_PARAMS_NAMED); + // Filter by discussion ids. + if (!empty($filters['discussionids'])) { + list($indiscussionssql, $indiscussionsparams) = $this->get_db()->get_in_or_equal($filters['discussionids'], + SQL_PARAMS_NAMED); + $wheresql[] = "{$alias}.discussion {$indiscussionssql}"; + $params += $indiscussionsparams; + } + // Filter by user ids. + if (!empty($filters['userids'])) { + list($inuserssql, $inusersparams) = $this->get_db()->get_in_or_equal($filters['userids'], + SQL_PARAMS_NAMED); + $wheresql[] = "{$alias}.userid {$inuserssql}"; + $params += $inusersparams; + } + + // Filter posts by from and to dates. + if (isset($filters['from'])) { + $wheresql[] = "{$alias}.created >= :from"; + $params['from'] = $filters['from']; + } + + if (isset($filters['to'])) { + $wheresql[] = "{$alias}.created < :to"; + $params['to'] = $filters['to']; + } + + // We need to build the WHERE here, because get_private_reply_sql returns the query with the AND clause. + $wheresql = implode(' AND ', $wheresql); + + // Build private replies sql. [ 'where' => $privatewhere, 'params' => $privateparams, ] = $this->get_private_reply_sql($user, $canseeprivatereplies); - - $wheresql = "{$alias}.discussion {$indiscussionssql} - AND {$alias}.userid {$inuserssql} - {$privatewhere}"; + $wheresql .= "{$privatewhere}"; + $params += $privateparams; if ($orderby) { $orderbysql = $alias . '.' . $orderby; @@ -198,7 +229,7 @@ class post extends db_table_vault { } $sql = $this->generate_get_records_sql($wheresql, $orderbysql); - $records = $this->get_db()->get_records_sql($sql, array_merge($indiscussionsparams, $inusersparams, $privateparams)); + $records = $this->get_db()->get_records_sql($sql, $params); return $this->transform_db_records_to_entities($records); } diff --git a/mod/forum/export.php b/mod/forum/export.php index 419997754a6..e268e586f18 100644 --- a/mod/forum/export.php +++ b/mod/forum/export.php @@ -78,16 +78,19 @@ if ($form->is_cancelled()) { }, $discussions); } + $filters = ['discussionids' => $discussionids]; if ($data->userids) { - $posts = $postvault->get_from_discussion_ids_and_user_ids($USER, - $discussionids, - $data->userids, - $capabilitymanager->can_view_any_private_reply($USER)); - } else { - $posts = $postvault->get_from_discussion_ids($USER, - $discussionids, - $capabilitymanager->can_view_any_private_reply($USER)); + $filters['userids'] = $data->userids; } + if ($data->from) { + $filters['from'] = $data->from; + } + if ($data->to) { + $filters['to'] = $data->to; + } + + // Retrieve posts based on the selected filters. + $posts = $postvault->get_from_filters($USER, $filters, $capabilitymanager->can_view_any_private_reply($USER)); $fields = ['id', 'discussion', 'parent', 'userid', 'created', 'modified', 'mailed', 'subject', 'message', 'messageformat', 'messagetrust', 'attachment', 'totalscore', 'mailnow', 'deleted', 'privatereplyto']; diff --git a/mod/forum/lang/en/forum.php b/mod/forum/lang/en/forum.php index da3424c2451..8fa58b0eefc 100644 --- a/mod/forum/lang/en/forum.php +++ b/mod/forum/lang/en/forum.php @@ -495,8 +495,10 @@ $string['postrating1'] = 'Mostly separate knowing'; $string['postrating2'] = 'Separate and connected'; $string['postrating3'] = 'Mostly connected knowing'; $string['posts'] = 'Posts'; +$string['postsfrom'] = 'Posts from'; $string['postsmadebyuser'] = 'Posts made by {$a}'; $string['postsmadebyuserincourse'] = 'Posts made by {$a->fullname} in {$a->coursename}'; +$string['poststo'] = 'Posts to'; $string['posttoforum'] = 'Post to forum'; $string['postupdated'] = 'Your post was updated'; $string['potentialsubscribers'] = 'Potential subscribers';