MDL-25742 mod_wiki: show wiki pages tagged with a tag
This commit is contained in:
@@ -29,5 +29,7 @@ $tagareas = array(
|
||||
array(
|
||||
'itemtype' => 'wiki_pages',
|
||||
'component' => 'mod_wiki',
|
||||
'callback' => 'mod_wiki_get_tagged_pages',
|
||||
'callbackfile' => '/mod/wiki/locallib.php',
|
||||
),
|
||||
);
|
||||
|
||||
@@ -1734,3 +1734,118 @@ function wiki_get_subwiki_by_group_and_user_with_validation($wiki, $groupid, $us
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,14 +110,22 @@ class mod_wiki_generator extends testing_module_generator {
|
||||
}
|
||||
}
|
||||
|
||||
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'];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,16 +64,22 @@ class mod_wiki_generator_testcase extends advanced_testcase {
|
||||
|
||||
$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() {
|
||||
|
||||
@@ -654,4 +654,88 @@ class mod_wiki_lib_testcase extends advanced_testcase {
|
||||
$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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
|
||||
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;
|
||||
|
||||
Reference in New Issue
Block a user