From 3261e9237deead83d60e66fca02a108c7117d6fe Mon Sep 17 00:00:00 2001 From: sam marshall Date: Wed, 20 Sep 2017 14:48:46 +0100 Subject: [PATCH] MDL-58885 core_search: Group support in relevant module search areas --- mod/data/classes/search/entry.php | 14 +++- mod/data/tests/search_test.php | 71 +++++++++++++++++++ mod/forum/classes/search/post.php | 16 ++++- mod/forum/tests/search_test.php | 69 ++++++++++++++++++ .../classes/search/collaborative_page.php | 14 +++- mod/wiki/tests/search_test.php | 54 ++++++++++++++ 6 files changed, 234 insertions(+), 4 deletions(-) diff --git a/mod/data/classes/search/entry.php b/mod/data/classes/search/entry.php index e2a25807454..b1a6fd9fd61 100644 --- a/mod/data/classes/search/entry.php +++ b/mod/data/classes/search/entry.php @@ -76,8 +76,6 @@ class entry extends \core_search\base_mod { * @return \core_search\document */ public function get_document($entry, $options = array()) { - global $DB; - try { $cm = $this->get_cm('data', $entry->dataid, $entry->course); $context = \context_module::instance($cm->id); @@ -97,6 +95,9 @@ class entry extends \core_search\base_mod { $doc->set('contextid', $context->id); $doc->set('courseid', $entry->course); $doc->set('userid', $entry->userid); + if ($entry->groupid > 0) { + $doc->set('groupid', $entry->groupid); + } $doc->set('owneruserid', \core_search\manager::NO_OWNER_ID); $doc->set('modified', $entry->timemodified); @@ -353,4 +354,13 @@ class entry extends \core_search\base_mod { require_once($CFG->dirroot . '/mod/data/field/' . $fieldtype . '/field.class.php'); return 'data_field_' . $fieldtype; } + + /** + * Confirms that data entries support group restrictions. + * + * @return bool True + */ + public function supports_group_restriction() { + return true; + } } diff --git a/mod/data/tests/search_test.php b/mod/data/tests/search_test.php index 78d1c6c0103..8988ea67074 100644 --- a/mod/data/tests/search_test.php +++ b/mod/data/tests/search_test.php @@ -575,6 +575,77 @@ class mod_data_search_test extends advanced_testcase { } + /** + * Group support for data entries. + */ + public function test_data_entries_group_support() { + global $DB; + + // Get the search area and test generators. + $searcharea = \core_search\manager::get_search_area($this->databaseentryareaid); + $generator = $this->getDataGenerator(); + $datagenerator = $generator->get_plugin_generator('mod_data'); + + // Create a course, a user, and two groups. + $course = $generator->create_course(); + $user = $generator->create_user(); + $generator->enrol_user($user->id, $course->id, 'teacher'); + $group1 = $generator->create_group(['courseid' => $course->id]); + $group2 = $generator->create_group(['courseid' => $course->id]); + + // Separate groups database. + $data = self::getDataGenerator()->create_module('data', ['course' => $course->id, + 'groupmode' => SEPARATEGROUPS]); + $fieldtypes = ['text', 'textarea']; + $this->create_default_data_fields($fieldtypes, $data); + $fields = $DB->get_records('data_fields', array('dataid' => $data->id)); + foreach ($fields as $field) { + switch ($field->type) { + case 'text' : + $textid = $field->id; + break; + case 'textarea' : + $textareaid = $field->id; + break; + } + } + + // As admin, create entries with each group and all groups. + $this->setAdminUser(); + $fieldvalues = [$textid => 'Title', $textareaid => 'Content']; + $e1 = $datagenerator->create_entry($data, $fieldvalues, $group1->id); + $e2 = $datagenerator->create_entry($data, $fieldvalues, $group2->id); + $e3 = $datagenerator->create_entry($data, $fieldvalues); + + // Do the indexing of all 3 entries. + $rs = $searcharea->get_recordset_by_timestamp(0); + $results = []; + foreach ($rs as $rec) { + $results[$rec->id] = $rec; + } + $rs->close(); + $this->assertCount(3, $results); + + // Check each has the correct groupid. + $doc = $searcharea->get_document($results[$e1]); + $this->assertTrue($doc->is_set('groupid')); + $this->assertEquals($group1->id, $doc->get('groupid')); + $doc = $searcharea->get_document($results[$e2]); + $this->assertTrue($doc->is_set('groupid')); + $this->assertEquals($group2->id, $doc->get('groupid')); + $doc = $searcharea->get_document($results[$e3]); + $this->assertFalse($doc->is_set('groupid')); + + // While we're here, also test that the search area requests restriction by group. + $modinfo = get_fast_modinfo($course); + $this->assertTrue($searcharea->restrict_cm_access_by_group($modinfo->get_cm($data->cmid))); + + // In visible groups mode, it won't request restriction by group. + set_coursemodule_groupmode($data->cmid, VISIBLEGROUPS); + $modinfo = get_fast_modinfo($course); + $this->assertFalse($searcharea->restrict_cm_access_by_group($modinfo->get_cm($data->cmid))); + } + /** * Document accesses. * diff --git a/mod/forum/classes/search/post.php b/mod/forum/classes/search/post.php index 9f5d68e499a..e83ddb96e60 100644 --- a/mod/forum/classes/search/post.php +++ b/mod/forum/classes/search/post.php @@ -68,7 +68,7 @@ class post extends \core_search\base_mod { return null; } - $sql = "SELECT fp.*, f.id AS forumid, f.course AS courseid + $sql = "SELECT fp.*, f.id AS forumid, f.course AS courseid, fd.groupid AS groupid FROM {forum_posts} fp JOIN {forum_discussions} fd ON fd.id = fp.discussion JOIN {forum} f ON f.id = fd.forum @@ -110,6 +110,11 @@ class post extends \core_search\base_mod { $doc->set('owneruserid', \core_search\manager::NO_OWNER_ID); $doc->set('modified', $record->modified); + // Store group id if there is one. (0 and -1 both mean not restricted to group.) + if ($record->groupid > 0) { + $doc->set('groupid', $record->groupid); + } + // Check if this document should be considered new. if (isset($options['lastindexedtime']) && ($options['lastindexedtime'] < $record->created)) { // If the document was created after the last index time, it must be new. @@ -305,4 +310,13 @@ class post extends \core_search\base_mod { 'MAX(fd.timemodified) DESC' ]; } + + /** + * Confirms that data entries support group restrictions. + * + * @return bool True + */ + public function supports_group_restriction() { + return true; + } } diff --git a/mod/forum/tests/search_test.php b/mod/forum/tests/search_test.php index d2cd42368c1..93095aab95e 100644 --- a/mod/forum/tests/search_test.php +++ b/mod/forum/tests/search_test.php @@ -196,6 +196,7 @@ class mod_forum_search_testcase extends advanced_testcase { $record->userid = $user->id; $record->forum = $forum1->id; $record->message = 'discussion'; + $record->groupid = 0; $discussion1 = self::getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record); // Create post1 in discussion1. @@ -205,11 +206,13 @@ class mod_forum_search_testcase extends advanced_testcase { $record->userid = $user->id; $record->subject = 'subject1'; $record->message = 'post1'; + $record->groupid = -1; $discussion1reply1 = self::getDataGenerator()->get_plugin_generator('mod_forum')->create_post($record); $post1 = $DB->get_record('forum_posts', array('id' => $discussion1reply1->id)); $post1->forumid = $forum1->id; $post1->courseid = $forum1->course; + $post1->groupid = -1; $doc = $searcharea->get_document($post1); $this->assertInstanceOf('\core_search\document', $doc); @@ -221,6 +224,72 @@ class mod_forum_search_testcase extends advanced_testcase { $this->assertEquals($discussion1reply1->message, $doc->get('content')); } + /** + * Group support for forum posts. + */ + public function test_posts_group_support() { + // Get the search area and test generators. + $searcharea = \core_search\manager::get_search_area($this->forumpostareaid); + $generator = $this->getDataGenerator(); + $forumgenerator = $generator->get_plugin_generator('mod_forum'); + + // Create a course, a user, and two groups. + $course = $generator->create_course(); + $user = $generator->create_user(); + $generator->enrol_user($user->id, $course->id, 'teacher'); + $group1 = $generator->create_group(['courseid' => $course->id]); + $group2 = $generator->create_group(['courseid' => $course->id]); + + // Separate groups forum. + $forum = self::getDataGenerator()->create_module('forum', ['course' => $course->id, + 'groupmode' => SEPARATEGROUPS]); + + // Create discussion with each group and one for all groups. One has a post in. + $discussion1 = $forumgenerator->create_discussion(['course' => $course->id, + 'userid' => $user->id, 'forum' => $forum->id, 'message' => 'd1', + 'groupid' => $group1->id]); + $forumgenerator->create_discussion(['course' => $course->id, + 'userid' => $user->id, 'forum' => $forum->id, 'message' => 'd2', + 'groupid' => $group2->id]); + $forumgenerator->create_discussion(['course' => $course->id, + 'userid' => $user->id, 'forum' => $forum->id, 'message' => 'd3']); + + // Create a reply in discussion1. + $forumgenerator->create_post(['discussion' => $discussion1->id, 'parent' => $discussion1->firstpost, + 'userid' => $user->id, 'message' => 'p1']); + + // Do the indexing of all 4 posts. + $rs = $searcharea->get_recordset_by_timestamp(0); + $results = []; + foreach ($rs as $rec) { + $results[$rec->message] = $rec; + } + $rs->close(); + $this->assertCount(4, $results); + + // Check each document has the correct groupid. + $doc = $searcharea->get_document($results['d1']); + $this->assertTrue($doc->is_set('groupid')); + $this->assertEquals($group1->id, $doc->get('groupid')); + $doc = $searcharea->get_document($results['d2']); + $this->assertTrue($doc->is_set('groupid')); + $this->assertEquals($group2->id, $doc->get('groupid')); + $doc = $searcharea->get_document($results['d3']); + $this->assertFalse($doc->is_set('groupid')); + $doc = $searcharea->get_document($results['p1']); + $this->assertTrue($doc->is_set('groupid')); + $this->assertEquals($group1->id, $doc->get('groupid')); + + // While we're here, also test that the search area requests restriction by group. + $modinfo = get_fast_modinfo($course); + $this->assertTrue($searcharea->restrict_cm_access_by_group($modinfo->get_cm($forum->cmid))); + + // In visible groups mode, it won't request restriction by group. + set_coursemodule_groupmode($forum->cmid, VISIBLEGROUPS); + $modinfo = get_fast_modinfo($course); + $this->assertFalse($searcharea->restrict_cm_access_by_group($modinfo->get_cm($forum->cmid))); + } + /** * Document accesses. * diff --git a/mod/wiki/classes/search/collaborative_page.php b/mod/wiki/classes/search/collaborative_page.php index 11220d2e3e1..81ca22955af 100644 --- a/mod/wiki/classes/search/collaborative_page.php +++ b/mod/wiki/classes/search/collaborative_page.php @@ -57,7 +57,7 @@ class collaborative_page extends \core_search\base_mod { return null; } - $sql = "SELECT p.*, w.id AS wikiid, w.course AS courseid + $sql = "SELECT p.*, w.id AS wikiid, w.course AS courseid, s.groupid AS groupid FROM {wiki_pages} p JOIN {wiki_subwikis} s ON s.id = p.subwikiid JOIN {wiki} w ON w.id = s.wikiid @@ -111,6 +111,9 @@ class collaborative_page extends \core_search\base_mod { $doc->set('content', $content); $doc->set('contextid', $context->id); $doc->set('courseid', $record->courseid); + if ($record->groupid > 0) { + $doc->set('groupid', $record->groupid); + } $doc->set('owneruserid', \core_search\manager::NO_OWNER_ID); $doc->set('modified', $record->timemodified); @@ -205,4 +208,13 @@ class collaborative_page extends \core_search\base_mod { return $fileareas; } + + /** + * Confirms that data entries support group restrictions. + * + * @return bool True + */ + public function supports_group_restriction() { + return true; + } } diff --git a/mod/wiki/tests/search_test.php b/mod/wiki/tests/search_test.php index 3daa8043ee9..9c3f9078fc6 100644 --- a/mod/wiki/tests/search_test.php +++ b/mod/wiki/tests/search_test.php @@ -143,6 +143,60 @@ class mod_wiki_search_testcase extends advanced_testcase { $rs->close(); } + /** + * Group support for wiki entries. + */ + public function test_collaborative_page_group_support() { + // Get the search area and test generators. + $searcharea = \core_search\manager::get_search_area($this->wikicollabpageareaid); + $generator = $this->getDataGenerator(); + $wikigenerator = $generator->get_plugin_generator('mod_wiki'); + + // Create a course, a user, and two groups. + $course = $generator->create_course(); + $user = $generator->create_user(); + $generator->enrol_user($user->id, $course->id, 'teacher'); + $group1 = $generator->create_group(['courseid' => $course->id]); + $group2 = $generator->create_group(['courseid' => $course->id]); + + // Separate groups wiki. + $wiki = self::getDataGenerator()->create_module('wiki', ['course' => $course->id, + 'groupmode' => SEPARATEGROUPS]); + + // Create page with each group and one for all groups. + $wikigenerator->create_page($wiki, ['title' => 'G1', 'group' => $group1->id]); + $wikigenerator->create_page($wiki, ['title' => 'G2', 'group' => $group2->id]); + $wikigenerator->create_page($wiki, ['title' => 'ALLGROUPS']); + + // Do the indexing of all 3 pages. + $rs = $searcharea->get_recordset_by_timestamp(0); + $results = []; + foreach ($rs as $rec) { + $results[$rec->title] = $rec; + } + $rs->close(); + $this->assertCount(3, $results); + + // Check each document has the correct groupid. + $doc = $searcharea->get_document($results['G1']); + $this->assertTrue($doc->is_set('groupid')); + $this->assertEquals($group1->id, $doc->get('groupid')); + $doc = $searcharea->get_document($results['G2']); + $this->assertTrue($doc->is_set('groupid')); + $this->assertEquals($group2->id, $doc->get('groupid')); + $doc = $searcharea->get_document($results['ALLGROUPS']); + $this->assertFalse($doc->is_set('groupid')); + + // While we're here, also test that the search area requests restriction by group. + $modinfo = get_fast_modinfo($course); + $this->assertTrue($searcharea->restrict_cm_access_by_group($modinfo->get_cm($wiki->cmid))); + + // In visible groups mode, it won't request restriction by group. + set_coursemodule_groupmode($wiki->cmid, VISIBLEGROUPS); + $modinfo = get_fast_modinfo($course); + $this->assertFalse($searcharea->restrict_cm_access_by_group($modinfo->get_cm($wiki->cmid))); + } + /** * Check collaborative_page check access. *