Merge branch 'MDL-83900-main' of https://github.com/laurentdavid/moodle
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
issueNumber: MDL-83900
|
||||
notes:
|
||||
mod_wiki:
|
||||
- message: >-
|
||||
Create a manager class to regroup common functionalities and a wiki_mode
|
||||
enum related to the two different modes
|
||||
type: improved
|
||||
@@ -141,7 +141,7 @@ final class overviewfactory_test extends \advanced_testcase {
|
||||
],
|
||||
'wiki' => [
|
||||
'resourcetype' => 'wiki',
|
||||
'expected' => resourceoverview::class,
|
||||
'expected' => \mod_wiki\courseformat\overview::class,
|
||||
],
|
||||
'workshop' => [
|
||||
'resourcetype' => 'workshop',
|
||||
|
||||
@@ -83,7 +83,7 @@ final class missingoverviewnotice_test extends \advanced_testcase {
|
||||
'resource' => ['modname' => 'resource', 'expectempty' => true],
|
||||
'scorm' => ['modname' => 'scorm', 'expectempty' => false],
|
||||
'url' => ['modname' => 'url', 'expectempty' => false],
|
||||
'wiki' => ['modname' => 'wiki', 'expectempty' => false],
|
||||
'wiki' => ['modname' => 'wiki', 'expectempty' => true],
|
||||
'workshop' => ['modname' => 'workshop', 'expectempty' => true],
|
||||
];
|
||||
}
|
||||
|
||||
@@ -0,0 +1,148 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace mod_wiki\courseformat;
|
||||
|
||||
use core\output\renderer_helper;
|
||||
use core\url;
|
||||
use cm_info;
|
||||
use core_courseformat\local\overview\overviewitem;
|
||||
use core\output\action_link;
|
||||
use core\output\local\properties\text_align;
|
||||
use core\output\local\properties\button;
|
||||
use mod_wiki\manager;
|
||||
|
||||
/**
|
||||
* Wiki overview integration.
|
||||
*
|
||||
* @package mod_wiki
|
||||
* @copyright 2025 Laurent David <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class overview extends \core_courseformat\activityoverviewbase {
|
||||
/**
|
||||
* @var manager the wiki manager.
|
||||
*/
|
||||
private manager $manager;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param cm_info $cm the course module instance.
|
||||
* @param renderer_helper $rendererhelper the renderer helper.
|
||||
* @param \core_string_manager $stringmanager
|
||||
*/
|
||||
public function __construct(
|
||||
cm_info $cm,
|
||||
/** @var renderer_helper $rendererhelper the renderer helper */
|
||||
protected readonly renderer_helper $rendererhelper,
|
||||
/** @var \core_string_manager $stringmanager the string manager */
|
||||
protected readonly \core_string_manager $stringmanager,
|
||||
) {
|
||||
parent::__construct($cm);
|
||||
$this->manager = manager::create_from_coursemodule($cm);
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
public function get_actions_overview(): ?overviewitem {
|
||||
if (!has_capability('mod/wiki:managewiki', $this->cm->context)) {
|
||||
return null; // If the user cannot manage the wiki, we don't show the actions.
|
||||
}
|
||||
// If a wiki does not have a main page means it is not used yet, so we do not show the action link.
|
||||
$pageid = $this->manager->get_main_wiki_pageid();
|
||||
if (!$pageid) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$text = $this->stringmanager->get_string('view');
|
||||
|
||||
$content = new action_link(
|
||||
url: new url(
|
||||
'/mod/wiki/map.php',
|
||||
['pageid' => $pageid],
|
||||
),
|
||||
text: $text,
|
||||
attributes: ['class' => button::SECONDARY_OUTLINE->classes()],
|
||||
);
|
||||
return new overviewitem(
|
||||
name: $this->stringmanager->get_string('actions'),
|
||||
value: $text,
|
||||
content: $content,
|
||||
textalign: text_align::CENTER,
|
||||
);
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
public function get_extra_overview_items(): array {
|
||||
return [
|
||||
'wiki_type' => $this->get_extra_wiki_type(),
|
||||
'totalentries' => $this->get_total_entries(),
|
||||
'my_entries' => $this->get_extra_my_entries(),
|
||||
];
|
||||
}
|
||||
/**
|
||||
* Get the overview item for wiki type.
|
||||
*
|
||||
* @return overviewitem An overview item for the wiki type.
|
||||
*/
|
||||
private function get_extra_wiki_type(): overviewitem {
|
||||
return new overviewitem(
|
||||
name: $this->stringmanager->get_string('wikimode', 'wiki'),
|
||||
value: $this->manager->get_wiki_mode()->value,
|
||||
content: $this->manager->get_wiki_mode()->to_string(),
|
||||
textalign: text_align::CENTER,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the entries for a user
|
||||
*
|
||||
* @return overviewitem|null An overview item, or null if the user lacks the required capability.
|
||||
*/
|
||||
private function get_extra_my_entries(): ?overviewitem {
|
||||
global $USER;
|
||||
if (has_capability('mod/wiki:managewiki', $this->cm->context)) {
|
||||
return null; // If the user manage the wiki, we don't show the my entries.
|
||||
}
|
||||
$entriescount = $this->manager->get_user_entries_count($USER->id);
|
||||
return new overviewitem(
|
||||
name: $this->stringmanager->get_string('myentries', 'wiki'),
|
||||
value: $entriescount,
|
||||
content: $entriescount,
|
||||
textalign: text_align::CENTER,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the overview item for total entries.
|
||||
*
|
||||
* @return overviewitem An overview item for total entries.
|
||||
*/
|
||||
private function get_total_entries(): overviewitem {
|
||||
global $USER;
|
||||
$entriescount = $this->manager->get_all_entries_count($USER->id);
|
||||
$label = $this->stringmanager->get_string('totalentries', 'wiki');
|
||||
if (has_capability('mod/wiki:managewiki', $this->cm->context)) {
|
||||
$label = $this->stringmanager->get_string('entries', 'wiki');
|
||||
}
|
||||
return new overviewitem(
|
||||
name: $label,
|
||||
value: $entriescount,
|
||||
content: $entriescount,
|
||||
textalign: text_align::CENTER,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,258 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace mod_wiki;
|
||||
|
||||
use cm_info;
|
||||
use context_module;
|
||||
use stdClass;
|
||||
|
||||
/**
|
||||
* Class manager for wiki activity
|
||||
*
|
||||
* @package mod_wiki
|
||||
* @copyright 2025 Laurent David <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class manager {
|
||||
/** Module name. */
|
||||
public const MODULE = 'wiki';
|
||||
|
||||
/** The plugin name. */
|
||||
public const PLUGINNAME = 'mod_wiki';
|
||||
|
||||
/** @var context_module the current context. */
|
||||
private context_module $context;
|
||||
|
||||
/** @var stdClass $course record. */
|
||||
private stdClass $course;
|
||||
|
||||
/**
|
||||
* @var int $groupmode as defined in SEPARATEGROUPS, VISIBLEGROUPS, or NOGROUPS.
|
||||
*/
|
||||
private int $groupmode;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param cm_info $cm course module info object
|
||||
* @param stdClass $instance activity instance object.
|
||||
* @param \moodle_database $db the database instance.
|
||||
*/
|
||||
public function __construct(
|
||||
/** @var cm_info $cm course_modules record. */
|
||||
private cm_info $cm,
|
||||
/** @var stdClass $instance course_module record. */
|
||||
private stdClass $instance,
|
||||
/** @var \moodle_database $db the database instance. */
|
||||
private readonly \moodle_database $db
|
||||
) {
|
||||
$this->context = context_module::instance($cm->id);
|
||||
$this->course = $cm->get_course();
|
||||
$this->groupmode = groups_get_activity_groupmode($cm, $this->course);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a manager instance from an instance record.
|
||||
*
|
||||
* @param stdClass $instance an activity record
|
||||
* @return manager
|
||||
*/
|
||||
public static function create_from_instance(stdClass $instance): self {
|
||||
$cm = get_coursemodule_from_instance(self::MODULE, $instance->id);
|
||||
// Ensure that $this->cm is a cm_info object.
|
||||
$cm = cm_info::create($cm);
|
||||
$db = \core\di::get(\moodle_database::class);
|
||||
return new self($cm, $instance, $db);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a manager instance from a course_modules record.
|
||||
*
|
||||
* @param stdClass|cm_info $cm an activity record
|
||||
* @return manager
|
||||
*/
|
||||
public static function create_from_coursemodule(stdClass|cm_info $cm): self {
|
||||
// Ensure that $this->cm is a cm_info object.
|
||||
$cm = cm_info::create($cm);
|
||||
$db = \core\di::get(\moodle_database::class);
|
||||
$instance = $db->get_record(self::MODULE, ['id' => $cm->instance], '*', MUST_EXIST);
|
||||
return new self($cm, $instance, $db);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current context.
|
||||
*
|
||||
* @return context_module
|
||||
*/
|
||||
public function get_context(): context_module {
|
||||
return $this->context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current instance.
|
||||
*
|
||||
* @return stdClass the instance record
|
||||
*/
|
||||
public function get_instance(): stdClass {
|
||||
return $this->instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current cm_info.
|
||||
*
|
||||
* @return cm_info the course module
|
||||
*/
|
||||
public function get_coursemodule(): cm_info {
|
||||
return $this->cm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current entries count for this wiki module, that the provided user.
|
||||
*
|
||||
* @param int $userid the current user id (for grouping purposes)
|
||||
* @return int the number of entries
|
||||
*/
|
||||
public function get_all_entries_count(int $userid): int {
|
||||
$where = ' WHERE wsp.wikiid = :wikiid ';
|
||||
$params = ['wikiid' => $this->instance->id];
|
||||
$groupmemberjoin = '';
|
||||
// Individual wikis acts like a personal notebook, so we only count the pages of the current user.
|
||||
// However, for teachers, or in visible groups, the user also sees pages from other users.
|
||||
if (
|
||||
$this->get_wiki_mode() == wiki_mode::INDIVIDUAL
|
||||
&& !has_capability('mod/wiki:managewiki', $this->context, $userid)
|
||||
&& $this->cm->groupmode != VISIBLEGROUPS
|
||||
) {
|
||||
$where .= 'AND wp.userid = :authoruserid';
|
||||
$params['authoruserid'] = $userid;
|
||||
} else {
|
||||
[
|
||||
'join' => $groupmemberjoin,
|
||||
'params' => $params,
|
||||
'where' => $where,
|
||||
] = $this->get_group_member_join($userid, $this->instance->id);
|
||||
}
|
||||
|
||||
return $this->db->count_records_sql(
|
||||
'SELECT COUNT(*) FROM {wiki_pages} wp
|
||||
LEFT JOIN {wiki_subwikis} wsp ON wsp.id=wp.subwikiid'
|
||||
. $groupmemberjoin . $where,
|
||||
$params
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the SQL join for group members based on the provided user's group.
|
||||
*
|
||||
* @param int $userid the current user id
|
||||
* @param int $wikiid the wiki id
|
||||
* @return array an array containing the SQL join string and parameters
|
||||
*/
|
||||
private function get_group_member_join(int $userid, int $wikiid): array {
|
||||
$where = ' WHERE wsp.wikiid = :wikiid';
|
||||
$params = ['wikiid' => $wikiid];
|
||||
if (
|
||||
$this->groupmode == SEPARATEGROUPS
|
||||
&& !has_capability('moodle/site:accessallgroups', $this->context, $userid)
|
||||
) {
|
||||
$groups = groups_get_all_groups($this->course->id, $userid, 0, 'g.id');
|
||||
if (empty($groups)) {
|
||||
// No groups found for this user, return empty join but we show only records belonging to this user.
|
||||
$where .= ' AND wp.userid = :userid';
|
||||
$params['userid'] = $userid;
|
||||
return [
|
||||
'join' => '',
|
||||
'params' => $params,
|
||||
'where' => $where,
|
||||
];
|
||||
}
|
||||
// If not we will check both group from the subwiki and wiki pages user's.
|
||||
$groupids = array_column($groups, 'id');
|
||||
[$groupmembersql, $groupmemberparams] = groups_get_members_ids_sql($groupids, $this->context);
|
||||
$params = array_merge($params, $groupmemberparams);
|
||||
$groupmemberjoin = " JOIN ({$groupmembersql}) jg ON jg.id = wp.userid";
|
||||
[$wheregroup, $paramgroup] = $this->db->get_in_or_equal($groupids, SQL_PARAMS_NAMED, 'groupid');
|
||||
$where .= ' AND wsp.groupid ' . $wheregroup;
|
||||
$params = array_merge($params, $paramgroup);
|
||||
} else {
|
||||
$groupmemberjoin = '';
|
||||
}
|
||||
return ['join' => $groupmemberjoin, 'params' => $params, 'where' => $where];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of entries for a given user.
|
||||
*
|
||||
* @param int $userid the user id. We will ignore subwikis and groups.
|
||||
* @return int the number of entries
|
||||
*/
|
||||
public function get_user_entries_count(int $userid): int {
|
||||
$where = ' WHERE wsp.wikiid = :wikiid AND wp.userid = :userid';
|
||||
$params = [
|
||||
'wikiid' => $this->instance->id,
|
||||
'userid' => $userid,
|
||||
];
|
||||
return $this->db->count_records_sql(
|
||||
'SELECT COUNT(*) FROM {wiki_pages} wp
|
||||
LEFT JOIN {wiki_subwikis} wsp ON wsp.id=wp.subwikiid' . $where,
|
||||
$params
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Wiki mode (Individual or Collaborative)
|
||||
*
|
||||
* @return wiki_mode the wiki current mode
|
||||
*/
|
||||
public function get_wiki_mode(): wiki_mode {
|
||||
return wiki_mode::tryFrom($this->instance->wikimode) ?? wiki_mode::UNDEFINED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the main wiki page id for the current user, group and wiki.
|
||||
* This follow the routine in the view.php file taking info from the course module
|
||||
* id and the current group..
|
||||
*
|
||||
* @return int|null the wiki page id or null if not found
|
||||
*/
|
||||
public function get_main_wiki_pageid(): ?int {
|
||||
global $USER, $CFG;
|
||||
require_once($CFG->dirroot . '/mod/wiki/locallib.php');
|
||||
|
||||
if (!$wiki = wiki_get_wiki($this->cm->instance)) {
|
||||
return null;
|
||||
}
|
||||
$currentgroup = groups_get_activity_group($this->cm);
|
||||
|
||||
if (wiki_mode::tryFrom($wiki->wikimode) === wiki_mode::INDIVIDUAL) {
|
||||
$userid = $USER->id;
|
||||
} else {
|
||||
$userid = 0;
|
||||
}
|
||||
|
||||
// Getting subwiki. If it does not exists, return null.
|
||||
if (!$subwiki = wiki_get_subwiki_by_group($wiki->id, $currentgroup, $userid)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Getting first page of the wiki.
|
||||
if (!$page = wiki_get_first_page($subwiki->id)) {
|
||||
return null;
|
||||
}
|
||||
return $page->id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace mod_wiki;
|
||||
|
||||
/**
|
||||
* Wiki modes enum.
|
||||
*
|
||||
* @package mod_wiki
|
||||
* @copyright 2025 Laurent David <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
enum wiki_mode: string {
|
||||
case UNDEFINED = '';
|
||||
case COLLABORATIVE = 'collaborative';
|
||||
case INDIVIDUAL = 'individual';
|
||||
|
||||
/**
|
||||
* Returns the user friendly string representation of the wiki mode.
|
||||
*
|
||||
* @return string user friendly representation.
|
||||
*/
|
||||
public function to_string(): string {
|
||||
$stringmanager = \core\di::get(\core_string_manager::class);
|
||||
if ($this === self::UNDEFINED) {
|
||||
return $stringmanager->get_string('wikimodeundefined', 'mod_wiki');
|
||||
}
|
||||
return $stringmanager->get_string('wikimode' . $this->value, 'mod_wiki');
|
||||
}
|
||||
}
|
||||
@@ -32,70 +32,7 @@
|
||||
*/
|
||||
|
||||
require_once('../../config.php');
|
||||
require_once('lib.php');
|
||||
|
||||
$id = required_param('id', PARAM_INT); // course
|
||||
$PAGE->set_url('/mod/wiki/index.php', array('id' => $id));
|
||||
$courseid = required_param('id', PARAM_INT);
|
||||
|
||||
if (!$course = $DB->get_record('course', array('id' => $id))) {
|
||||
throw new \moodle_exception('invalidcourseid');
|
||||
}
|
||||
|
||||
require_login($course, true);
|
||||
$PAGE->set_pagelayout('incourse');
|
||||
$context = context_course::instance($course->id);
|
||||
|
||||
$event = \mod_wiki\event\course_module_instance_list_viewed::create(array('context' => $context));
|
||||
$event->add_record_snapshot('course', $course);
|
||||
$event->trigger();
|
||||
|
||||
/// Get all required stringswiki
|
||||
$strwikis = get_string("modulenameplural", "wiki");
|
||||
$strwiki = get_string("modulename", "wiki");
|
||||
|
||||
/// Print the header
|
||||
$PAGE->navbar->add($strwikis, "index.php?id=$course->id");
|
||||
$PAGE->set_title($strwikis);
|
||||
$PAGE->set_heading($course->fullname);
|
||||
echo $OUTPUT->header();
|
||||
echo $OUTPUT->heading($strwikis);
|
||||
|
||||
/// Get all the appropriate data
|
||||
if (!$wikis = get_all_instances_in_course("wiki", $course)) {
|
||||
notice("There are no wikis", "../../course/view.php?id=$course->id");
|
||||
die;
|
||||
}
|
||||
|
||||
$usesections = course_format_uses_sections($course->format);
|
||||
|
||||
/// Print the list of instances (your module will probably extend this)
|
||||
|
||||
$timenow = time();
|
||||
$strname = get_string("name");
|
||||
$table = new html_table();
|
||||
|
||||
if ($usesections) {
|
||||
$strsectionname = course_get_format($course)->get_generic_section_name();
|
||||
$table->head = array($strsectionname, $strname);
|
||||
} else {
|
||||
$table->head = array($strname);
|
||||
}
|
||||
|
||||
foreach ($wikis as $wiki) {
|
||||
$linkcss = null;
|
||||
if (!$wiki->visible) {
|
||||
$linkcss = array('class' => 'dimmed');
|
||||
}
|
||||
$link = html_writer::link(new moodle_url('/mod/wiki/view.php', array('id' => $wiki->coursemodule)), $wiki->name, $linkcss);
|
||||
|
||||
if ($usesections) {
|
||||
$table->data[] = array(get_section_name($course, $wiki->section), $link);
|
||||
} else {
|
||||
$table->data[] = array($link);
|
||||
}
|
||||
}
|
||||
|
||||
echo html_writer::table($table);
|
||||
|
||||
/// Finish the page
|
||||
echo $OUTPUT->footer();
|
||||
\core_courseformat\activityoverviewbase::redirect_to_overview_page($courseid, 'wiki');
|
||||
|
||||
@@ -64,6 +64,7 @@ $string['editing'] = 'Editing wiki page';
|
||||
$string['editingcomment'] = 'Editing comment';
|
||||
$string['editingpage'] = 'Editing this page \'{$a}\'';
|
||||
$string['editsection'] = 'edit';
|
||||
$string['entries'] = 'Entries';
|
||||
$string['eventdiffviewed'] = 'Wiki diff viewed';
|
||||
$string['eventhistoryviewed'] = 'Wiki history viewed';
|
||||
$string['eventmapviewed'] = 'Wiki page map viewed';
|
||||
@@ -151,6 +152,7 @@ Wikis have many uses, such as
|
||||
* As a personal journal for examination notes or revision (using an individual wiki)';
|
||||
$string['modulename_link'] = 'mod/wiki/view';
|
||||
$string['modulenameplural'] = 'Wikis';
|
||||
$string['myentries'] = 'My entries';
|
||||
$string['navigation'] = 'Navigation';
|
||||
$string['navigationfrom'] = 'This page comes from';
|
||||
$string['navigationfrom_help'] = 'The wiki pages linking to this page';
|
||||
@@ -259,6 +261,7 @@ $string['tableofcontents'] = 'Table of contents';
|
||||
$string['tagarea_wiki_pages'] = 'Wiki pages';
|
||||
$string['teacherrating'] = 'Teacher rating';
|
||||
$string['timesrating'] = 'This page has been rated {$a->c} times with an average of: {$a->s}';
|
||||
$string['totalentries'] = 'Total entries';
|
||||
$string['updatedpages'] = "Updated pages";
|
||||
$string['updatedpages_help'] = "Recently updated wiki pages";
|
||||
$string['updatedwikipages'] = "Updated wiki pages";
|
||||
@@ -292,6 +295,7 @@ $string['wikimode'] = 'Wiki mode';
|
||||
$string['wikimode_help'] = 'The wiki mode determines whether everyone can edit the wiki - a collaborative wiki - or whether everyone has their own wiki which only they can edit - an individual wiki.';
|
||||
$string['wikimodecollaborative'] = 'Collaborative wiki';
|
||||
$string['wikimodeindividual'] = 'Individual wiki';
|
||||
$string['wikimodeundefined'] = 'Wikimode undefined';
|
||||
$string['wikiname'] = 'Wiki name';
|
||||
$string['wikinowikitext'] = 'No wiki text';
|
||||
$string['wikiorderedlist'] = 'Ordered list';
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
@mod @mod_wiki
|
||||
Feature: Testing overview integration in mod_wiki
|
||||
In order to summarize the wikis
|
||||
As a user
|
||||
I need to be able to see the wiki overview
|
||||
|
||||
Background:
|
||||
Given the following "users" exist:
|
||||
| username | firstname | lastname |
|
||||
| student1 | Student | 1 |
|
||||
| student2 | Student | 2 |
|
||||
| student3 | Student | 3 |
|
||||
| teacher1 | Teacher | T |
|
||||
And the following "courses" exist:
|
||||
| fullname | shortname | groupmode |
|
||||
| Course 1 | C1 | 1 |
|
||||
And the following "course enrolments" exist:
|
||||
| user | course | role |
|
||||
| student1 | C1 | student |
|
||||
| student2 | C1 | student |
|
||||
| student3 | C1 | student |
|
||||
| teacher1 | C1 | editingteacher |
|
||||
Given the following "groups" exist:
|
||||
| name | course | idnumber | participation |
|
||||
| Group 1 | C1 | G1 | 1 |
|
||||
| Group 2 | C1 | G2 | 1 |
|
||||
| Group 3 | C1 | G3 | 0 |
|
||||
And the following "group members" exist:
|
||||
| user | group |
|
||||
| student1 | G1 |
|
||||
| student2 | G2 |
|
||||
| student3 | G3 |
|
||||
And the following "activities" exist:
|
||||
| activity | course | name | idnumber | wikimode | firstpagetitle | groupmode |
|
||||
| wiki | C1 | Separate wiki | wiki1 | collaborative | Separate page 1 | 1 |
|
||||
| wiki | C1 | Visible wiki | wiki2 | collaborative | Visible page 1 | 2 |
|
||||
And the following wiki pages exist:
|
||||
| wiki | title | content | group |
|
||||
| wiki1 | Separate page 1 | Group 1 page | G1 |
|
||||
| wiki1 | Separate page 1 | Group 2 page | G2 |
|
||||
| wiki2 | Visible page 1 | Group 1 page | G1 |
|
||||
| wiki2 | Visible page 1 | Group 2 page | G2 |
|
||||
And the following wiki pages exist:
|
||||
| wiki | title | content |
|
||||
| wiki1 | Separate page 1 | No group page |
|
||||
| wiki2 | Visible page 1 | No group page |
|
||||
|
||||
Scenario: The wiki overview report should generate log events
|
||||
Given I am on the "Course 1" "course > activities > wiki" page logged in as "teacher1"
|
||||
When I am on the "Course 1" "course" page logged in as "teacher1"
|
||||
And I navigate to "Reports" in current page administration
|
||||
And I click on "Logs" "link"
|
||||
And I click on "Get these logs" "button"
|
||||
Then I should see "Course activities overview page viewed"
|
||||
And I should see "viewed the instance list for the module 'wiki'"
|
||||
|
||||
Scenario: Students can see relevant columns in the wiki overview
|
||||
Given I am on the "Course 1" "course > activities > wiki" page logged in as "student1"
|
||||
Then the following should exist in the "Table listing all Wiki activities" table:
|
||||
| Name | My entries | Total entries |
|
||||
| Separate wiki | 0 | 0 |
|
||||
| Visible wiki | 0 | 3 |
|
||||
|
||||
Scenario: Teachers can see relevant columns in the wiki overview
|
||||
Given I am on the "Course 1" "course > activities > wiki" page logged in as "teacher1"
|
||||
Then the following should exist in the "Table listing all Wiki activities" table:
|
||||
| Name | Wiki mode | Entries | Actions |
|
||||
| Separate wiki | Collaborative wiki | 3 | View |
|
||||
| Visible wiki | Collaborative wiki | 3 | View |
|
||||
|
||||
Scenario: The wiki index redirect to the activities overview
|
||||
When I log in as "admin"
|
||||
And I am on "Course 1" course homepage with editing mode on
|
||||
And I add the "Activities" block
|
||||
And I click on "Wikis" "link" in the "Activities" "block"
|
||||
Then I should see "An overview of all activities in the course"
|
||||
And I should see "Name" in the "wiki_overview_collapsible" "region"
|
||||
And I should see "Wiki mode" in the "wiki_overview_collapsible" "region"
|
||||
And I should see "Entries" in the "wiki_overview_collapsible" "region"
|
||||
@@ -0,0 +1,279 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace mod_wiki\courseformat;
|
||||
|
||||
use core_courseformat\local\overview\overviewfactory;
|
||||
use mod_wiki\wiki_mode;
|
||||
use ReflectionClass;
|
||||
|
||||
/**
|
||||
* Tests for Wiki integration.
|
||||
*
|
||||
* @covers \mod_wiki\courseformat\overview
|
||||
* @package mod_wiki
|
||||
* @category test
|
||||
* @copyright 2025 Laurent David <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
final class overview_test extends \advanced_testcase {
|
||||
|
||||
|
||||
/**
|
||||
* Data provider for wiki modes.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_wiki_mode_provider(): array {
|
||||
return [
|
||||
'collaborative' => ['mode' => wiki_mode::COLLABORATIVE],
|
||||
'individual' => ['mode' => wiki_mode::INDIVIDUAL],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get_extra_my_entries method.
|
||||
*
|
||||
* @param string $username
|
||||
* @param int|null $expectedcount
|
||||
* @return void
|
||||
*
|
||||
* @covers ::get_extra_my_entries
|
||||
* @dataProvider get_extra_my_entries_provider
|
||||
*/
|
||||
public function test_get_extra_my_entries(string $username, ?int $expectedcount = null): void {
|
||||
$this->resetAfterTest();
|
||||
['users' => $users, 'instance' => $instance, 'course' => $course] = $this->setup_users_and_activity();
|
||||
$cm = get_fast_modinfo($course)->get_cm($instance->cmid);
|
||||
$overview = overviewfactory::create($cm);
|
||||
$this->setUser($users[$username]->id);
|
||||
$items = $overview->get_extra_overview_items();
|
||||
$item = $items['my_entries'] ?? null;
|
||||
|
||||
$this->assertEquals(
|
||||
$expectedcount,
|
||||
$item?->get_value()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for get_extra_my_entries.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_extra_my_entries_provider(): array {
|
||||
return [
|
||||
'student 1' => ['s1', 1],
|
||||
'student 2' => ['s2', 1],
|
||||
'teacher 1' => ['t1', null], // Teacher 1 does not have any entries.
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the wiki mode of the wiki instance.
|
||||
*
|
||||
* @param wiki_mode $mode the expected wiki mode.
|
||||
*
|
||||
* @covers ::get_extra_wiki_type
|
||||
* @dataProvider get_wiki_mode_provider
|
||||
*/
|
||||
public function test_wiki_mode(wiki_mode $mode): void {
|
||||
$this->resetAfterTest();
|
||||
['users' => $users, 'instance' => $instance, 'course' => $course] =
|
||||
$this->setup_users_and_activity(NOGROUPS, $mode->value);
|
||||
$cm = get_fast_modinfo($course)->get_cm($instance->cmid);
|
||||
$overview = overviewfactory::create($cm);
|
||||
$this->setUser($users['t1']->id);
|
||||
$items = $overview->get_extra_overview_items();
|
||||
$item = $items['wiki_type'] ?? null;
|
||||
|
||||
$this->assertEquals(
|
||||
$mode->value,
|
||||
$item->get_value(),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup users and activity for testing answers retrieval.
|
||||
*
|
||||
* @param int $groupmode the group mode to use for the course.
|
||||
* @param string $mode the mode of the wiki instance.
|
||||
* @return array indexed array with 'users', 'course' and 'instance'.
|
||||
*/
|
||||
private function setup_users_and_activity(int $groupmode = NOGROUPS, string $mode = 'collaborative'): array {
|
||||
global $CFG;
|
||||
require_once($CFG->dirroot . '/mod/wiki/locallib.php');
|
||||
$users = [];
|
||||
$generator = $this->getDataGenerator();
|
||||
$courseparams = [];
|
||||
if ($groupmode !== NOGROUPS) {
|
||||
// Set the group mode for the course.
|
||||
$courseparams['groupmode'] = $groupmode;
|
||||
}
|
||||
$course = $generator->create_course($courseparams);
|
||||
foreach (['s1' => 'student', 's2' => 'student', 't1' => 'teacher', 't2' => 'teacher'] as $username => $role) {
|
||||
$users[$username] = $generator->create_and_enrol($course, $role, ['username' => $username]);
|
||||
}
|
||||
|
||||
$groups = [];
|
||||
if ($groupmode !== NOGROUPS) {
|
||||
// Create a group if the group mode is not NOGROUPS.
|
||||
$groups[] = $generator->create_group(['courseid' => $course->id]);
|
||||
$groups[] = $generator->create_group(['courseid' => $course->id]);
|
||||
groups_add_member($groups[0], $users['s1']->id);
|
||||
groups_add_member($groups[1], $users['s2']->id);
|
||||
groups_add_member($groups[0], $users['t1']->id);
|
||||
}
|
||||
$instance = $generator->create_module(
|
||||
'wiki',
|
||||
[
|
||||
'course' => $course,
|
||||
'wikimode' => $mode,
|
||||
'groupmode' => $groupmode,
|
||||
'firstpagetitle' => 'Wiki first page title',
|
||||
],
|
||||
);
|
||||
|
||||
$wikigenerator = $generator->get_plugin_generator('mod_wiki');
|
||||
|
||||
$pages = [];
|
||||
foreach (['s1', 's2'] as $username) {
|
||||
$user = $users[$username];
|
||||
// Create a first page for each user.
|
||||
$this->setUser($user->id);
|
||||
$groups = groups_get_my_groups();
|
||||
foreach ($groups as $group) {
|
||||
$authorid = ($mode === wiki_mode::INDIVIDUAL->value) ? $user->id : 0;
|
||||
|
||||
// Ensure the user is in the group.
|
||||
$pages[] = $wikigenerator->create_first_page(
|
||||
$instance,
|
||||
[
|
||||
'wikiid' => $instance->id,
|
||||
'userid' => $authorid,
|
||||
'group' => $group->id,
|
||||
'content' => "Wiki first page content for $username",
|
||||
'title' => "Wiki first page title",
|
||||
],
|
||||
);
|
||||
}
|
||||
if (empty($groups)) {
|
||||
$pages[] = $wikigenerator->create_page(
|
||||
$instance,
|
||||
[
|
||||
'wikiid' => $instance->id,
|
||||
'userid' => $user->id,
|
||||
'content' => "Wiki first page content for $username",
|
||||
'title' => "Wiki first page title",
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
return [
|
||||
'users' => $users,
|
||||
'course' => $course,
|
||||
'instance' => $instance,
|
||||
'pages' => $pages,
|
||||
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get_extra_entries method.
|
||||
*
|
||||
* @param string $username
|
||||
* @param int $coursegroupmode
|
||||
* @param int $expectedcount
|
||||
*
|
||||
* @covers ::get_extra_entries
|
||||
* @dataProvider data_provider_get_extra_entries
|
||||
*/
|
||||
public function test_get_extra_entries(
|
||||
string $username,
|
||||
int $coursegroupmode,
|
||||
int $expectedcount
|
||||
): void {
|
||||
$this->resetAfterTest();
|
||||
[
|
||||
'users' => $users,
|
||||
'instance' => $instance,
|
||||
'course' => $course
|
||||
] = $this->setup_users_and_activity($coursegroupmode);
|
||||
|
||||
$cm = get_fast_modinfo($course)->get_cm($instance->cmid);
|
||||
$this->setUser($users[$username]->id);
|
||||
|
||||
$overview = overviewfactory::create($cm);
|
||||
$items = $overview->get_extra_overview_items();
|
||||
$item = $items['totalentries'] ?? null;
|
||||
$this->assertEquals($expectedcount, $item->get_value());
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for get_extra_entries.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function data_provider_get_extra_entries(): array {
|
||||
return [
|
||||
'teacher 1 (no group mode)' => ['t1', NOGROUPS, 2],
|
||||
'teacher 1 (separate group mode)' => ['t1', SEPARATEGROUPS, 1], // Teacher 1 belongs to group 1, so should see s1.
|
||||
'teacher 1 (visible group mode)' => ['t1', VISIBLEGROUPS, 2],
|
||||
// Teacher 2 does not belong to any group.
|
||||
'teacher 2 (no group mode)' => ['t2', NOGROUPS, 2],
|
||||
'teacher 2 (separate group mode)' => ['t2', SEPARATEGROUPS, 0], // Teacher 2 does not belong to any group.
|
||||
'teacher 2 (visible group mode)' => ['t2', VISIBLEGROUPS, 2],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get_extra_entries method.
|
||||
*
|
||||
* @covers ::get_actions_overview
|
||||
*/
|
||||
public function test_get_actions_overview(): void {
|
||||
$this->resetAfterTest();
|
||||
|
||||
[
|
||||
'users' => $users,
|
||||
'instance' => $instance,
|
||||
'course' => $course
|
||||
] = $this->setup_users_and_activity(SEPARATEGROUPS);
|
||||
|
||||
$notinitinstance = $this->getDataGenerator()->create_module(
|
||||
'wiki',
|
||||
[
|
||||
'course' => $course,
|
||||
'wikimode' => wiki_mode::INDIVIDUAL->value,
|
||||
]
|
||||
);
|
||||
|
||||
$this->setUser($users['t1']->id);
|
||||
|
||||
$cm = get_fast_modinfo($course)->get_cm($instance->cmid);
|
||||
$emptycm = get_fast_modinfo($course)->get_cm($notinitinstance->cmid);
|
||||
|
||||
$overview = overviewfactory::create($cm);
|
||||
$item = $overview->get_actions_overview();
|
||||
|
||||
$this->assertNotNull($item);
|
||||
|
||||
$overview = overviewfactory::create($emptycm);
|
||||
$item = $overview->get_actions_overview();
|
||||
|
||||
$this->assertNull($item);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,465 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace mod_wiki;
|
||||
/**
|
||||
* Generator tests class.
|
||||
*
|
||||
* @package mod_wiki
|
||||
* @copyright 2025 Laurent David <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @covers \mod_wiki\manager
|
||||
*/
|
||||
final class manager_test extends \advanced_testcase {
|
||||
|
||||
/**
|
||||
* Data provider for wiki modes.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_wiki_mode_provider(): array {
|
||||
return [
|
||||
'collaborative' => ['mode' => 'collaborative', 'expected' => wiki_mode::COLLABORATIVE],
|
||||
'individual' => ['mode' => 'individual', 'expected' => wiki_mode::INDIVIDUAL],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for test_get_all_entries_count.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_all_entries_count_provider(): array {
|
||||
return [
|
||||
'teacher 1 (no group mode, collaborative)' => [
|
||||
'username' => 't1',
|
||||
'coursegroupmode' => NOGROUPS,
|
||||
'wikimode' => wiki_mode::COLLABORATIVE,
|
||||
'expectedcount' => 2,
|
||||
],
|
||||
'teacher 1 (no group mode, undefined)' => [
|
||||
'username' => 't1',
|
||||
'coursegroupmode' => NOGROUPS,
|
||||
'wikimode' => wiki_mode::UNDEFINED,
|
||||
'expectedcount' => 2,
|
||||
],
|
||||
'teacher 1 (separate group mode, collaborative)' => [
|
||||
'username' => 't1',
|
||||
'coursegroupmode' => SEPARATEGROUPS,
|
||||
'wikimode' => wiki_mode::COLLABORATIVE,
|
||||
'expectedcount' => 1,
|
||||
],
|
||||
// Teacher 1 belongs to group 1, so should see s1.
|
||||
'teacher 1 (visible group mode, collaborative)' => [
|
||||
'username' => 't1',
|
||||
'coursegroupmode' => VISIBLEGROUPS,
|
||||
'wikimode' => wiki_mode::COLLABORATIVE,
|
||||
'expectedcount' => 2,
|
||||
],
|
||||
// Teacher 2 does not belong to any group.
|
||||
'teacher 2 (no group mode, collaborative)' => [
|
||||
'username' => 't2',
|
||||
'coursegroupmode' => NOGROUPS,
|
||||
'wikimode' => wiki_mode::COLLABORATIVE,
|
||||
'expectedcount' => 2,
|
||||
],
|
||||
'teacher 2 (separate group mode, collaborative)' => [
|
||||
'username' => 't2',
|
||||
'coursegroupmode' => SEPARATEGROUPS,
|
||||
'wikimode' => wiki_mode::COLLABORATIVE,
|
||||
'expectedcount' => 0,
|
||||
],
|
||||
// Teacher 2 does not belong to any group.
|
||||
'teacher 2 (visible group mode, collaborative)' => [
|
||||
'username' => 't2',
|
||||
'coursegroupmode' => VISIBLEGROUPS,
|
||||
'wikimode' => wiki_mode::COLLABORATIVE,
|
||||
'expectedcount' => 2,
|
||||
],
|
||||
// Teacher Individual mode.
|
||||
'teacher 1 (no group mode, individual)' => [
|
||||
'username' => 't1',
|
||||
'coursegroupmode' => NOGROUPS,
|
||||
'wikimode' => wiki_mode::INDIVIDUAL,
|
||||
'expectedcount' => 2,
|
||||
],
|
||||
'teacher 1 (separate group mode, individual)' => [
|
||||
'username' => 't1',
|
||||
'coursegroupmode' => SEPARATEGROUPS,
|
||||
'wikimode' => wiki_mode::INDIVIDUAL,
|
||||
'expectedcount' => 1,
|
||||
],
|
||||
'teacher 1 (visible group mode, individual)' => [
|
||||
'username' => 't1',
|
||||
'coursegroupmode' => VISIBLEGROUPS,
|
||||
'wikimode' => wiki_mode::INDIVIDUAL,
|
||||
'expectedcount' => 2,
|
||||
],
|
||||
// Student collaborative mode.
|
||||
'student 1 (no group mode, collaborative)' => [
|
||||
'username' => 's1',
|
||||
'coursegroupmode' => NOGROUPS,
|
||||
'wikimode' => wiki_mode::COLLABORATIVE,
|
||||
'expectedcount' => 2,
|
||||
],
|
||||
'student 1 (separate group mode, collaborative)' => [
|
||||
'username' => 's1',
|
||||
'coursegroupmode' => SEPARATEGROUPS,
|
||||
'wikimode' => wiki_mode::COLLABORATIVE,
|
||||
'expectedcount' => 1,
|
||||
],
|
||||
'student 1 (visible group mode, collaborative)' => [
|
||||
'username' => 's1',
|
||||
'coursegroupmode' => VISIBLEGROUPS,
|
||||
'wikimode' => wiki_mode::COLLABORATIVE,
|
||||
'expectedcount' => 2,
|
||||
],
|
||||
// Student individual mode.
|
||||
'student 1 (no group mode, individual)' => [
|
||||
'username' => 's1',
|
||||
'coursegroupmode' => NOGROUPS,
|
||||
'wikimode' => wiki_mode::INDIVIDUAL,
|
||||
'expectedcount' => 1,
|
||||
],
|
||||
'student 1 (separate group mode, individual)' => [
|
||||
'username' => 's1',
|
||||
'coursegroupmode' => SEPARATEGROUPS,
|
||||
'wikimode' => wiki_mode::INDIVIDUAL,
|
||||
'expectedcount' => 1,
|
||||
],
|
||||
'student 1 (visible group mode, individual)' => [
|
||||
'username' => 's1',
|
||||
'coursegroupmode' => VISIBLEGROUPS,
|
||||
'wikimode' => wiki_mode::INDIVIDUAL,
|
||||
'expectedcount' => 2,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for test_get_all_entries_count.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_user_entries_count_provider(): array {
|
||||
return [
|
||||
'student 1' => ['s1', 1],
|
||||
'student 2' => ['s2', 1],
|
||||
'teacher 1' => ['t1', 0],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up the test environment.
|
||||
*/
|
||||
public function setUp(): void {
|
||||
parent::setUp();
|
||||
$this->resetAfterTest();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test creating a manager instance from an instance record.
|
||||
*
|
||||
* @covers \mod_wiki\manager::create_from_instance
|
||||
*/
|
||||
public function test_create_manager_instance_from_instance_record(): void {
|
||||
$this->resetAfterTest();
|
||||
['instance' => $instance] = $this->setup_users_and_activity();
|
||||
$manager = manager::create_from_instance($instance);
|
||||
$this->assertNotNull($manager);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup users and activity for testing answers retrieval.
|
||||
*
|
||||
* @param int $groupmode the group mode to use for the course.
|
||||
* @param wiki_mode $mode the wiki mode to use for the instance.
|
||||
* @return array indexed array with 'users', 'course' and 'instance'.
|
||||
*/
|
||||
private function setup_users_and_activity(int $groupmode = NOGROUPS, wiki_mode $mode = wiki_mode::COLLABORATIVE): array {
|
||||
global $CFG;
|
||||
require_once($CFG->dirroot . '/mod/wiki/locallib.php');
|
||||
$users = [];
|
||||
$generator = $this->getDataGenerator();
|
||||
$courseparams = [];
|
||||
if ($groupmode !== NOGROUPS) {
|
||||
// Set the group mode for the course.
|
||||
$courseparams['groupmode'] = $groupmode;
|
||||
}
|
||||
$course = $generator->create_course($courseparams);
|
||||
foreach (['s1' => 'student', 's2' => 'student', 't1' => 'teacher', 't2' => 'teacher'] as $username => $role) {
|
||||
$users[$username] = $generator->create_and_enrol($course, $role, ['username' => $username]);
|
||||
}
|
||||
|
||||
$groups = [];
|
||||
if ($groupmode !== NOGROUPS) {
|
||||
// Create a group if the group mode is not NOGROUPS.
|
||||
$groups[] = $generator->create_group(['courseid' => $course->id]);
|
||||
$groups[] = $generator->create_group(['courseid' => $course->id]);
|
||||
groups_add_member($groups[0], $users['s1']->id);
|
||||
groups_add_member($groups[1], $users['s2']->id);
|
||||
groups_add_member($groups[0], $users['t1']->id);
|
||||
}
|
||||
$instance = $generator->create_module(
|
||||
'wiki',
|
||||
[
|
||||
'course' => $course,
|
||||
'wikimode' => $mode->value,
|
||||
'groupmode' => $groupmode,
|
||||
],
|
||||
);
|
||||
|
||||
$wikigenerator = $generator->get_plugin_generator('mod_wiki');
|
||||
|
||||
$pages = [];
|
||||
foreach (['s1', 's2'] as $username) {
|
||||
$user = $users[$username];
|
||||
// Create a first page for each user.
|
||||
$this->setUser($user->id);
|
||||
$groups = groups_get_my_groups();
|
||||
$userid = $mode === wiki_mode::INDIVIDUAL ? $user->id : 0; // Use user id for individual mode, 0 for collaborative
|
||||
// This is similar to the view.php logic, where the first page is created either for group or users.
|
||||
foreach ($groups as $group) {
|
||||
// Ensure the user is in the group.
|
||||
$pages["{$username}{$group->name}"] = $wikigenerator->create_first_page($instance, [
|
||||
'wikiid' => $instance->id,
|
||||
'userid' => $userid,
|
||||
'group' => $group->id,
|
||||
'content' => "Wiki first page content for $username",
|
||||
'title' => $instance->firstpagetitle, // We need to use the first page title from the instance to make sure
|
||||
// that this page is considered as first page. {@see wiki_get_first_page()}.
|
||||
]);
|
||||
}
|
||||
if (empty($groups)) {
|
||||
$pages["{$username}"] = $wikigenerator->create_page($instance, [
|
||||
'wikiid' => $instance->id,
|
||||
'userid' => $userid,
|
||||
'content' => "Wiki first page content for $username",
|
||||
'title' => "Wiki first page title for $username",
|
||||
]);
|
||||
}
|
||||
}
|
||||
return [
|
||||
'users' => $users,
|
||||
'course' => $course,
|
||||
'instance' => $instance,
|
||||
'pages' => $pages,
|
||||
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test creating a manager instance from a course module.
|
||||
*
|
||||
* @covers \mod_wiki\manager::create_from_coursemodule
|
||||
*/
|
||||
public function test_create_manager_instance_from_coursemodule(): void {
|
||||
$this->resetAfterTest();
|
||||
['instance' => $instance, 'course' => $course] = $this->setup_users_and_activity();
|
||||
$cm = get_fast_modinfo($course)->get_cm($instance->cmid);
|
||||
$manager = manager::create_from_coursemodule($cm);
|
||||
$this->assertNotNull($manager);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the wiki mode of the wiki instance.
|
||||
*
|
||||
* @param string $mode the mode of the wiki instance.
|
||||
* @param wiki_mode $expected the expected wiki mode.
|
||||
*
|
||||
* @covers \mod_wiki\manager::get_wiki_mode
|
||||
* @dataProvider get_wiki_mode_provider
|
||||
*/
|
||||
public function test_wiki_mode(string $mode, wiki_mode $expected): void {
|
||||
$this->resetAfterTest();
|
||||
$course = $this->getDataGenerator()->create_course();
|
||||
$wiki = $this->getDataGenerator()->create_module('wiki', ['course' => $course, 'wikimode' => $mode]);
|
||||
$manager = manager::create_from_instance($wiki);
|
||||
$this->assertEquals($expected, $manager->get_wiki_mode());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test retrieving entries count for all users.
|
||||
*
|
||||
* @param string $username the username of the user to retrieve entries count for.
|
||||
* @param int $coursegroupmode the group mode of the course.
|
||||
* @param wiki_mode $wikimode the wiki mode of the instance.
|
||||
* @param int $expectedcount the expected count of answers for the user.
|
||||
*
|
||||
* @covers \mod_wiki\manager::get_all_entries_count
|
||||
* @dataProvider get_all_entries_count_provider
|
||||
*/
|
||||
public function test_get_all_entries_count(
|
||||
string $username,
|
||||
int $coursegroupmode,
|
||||
wiki_mode $wikimode,
|
||||
int $expectedcount
|
||||
): void {
|
||||
[
|
||||
'users' => $users,
|
||||
'instance' => $instance
|
||||
] = $this->setup_users_and_activity($coursegroupmode, $wikimode);
|
||||
|
||||
$manager = manager::create_from_instance($instance);
|
||||
$count = $manager->get_all_entries_count($users[$username]->id);
|
||||
$this->assertEquals($expectedcount, $count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test retrieving entries my count for a given user.
|
||||
*
|
||||
* @param string $username the username of the user to retrieve entries count for.
|
||||
* @param int $expectedcount the expected count of answers for the user.
|
||||
*
|
||||
* @covers \mod_wiki\manager::get_user_entries_count
|
||||
* @dataProvider get_user_entries_count_provider
|
||||
*/
|
||||
public function test_get_user_entries_count(string $username, int $expectedcount): void {
|
||||
['users' => $users, 'instance' => $instance] = $this->setup_users_and_activity();
|
||||
$manager = manager::create_from_instance($instance);
|
||||
$count = $manager->get_user_entries_count($users[$username]->id);
|
||||
$this->assertEquals($expectedcount, $count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the get_wiki_pageid method.
|
||||
*
|
||||
* @param string $username the username of the user to retrieve the page id for.
|
||||
* @param int $groupmode
|
||||
* @param wiki_mode $wikimode the wiki mode of the instance.
|
||||
* @param string|null $expectedpage the expected page id for the user.
|
||||
*
|
||||
* @covers \mod_wiki\manager::get_main_wiki_pageid
|
||||
* @dataProvider get_main_wiki_pageid_data_provider
|
||||
*/
|
||||
public function test_get_main_wiki_pageid(string $username, int $groupmode, wiki_mode $wikimode, ?string $expectedpage): void {
|
||||
$this->resetAfterTest();
|
||||
['users' => $users, 'instance' => $instance, 'pages' => $pages] = $this->setup_users_and_activity($groupmode, $wikimode);
|
||||
$manager = manager::create_from_instance($instance);
|
||||
$this->setUser($users[$username]); // Set the user to the one who created the wiki.
|
||||
$pageid = $manager->get_main_wiki_pageid();
|
||||
$pagestoid = array_map(function($page) {
|
||||
return $page->id;
|
||||
}, $pages);
|
||||
$idtopage = array_flip($pagestoid);
|
||||
$this->assertEquals(
|
||||
$expectedpage,
|
||||
$idtopage[$pageid] ?? null,
|
||||
"Page id for user $username does not match expected page id."
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for test_get_wiki_pageid.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_main_wiki_pageid_data_provider(): array {
|
||||
return [
|
||||
'teacher 1 (no group mode)' => [
|
||||
'username' => 't1',
|
||||
'groupmode' => NOGROUPS,
|
||||
'wikimode' => wiki_mode::COLLABORATIVE,
|
||||
'expectedpage' => null,
|
||||
],
|
||||
'teacher 2 (no group mode)' => [
|
||||
'username' => 't2',
|
||||
'groupmode' => NOGROUPS,
|
||||
'wikimode' => wiki_mode::COLLABORATIVE,
|
||||
'expectedpage' => null,
|
||||
],
|
||||
'student1 (no group mode, collaborative)' => [
|
||||
'username' => 's1',
|
||||
'groupmode' => NOGROUPS,
|
||||
'wikimode' => wiki_mode::COLLABORATIVE,
|
||||
'expectedpage' => null,
|
||||
],
|
||||
'student1 (no group mode, no wiki mode)' => [
|
||||
'username' => 's1',
|
||||
'groupmode' => SEPARATEGROUPS,
|
||||
'wikimode' => wiki_mode::UNDEFINED,
|
||||
'expectedpage' => 's1group-0001', // This is the first page created for all users (userid = 0).
|
||||
],
|
||||
'teacher 1 (separate group mode)' => [
|
||||
'username' => 't1',
|
||||
'groupmode' => SEPARATEGROUPS,
|
||||
'wikimode' => wiki_mode::COLLABORATIVE,
|
||||
'expectedpage' => "s1group-0001",
|
||||
],
|
||||
'teacher 2 (separate group mode)' => [
|
||||
'username' => 't2',
|
||||
'groupmode' => SEPARATEGROUPS,
|
||||
'wikimode' => wiki_mode::COLLABORATIVE,
|
||||
'expectedpage' => null,
|
||||
],
|
||||
'student 1 (separate group mode)' => [
|
||||
'username' => 's1',
|
||||
'groupmode' => SEPARATEGROUPS,
|
||||
'wikimode' => wiki_mode::COLLABORATIVE,
|
||||
'expectedpage' => "s1group-0001",
|
||||
],
|
||||
'student 1 (separate group mode, no wiki mode)' => [
|
||||
'username' => 's1',
|
||||
'groupmode' => SEPARATEGROUPS,
|
||||
'wikimode' => wiki_mode::UNDEFINED,
|
||||
'expectedpage' => "s1group-0001",
|
||||
],
|
||||
'teacher 1 (visible group mode)' => [
|
||||
'username' => 't1',
|
||||
'groupmode' => VISIBLEGROUPS,
|
||||
'wikimode' => wiki_mode::COLLABORATIVE,
|
||||
'expectedpage' => "s1group-0001",
|
||||
],
|
||||
'teacher 2 (visible group mode)' => [
|
||||
'username' => 't2',
|
||||
'groupmode' => VISIBLEGROUPS,
|
||||
'wikimode' => wiki_mode::COLLABORATIVE,
|
||||
'expectedpage' => "s1group-0001",
|
||||
],
|
||||
'student 1 (visible group mode)' => [
|
||||
'username' => 's1',
|
||||
'groupmode' => VISIBLEGROUPS,
|
||||
'wikimode' => wiki_mode::COLLABORATIVE,
|
||||
'expectedpage' => "s1group-0001",
|
||||
],
|
||||
'student 1 (visible group mode, no wiki mode)' => [
|
||||
'username' => 's1',
|
||||
'groupmode' => VISIBLEGROUPS,
|
||||
'wikimode' => wiki_mode::UNDEFINED,
|
||||
'expectedpage' => "s1group-0001",
|
||||
],
|
||||
'teacher 1 (no group mode) - individual' => [
|
||||
'username' => 't1',
|
||||
'groupmode' => VISIBLEGROUPS,
|
||||
'wikimode' => wiki_mode::INDIVIDUAL,
|
||||
'expectedpage' => null,
|
||||
],
|
||||
'teacher 1 (separate group mode) - individual' => [
|
||||
'username' => 't1',
|
||||
'groupmode' => VISIBLEGROUPS,
|
||||
'wikimode' => wiki_mode::INDIVIDUAL,
|
||||
'expectedpage' => null,
|
||||
],
|
||||
'teacher 1 (visible group mode) - individual' => [
|
||||
'username' => 't1',
|
||||
'groupmode' => VISIBLEGROUPS,
|
||||
'wikimode' => wiki_mode::INDIVIDUAL,
|
||||
'expectedpage' => null,
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user