Merge branch 'MDL-66625-master' of git://github.com/rezaies/moodle
authorJun Pataleta <jun@moodle.com>
Thu, 17 Oct 2019 22:39:01 +0000 (06:39 +0800)
committerJun Pataleta <jun@moodle.com>
Thu, 17 Oct 2019 22:39:01 +0000 (06:39 +0800)
mod/forum/report/summary/classes/summary_table.php
mod/forum/report/summary/index.php
mod/forum/report/summary/tests/behat/private_replies.feature [new file with mode: 0644]

index ca1dd93..323a519 100644 (file)
@@ -77,14 +77,20 @@ class summary_table extends table_sql {
      */
     private $showwordcharcounts = null;
 
+    /**
+     * @var bool Whether the user can see all private replies or not.
+     */
+    protected $canseeprivatereplies;
+
     /**
      * Forum report table constructor.
      *
      * @param int $courseid The ID of the course the forum(s) exist within.
      * @param array $filters Report filters in the format 'type' => [values].
      * @param bool $bulkoperations Is the user allowed to perform bulk operations?
+     * @param bool $canseeprivatereplies Whether the user can see all private replies or not.
      */
-    public function __construct(int $courseid, array $filters, bool $bulkoperations) {
+    public function __construct(int $courseid, array $filters, bool $bulkoperations, bool $canseeprivatereplies) {
         global $USER, $OUTPUT;
 
         $forumid = $filters['forums'][0];
@@ -93,6 +99,7 @@ class summary_table extends table_sql {
 
         $this->cm = get_coursemodule_from_instance('forum', $forumid, $courseid);
         $this->context = \context_module::instance($this->cm->id);
+        $this->canseeprivatereplies = $canseeprivatereplies;
 
         // Only show their own summary unless they have permission to view all.
         if (!has_capability('forumreport/summary:viewall', $this->context)) {
@@ -408,13 +415,14 @@ class summary_table extends table_sql {
      * @return void.
      */
     protected function define_base_sql(): void {
+        global $USER;
+
         $this->sql = new \stdClass();
 
         $userfields = get_extra_user_fields($this->context);
         $userfieldssql = \user_picture::fields('u', $userfields);
 
         // Define base SQL query format.
-        // Ignores private replies as they are not visible to all participants.
         $this->sql->basefields = ' ue.userid AS userid,
                                    e.courseid AS courseid,
                                    f.id as forumid,
@@ -425,6 +433,17 @@ class summary_table extends table_sql {
                                    MIN(p.created) AS earliestpost,
                                    MAX(p.created) AS latestpost';
 
+        // Handle private replies.
+        $privaterepliessql = '';
+        $privaterepliesparams = [];
+        if (!$this->canseeprivatereplies) {
+            $privaterepliessql = ' AND (p.privatereplyto = :privatereplyto
+                                        OR p.userid = :privatereplyfrom
+                                        OR p.privatereplyto = 0)';
+            $privaterepliesparams['privatereplyto'] = $USER->id;
+            $privaterepliesparams['privatereplyfrom'] = $USER->id;
+        }
+
         $this->sql->basefromjoins = '    {enrol} e
                                     JOIN {user_enrolments} ue ON ue.enrolid = e.id
                                     JOIN {user} u ON u.id = ue.userid
@@ -432,7 +451,7 @@ class summary_table extends table_sql {
                                     JOIN {forum_discussions} d ON d.forum = f.id
                                LEFT JOIN {forum_posts} p ON p.discussion =  d.id
                                      AND p.userid = ue.userid
-                                     AND p.privatereplyto = 0
+                                     ' . $privaterepliessql . '
                                LEFT JOIN (
                                             SELECT COUNT(fi.id) AS attcount, fi.itemid AS postid, fi.userid
                                               FROM {files} fi
@@ -463,7 +482,7 @@ class summary_table extends table_sql {
         $this->sql->params = [
             'component' => 'mod_forum',
             'courseid' => $this->cm->course,
-        ];
+        ] + $privaterepliesparams;
 
         // Handle if a user is limited to viewing their own summary.
         if (!empty($this->userid)) {
index 61f407b..9b8e828 100644 (file)
@@ -77,8 +77,9 @@ $PAGE->navbar->add(get_string('nodetitle', "forumreport_summary"));
 
 // Prepare and display the report.
 $bulkoperations = !$download && !empty($CFG->messaging) && has_capability('moodle/course:bulkmessaging', $context);
+$canseeprivatereplies = has_capability('mod/forum:readprivatereplies', $context);
 
-$table = new \forumreport_summary\summary_table($courseid, $filters, $bulkoperations);
+$table = new \forumreport_summary\summary_table($courseid, $filters, $bulkoperations, $canseeprivatereplies);
 $table->baseurl = $url;
 
 if ($download) {
diff --git a/mod/forum/report/summary/tests/behat/private_replies.feature b/mod/forum/report/summary/tests/behat/private_replies.feature
new file mode 100644 (file)
index 0000000..92d040d
--- /dev/null
@@ -0,0 +1,58 @@
+@mod @mod_forum @forumreport @forumreport_summary
+Feature: Include private replies in the summary report
+  In order to generate accurate reports based on what is visible
+  As a teacher
+  I should have private replies being counted as well
+
+  Background:
+    Given the following "users" exist:
+      | username | firstname | lastname | email                |
+      | teacher1 | Teacher   | 1        | teacher1@example.com |
+      | teacher2 | Teacher   | 2        | teacher2@example.com |
+      | student1 | Student   | 1        | student1@example.com |
+      | student2 | Student   | 2        | student1@example.com |
+    And the following "courses" exist:
+      | fullname | shortname |
+      | Course 1 | C1        |
+    And the following "course enrolments" exist:
+      | user     | course | role           |
+      | teacher1 | C1     | editingteacher |
+      | teacher2 | C1     | editingteacher |
+      | student1 | C1     | student        |
+      | student2 | C1     | student        |
+    And the following "activities" exist:
+      | activity | name   | description     | course | idnumber |
+      | forum    | forum1 | C1 first forum  | C1     | forum1   |
+    And the following forum discussions exist in course "Course 1":
+      | user     | forum  | name        | message         |
+      | teacher1 | forum1 | discussion1 | t1 earliest     |
+      | teacher1 | forum1 | discussion2 | t1 between      |
+      | student1 | forum1 | discussion3 | s1 latest       |
+    And the following forum replies exist in course "Course 1":
+      | user     | forum  | discussion  | subject     | message     |
+      | teacher1 | forum1 | discussion1 | t1 between  | t1 between  |
+      | teacher1 | forum1 | discussion2 | t1 latest   | t1 latest   |
+      | student1 | forum1 | discussion1 | s1 earliest | s1 earliest |
+    And I log in as "teacher1"
+    And I am on "Course 1" course homepage
+    And I reply "s1 earliest" post from "discussion1" forum with:
+      | Message         | This is a private reply |
+      | Reply privately | 1                       |
+    And I log out
+
+  Scenario: Private replies are counted for Teacher
+    When I log in as "teacher2"
+    And I am on "Course 1" course homepage
+    And I follow "forum1"
+    And I navigate to "Summary report" in current page administration
+    Then "Teacher 1" row "Number of replies posted" column of "forumreport_summary_table" table should contain "3"
+
+  Scenario: Private replies are not counted when Teacher has not capability
+    Given the following "permission overrides" exist:
+      | capability                   | permission | role           | contextlevel | reference |
+      | mod/forum:readprivatereplies | Prevent    | editingteacher | Course       | C1        |
+    When I log in as "teacher2"
+    And I am on "Course 1" course homepage
+    And I follow "forum1"
+    And I navigate to "Summary report" in current page administration
+    Then "Teacher 1" row "Number of replies posted" column of "forumreport_summary_table" table should contain "2"