array(
'itemtype' => 'wiki_pages',
'component' => 'mod_wiki',
+ 'callback' => 'mod_wiki_get_tagged_pages',
+ 'callbackfile' => '/mod/wiki/locallib.php',
),
);
return $subwiki;
}
+
+/**
+ * Returns wiki pages tagged with a specified tag.
+ *
+ * This is a callback used by the tag area mod_wiki/wiki_pages to search for wiki pages
+ * tagged with a specific tag.
+ *
+ * @param core_tag_tag $tag
+ * @param bool $exclusivemode if set to true it means that no other entities tagged with this tag
+ * are displayed on the page and the per-page limit may be bigger
+ * @param int $fromctx context id where the link was displayed, may be used by callbacks
+ * to display items in the same context first
+ * @param int $ctx context id where to search for records
+ * @param bool $rec search in subcontexts as well
+ * @param int $page 0-based number of page being displayed
+ * @return \core_tag\output\tagindex
+ */
+function mod_wiki_get_tagged_pages($tag, $exclusivemode = false, $fromctx = 0, $ctx = 0, $rec = 1, $page = 0) {
+ global $OUTPUT;
+ $perpage = $exclusivemode ? 20 : 5;
+
+ // Build the SQL query.
+ $ctxselect = context_helper::get_preload_record_columns_sql('ctx');
+ $query = "SELECT wp.id, wp.title, ws.userid, ws.wikiid, ws.id AS subwikiid, ws.groupid, w.wikimode,
+ cm.id AS cmid, c.id AS courseid, c.shortname, c.fullname, $ctxselect
+ FROM {wiki_pages} wp
+ JOIN {wiki_subwikis} ws ON wp.subwikiid = ws.id
+ JOIN {wiki} w ON w.id = ws.wikiid
+ JOIN {modules} m ON m.name='wiki'
+ JOIN {course_modules} cm ON cm.module = m.id AND cm.instance = w.id
+ JOIN {tag_instance} tt ON wp.id = tt.itemid
+ JOIN {course} c ON cm.course = c.id
+ JOIN {context} ctx ON ctx.instanceid = cm.id AND ctx.contextlevel = :coursemodulecontextlevel
+ WHERE tt.itemtype = :itemtype AND tt.tagid = :tagid AND tt.component = :component
+ AND wp.id %ITEMFILTER% AND c.id %COURSEFILTER%";
+
+ $params = array('itemtype' => 'wiki_pages', 'tagid' => $tag->id, 'component' => 'mod_wiki',
+ 'coursemodulecontextlevel' => CONTEXT_MODULE);
+
+ if ($ctx) {
+ $context = $ctx ? context::instance_by_id($ctx) : context_system::instance();
+ $query .= $rec ? ' AND (ctx.id = :contextid OR ctx.path LIKE :path)' : ' AND ctx.id = :contextid';
+ $params['contextid'] = $context->id;
+ $params['path'] = $context->path.'/%';
+ }
+
+ $query .= " ORDER BY ";
+ if ($fromctx) {
+ // In order-clause specify that modules from inside "fromctx" context should be returned first.
+ $fromcontext = context::instance_by_id($fromctx);
+ $query .= ' (CASE WHEN ctx.id = :fromcontextid OR ctx.path LIKE :frompath THEN 0 ELSE 1 END),';
+ $params['fromcontextid'] = $fromcontext->id;
+ $params['frompath'] = $fromcontext->path.'/%';
+ }
+ $query .= ' c.sortorder, cm.id, wp.id';
+
+ $totalpages = $page + 1;
+
+ // Use core_tag_index_builder to build and filter the list of items.
+ $builder = new core_tag_index_builder('mod_wiki', 'wiki_pages', $query, $params, $page * $perpage, $perpage + 1);
+ while ($item = $builder->has_item_that_needs_access_check()) {
+ context_helper::preload_from_record($item);
+ $courseid = $item->courseid;
+ if (!$builder->can_access_course($courseid)) {
+ $builder->set_accessible($item, false);
+ continue;
+ }
+ $modinfo = get_fast_modinfo($builder->get_course($courseid));
+ // Set accessibility of this item and all other items in the same course.
+ $builder->walk(function ($taggeditem) use ($courseid, $modinfo, $builder) {
+ if ($taggeditem->courseid == $courseid) {
+ $accessible = false;
+ if (($cm = $modinfo->get_cm($taggeditem->cmid)) && $cm->uservisible) {
+ $subwiki = (object)array('id' => $taggeditem->subwikiid, 'groupid' => $taggeditem->groupid,
+ 'userid' => $taggeditem->groupid, 'wikiid' => $taggeditem->wikiid);
+ $wiki = (object)array('id' => $taggeditem->wikiid, 'wikimode' => $taggeditem->wikimode,
+ 'course' => $cm->course);
+ $accessible = wiki_user_can_view($subwiki, $wiki);
+ }
+ $builder->set_accessible($taggeditem, $accessible);
+ }
+ });
+ }
+
+ $items = $builder->get_items();
+ if (count($items) > $perpage) {
+ $totalpages = $page + 2; // We don't need exact page count, just indicate that the next page exists.
+ array_pop($items);
+ }
+
+ // Build the display contents.
+ if ($items) {
+ $tagfeed = new core_tag\output\tagfeed();
+ foreach ($items as $item) {
+ context_helper::preload_from_record($item);
+ $modinfo = get_fast_modinfo($item->courseid);
+ $cm = $modinfo->get_cm($item->cmid);
+ $pageurl = new moodle_url('/mod/wiki/view.php', array('pageid' => $item->id));
+ $pagename = format_string($item->title, true, array('context' => context_module::instance($item->cmid)));
+ $pagename = html_writer::link($pageurl, $pagename);
+ $courseurl = course_get_url($item->courseid, $cm->sectionnum);
+ $cmname = html_writer::link($cm->url, $cm->get_formatted_name());
+ $coursename = format_string($item->fullname, true, array('context' => context_course::instance($item->courseid)));
+ $coursename = html_writer::link($courseurl, $coursename);
+ $icon = html_writer::link($pageurl, html_writer::empty_tag('img', array('src' => $cm->get_icon_url())));
+ $tagfeed->add($icon, $pagename, $cmname.'<br>'.$coursename);
+ }
+
+ $content = $OUTPUT->render_from_template('core_tag/tagfeed',
+ $tagfeed->export_for_template($OUTPUT));
+
+ return new core_tag\output\tagindex($tag, 'mod_wiki', 'wiki_pages', $content,
+ $exclusivemode, $fromctx, $ctx, $rec, $page, $totalpages);
+ }
+}
}
}
- if ($wikipage = wiki_get_page_by_title($record['subwikiid'], $record['title'])) {
- $rv = wiki_save_page($wikipage, $record['content'], $USER->id);
- return $rv['page'];
+ $wikipage = wiki_get_page_by_title($record['subwikiid'], $record['title']);
+ if (!$wikipage) {
+ $pageid = wiki_create_page($record['subwikiid'], $record['title'], $record['format'], $USER->id);
+ $wikipage = wiki_get_page($pageid);
}
-
- $pageid = wiki_create_page($record['subwikiid'], $record['title'], $record['format'], $USER->id);
- $wikipage = wiki_get_page($pageid);
$rv = wiki_save_page($wikipage, $record['content'], $USER->id);
+
+ if (array_key_exists('tags', $record)) {
+ $tags = is_array($record['tags']) ? $record['tags'] : preg_split('/,/', $record['tags']);
+ if (empty($wiki->cmid)) {
+ $cm = get_coursemodule_from_instance('wiki', $wiki->id, isset($wiki->course) ? $wiki->course : 0);
+ $wiki->cmid = $cm->id;
+ }
+ core_tag_tag::set_item_tags('mod_wiki', 'wiki_pages', $wikipage->id,
+ context_module::instance($wiki->cmid), $tags);
+ }
return $rv['page'];
}
}
$page1 = $wikigenerator->create_first_page($wiki);
$page2 = $wikigenerator->create_content($wiki);
- $page3 = $wikigenerator->create_content($wiki, array('title' => 'Custom title'));
+ $page3 = $wikigenerator->create_content($wiki, array('title' => 'Custom title', 'tags' => array('Cats', 'mice')));
+ unset($wiki->cmid);
+ $page4 = $wikigenerator->create_content($wiki, array('tags' => 'Cats, dogs'));
$subwikis = $DB->get_records('wiki_subwikis', array('wikiid' => $wiki->id), 'id');
$this->assertEquals(1, count($subwikis));
$subwikiid = key($subwikis);
$records = $DB->get_records('wiki_pages', array('subwikiid' => $subwikiid), 'id');
- $this->assertEquals(3, count($records));
+ $this->assertEquals(4, count($records));
$this->assertEquals($page1->id, $records[$page1->id]->id);
$this->assertEquals($page2->id, $records[$page2->id]->id);
$this->assertEquals($page3->id, $records[$page3->id]->id);
$this->assertEquals('Custom title', $records[$page3->id]->title);
+ $this->assertEquals(array('Cats', 'mice'),
+ array_values(core_tag_tag::get_item_tags_array('mod_wiki', 'wiki_pages', $page3->id)));
+ $this->assertEquals(array('Cats', 'dogs'),
+ array_values(core_tag_tag::get_item_tags_array('mod_wiki', 'wiki_pages', $page4->id)));
}
public function test_create_content_individual() {
$result = wiki_get_visible_subwikis($wikisepind);
$this->assertEquals($expectedsubwikis, $result, '', 0, 10, true);
}
+
+ public function test_mod_wiki_get_tagged_pages() {
+ global $DB;
+
+ $this->resetAfterTest();
+ $this->setAdminUser();
+
+ // Setup test data.
+ $wikigenerator = $this->getDataGenerator()->get_plugin_generator('mod_wiki');
+ $course3 = $this->getDataGenerator()->create_course();
+ $course2 = $this->getDataGenerator()->create_course();
+ $course1 = $this->getDataGenerator()->create_course();
+ $wiki1 = $this->getDataGenerator()->create_module('wiki', array('course' => $course1->id));
+ $wiki2 = $this->getDataGenerator()->create_module('wiki', array('course' => $course2->id));
+ $wiki3 = $this->getDataGenerator()->create_module('wiki', array('course' => $course3->id));
+ $page11 = $wikigenerator->create_content($wiki1, array('tags' => array('Cats', 'Dogs')));
+ $page12 = $wikigenerator->create_content($wiki1, array('tags' => array('Cats', 'mice')));
+ $page13 = $wikigenerator->create_content($wiki1, array('tags' => array('Cats')));
+ $page14 = $wikigenerator->create_content($wiki1);
+ $page15 = $wikigenerator->create_content($wiki1, array('tags' => array('Cats')));
+ $page21 = $wikigenerator->create_content($wiki2, array('tags' => array('Cats')));
+ $page22 = $wikigenerator->create_content($wiki2, array('tags' => array('Cats', 'Dogs')));
+ $page23 = $wikigenerator->create_content($wiki2, array('tags' => array('mice', 'Cats')));
+ $page31 = $wikigenerator->create_content($wiki3, array('tags' => array('mice', 'Cats')));
+
+ $tag = core_tag_tag::get_by_name(0, 'Cats');
+
+ // Admin can see everything.
+ $res = mod_wiki_get_tagged_pages($tag, /*$exclusivemode = */false,
+ /*$fromctx = */0, /*$ctx = */0, /*$rec = */1, /*$page = */0);
+ $this->assertRegExp('/'.$page11->title.'/', $res->content);
+ $this->assertRegExp('/'.$page12->title.'/', $res->content);
+ $this->assertRegExp('/'.$page13->title.'/', $res->content);
+ $this->assertNotRegExp('/'.$page14->title.'/', $res->content);
+ $this->assertRegExp('/'.$page15->title.'/', $res->content);
+ $this->assertRegExp('/'.$page21->title.'/', $res->content);
+ $this->assertNotRegExp('/'.$page22->title.'/', $res->content);
+ $this->assertNotRegExp('/'.$page23->title.'/', $res->content);
+ $this->assertNotRegExp('/'.$page31->title.'/', $res->content);
+ $this->assertEmpty($res->prevpageurl);
+ $this->assertNotEmpty($res->nextpageurl);
+ $res = mod_wiki_get_tagged_pages($tag, /*$exclusivemode = */false,
+ /*$fromctx = */0, /*$ctx = */0, /*$rec = */1, /*$page = */1);
+ $this->assertNotRegExp('/'.$page11->title.'/', $res->content);
+ $this->assertNotRegExp('/'.$page12->title.'/', $res->content);
+ $this->assertNotRegExp('/'.$page13->title.'/', $res->content);
+ $this->assertNotRegExp('/'.$page14->title.'/', $res->content);
+ $this->assertNotRegExp('/'.$page15->title.'/', $res->content);
+ $this->assertNotRegExp('/'.$page21->title.'/', $res->content);
+ $this->assertRegExp('/'.$page22->title.'/', $res->content);
+ $this->assertRegExp('/'.$page23->title.'/', $res->content);
+ $this->assertRegExp('/'.$page31->title.'/', $res->content);
+ $this->assertNotEmpty($res->prevpageurl);
+ $this->assertEmpty($res->nextpageurl);
+
+ // Create and enrol a user.
+ $student = self::getDataGenerator()->create_user();
+ $studentrole = $DB->get_record('role', array('shortname' => 'student'));
+ $this->getDataGenerator()->enrol_user($student->id, $course1->id, $studentrole->id, 'manual');
+ $this->getDataGenerator()->enrol_user($student->id, $course2->id, $studentrole->id, 'manual');
+ $this->setUser($student);
+ core_tag_index_builder::reset_caches();
+
+ // User can not see pages in course 3 because he is not enrolled.
+ $res = mod_wiki_get_tagged_pages($tag, /*$exclusivemode = */false,
+ /*$fromctx = */0, /*$ctx = */0, /*$rec = */1, /*$page = */1);
+ $this->assertRegExp('/'.$page22->title.'/', $res->content);
+ $this->assertRegExp('/'.$page23->title.'/', $res->content);
+ $this->assertNotRegExp('/'.$page31->title.'/', $res->content);
+
+ // User can search wiki pages inside a course.
+ $coursecontext = context_course::instance($course1->id);
+ $res = mod_wiki_get_tagged_pages($tag, /*$exclusivemode = */false,
+ /*$fromctx = */0, /*$ctx = */$coursecontext->id, /*$rec = */1, /*$page = */0);
+ $this->assertRegExp('/'.$page11->title.'/', $res->content);
+ $this->assertRegExp('/'.$page12->title.'/', $res->content);
+ $this->assertRegExp('/'.$page13->title.'/', $res->content);
+ $this->assertNotRegExp('/'.$page14->title.'/', $res->content);
+ $this->assertRegExp('/'.$page15->title.'/', $res->content);
+ $this->assertNotRegExp('/'.$page21->title.'/', $res->content);
+ $this->assertNotRegExp('/'.$page22->title.'/', $res->content);
+ $this->assertNotRegExp('/'.$page23->title.'/', $res->content);
+ $this->assertEmpty($res->nextpageurl);
+ }
}
defined('MOODLE_INTERNAL') || die();
-$plugin->version = 2016011103; // The current module version (Date: YYYYMMDDXX)
+$plugin->version = 2016032700; // The current module version (Date: YYYYMMDDXX)
$plugin->requires = 2015111000; // Requires this Moodle version
$plugin->component = 'mod_wiki'; // Full name of the plugin (used for diagnostics)
$plugin->cron = 0;