first commit

This commit is contained in:
CHIEFSOFT\ameye
2024-09-30 18:11:26 -04:00
commit e592ca6823
27270 changed files with 5002257 additions and 0 deletions
+100
View File
@@ -0,0 +1,100 @@
<?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 core_my\external;
use core_external\external_api;
use core_external\external_function_parameters;
use core_external\external_single_structure;
use core_external\external_value;
use core_external\external_warnings;
/**
* External service to log viewed Dashboard and My pages.
*
* This is mainly used by the mobile application.
*
* @package core_my
* @category external
* @copyright 2023 Rodrigo Mady <rodrigo.mady@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @since Moodle 4.3
*/
class view_page extends external_api {
/**
* Returns description of method parameters
*
* @return external_function_parameters
*/
public static function execute_parameters(): external_function_parameters {
return new external_function_parameters([
'page' => new external_value(PARAM_TEXT, 'My page to trigger a view event'),
]);
}
/**
* Execute the My or Dashboard view event.
*
* @param string $page the page for trigger the event.
* @return array
*/
public static function execute(string $page): array {
$warnings = [];
$status = true;
// Validate the cmid ID.
['page' => $page] = self::validate_parameters(
self::execute_parameters(), ['page' => $page]
);
if ($page === 'my') {
$eventname = '\core\event\mycourses_viewed';
} else if ($page === 'dashboard') {
$eventname = '\core\event\dashboard_viewed';
} else {
$status = false;
$warnings[] = [
'item' => $page,
'warningcode' => 'invalidmypage',
'message' => 'The value for the page request is invalid!'
];
}
// Trigger my/dashboard view event.
$context = \context_system::instance();
self::validate_context($context);
if ($status) {
$event = $eventname::create(['context' => $context]);
$event->trigger();
}
$result = [
'status' => $status,
'warnings' => $warnings
];
return $result;
}
/**
* Describe the return structure of the external service.
*
* @return external_single_structure
*/
public static function execute_returns(): external_single_structure {
return new external_single_structure([
'status' => new external_value(PARAM_BOOL, 'status: true if success'),
'warnings' => new external_warnings(),
]);
}
}
+76
View File
@@ -0,0 +1,76 @@
<?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/>.
/**
* Privacy Subsystem implementation for core_my.
*
* @package core_my
* @copyright 2018 Zig Tan <zig@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_my\privacy;
use core_privacy\local\metadata\collection;
use core_privacy\local\request\approved_contextlist;
use core_privacy\local\request\context;
use core_privacy\local\request\contextlist;
use core_privacy\local\request\writer;
defined('MOODLE_INTERNAL') || die();
/**
* Privacy Subsystem for core_my implementing metadata, plugin, and user_preference providers.
*
* @copyright 2018 Zig Tan <zig@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class provider implements
\core_privacy\local\metadata\provider,
\core_privacy\local\request\user_preference_provider {
/**
* Returns meta data about this system.
*
* @param collection $collection The initialised collection to add items to.
* @return collection A listing of user data stored through this system.
*/
public static function get_metadata(collection $collection): collection {
$collection->add_user_preference(
'user_home_page_preference',
'privacy:metadata:core_my:preference:user_home_page_preference'
);
return $collection;
}
/**
* Export all user preferences for the plugin.
*
* @param int $userid The userid of the user whose data is to be exported.
*/
public static function export_user_preferences(int $userid) {
$userhomepagepreference = get_user_preferences('user_home_page_preference', null, $userid);
if (null !== $userhomepagepreference) {
writer::export_user_preference(
'core_my',
'user_home_page_preference',
$userhomepagepreference,
get_string('privacy:metadata:core_my:preference:user_home_page_preference', 'core_my')
);
}
}
}
+107
View File
@@ -0,0 +1,107 @@
<?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/>.
/**
* My Courses.
*
* - each user can currently have their own page (cloned from system and then customised)
* - only the user can see their own dashboard
* - users can add any blocks they want
*
* @package core
* @subpackage my
* @copyright 2021 Mathew May <mathew.solutions>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once(__DIR__ . '/../config.php');
require_once($CFG->dirroot . '/my/lib.php');
require_once($CFG->dirroot . '/course/lib.php');
redirect_if_major_upgrade_required();
require_login();
$hassiteconfig = has_capability('moodle/site:config', context_system::instance());
if ($hassiteconfig && moodle_needs_upgrading()) {
redirect(new moodle_url('/admin/index.php'));
}
$context = context_system::instance();
// Get the My Moodle page info. Should always return something unless the database is broken.
if (!$currentpage = my_get_page(null, MY_PAGE_PUBLIC, MY_PAGE_COURSES)) {
throw new Exception('mymoodlesetup');
}
// Start setting up the page.
$PAGE->set_context($context);
$PAGE->set_url('/my/courses.php');
$PAGE->add_body_classes(['limitedwidth', 'page-mycourses']);
$PAGE->set_pagelayout('mycourses');
$PAGE->set_pagetype('my-index');
$PAGE->blocks->add_region('content');
$PAGE->set_subpage($currentpage->id);
$PAGE->set_title(get_string('mycourses'));
$PAGE->set_heading(get_string('mycourses'));
// No blocks can be edited on this page (including by managers/admins) because:
// - Course overview is a fixed item on the page and cannot be moved/removed.
// - We do not want new blocks on the page.
// - Only global blocks (if any) should be visible on the site panel, and cannot be moved int othe centre pane.
$PAGE->force_lock_all_blocks();
// Force the add block out of the default area.
$PAGE->theme->addblockposition = BLOCK_ADDBLOCK_POSITION_CUSTOM;
// Add course management if the user has the capabilities for it.
$coursecat = core_course_category::user_top();
$coursemanagemenu = [];
if ($coursecat && ($category = core_course_category::get_nearest_editable_subcategory($coursecat, ['create']))) {
// The user has the capability to create course.
$coursemanagemenu['newcourseurl'] = new moodle_url('/course/edit.php', ['category' => $category->id]);
}
if ($coursecat && ($category = core_course_category::get_nearest_editable_subcategory($coursecat, ['manage']))) {
// The user has the capability to manage the course category.
$coursemanagemenu['manageurl'] = new moodle_url('/course/management.php', ['categoryid' => $category->id]);
}
if ($coursecat) {
$category = core_course_category::get_nearest_editable_subcategory($coursecat, ['moodle/course:request']);
if ($category && $category->can_request_course()) {
$coursemanagemenu['courserequesturl'] = new moodle_url('/course/request.php', ['categoryid' => $category->id]);
}
}
if (!empty($coursemanagemenu)) {
// Render the course management menu.
$PAGE->add_header_action($OUTPUT->render_from_template('my/dropdown', $coursemanagemenu));
}
echo $OUTPUT->header();
if (core_userfeedback::should_display_reminder()) {
core_userfeedback::print_reminder_block();
}
echo $OUTPUT->custom_block_region('content');
echo $OUTPUT->footer();
// Trigger dashboard has been viewed event.
$eventparams = array('context' => $context);
$event = \core\event\mycourses_viewed::create($eventparams);
$event->trigger();
+194
View File
@@ -0,0 +1,194 @@
<?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/>.
/**
* My Moodle -- a user's personal dashboard
*
* - each user can currently have their own page (cloned from system and then customised)
* - only the user can see their own dashboard
* - users can add any blocks they want
* - the administrators can define a default site dashboard for users who have
* not created their own dashboard
*
* This script implements the user's view of the dashboard, and allows editing
* of the dashboard.
*
* @package moodlecore
* @subpackage my
* @copyright 2010 Remote-Learner.net
* @author Hubert Chathi <hubert@remote-learner.net>
* @author Olav Jordan <olav.jordan@remote-learner.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once(__DIR__ . '/../config.php');
require_once($CFG->dirroot . '/my/lib.php');
redirect_if_major_upgrade_required();
// TODO Add sesskey check to edit
$edit = optional_param('edit', null, PARAM_BOOL); // Turn editing on and off
$reset = optional_param('reset', null, PARAM_BOOL);
require_login();
$hassiteconfig = has_capability('moodle/site:config', context_system::instance());
if ($hassiteconfig && moodle_needs_upgrading()) {
redirect(new moodle_url('/admin/index.php'));
}
$strmymoodle = get_string('myhome');
if (empty($CFG->enabledashboard)) {
// Dashboard is disabled, so the /my page shouldn't be displayed.
$defaultpage = get_default_home_page();
if ($defaultpage == HOMEPAGE_MYCOURSES) {
// If default page is set to "My courses", redirect to it.
redirect(new moodle_url('/my/courses.php'));
} else {
// Otherwise, raise an exception to inform the dashboard is disabled.
throw new moodle_exception('error:dashboardisdisabled', 'my');
}
}
if (isguestuser()) { // Force them to see system default, no editing allowed
// If guests are not allowed my moodle, send them to front page.
if (empty($CFG->allowguestmymoodle)) {
redirect(new moodle_url('/', array('redirect' => 0)));
}
$userid = null;
$USER->editing = $edit = 0; // Just in case
$context = context_system::instance();
$PAGE->set_blocks_editing_capability('moodle/my:configsyspages'); // unlikely :)
$strguest = get_string('guest');
$pagetitle = "$strmymoodle ($strguest)";
} else { // We are trying to view or edit our own My Moodle page
$userid = $USER->id; // Owner of the page
$context = context_user::instance($USER->id);
$PAGE->set_blocks_editing_capability('moodle/my:manageblocks');
$pagetitle = $strmymoodle;
}
// Get the My Moodle page info. Should always return something unless the database is broken.
if (!$currentpage = my_get_page($userid, MY_PAGE_PRIVATE)) {
throw new \moodle_exception('mymoodlesetup');
}
// Start setting up the page
$params = array();
$PAGE->set_context($context);
$PAGE->set_url('/my/index.php', $params);
$PAGE->set_pagelayout('mydashboard');
$PAGE->add_body_class('limitedwidth');
$PAGE->set_pagetype('my-index');
$PAGE->blocks->add_region('content');
$PAGE->set_subpage($currentpage->id);
$PAGE->set_title($pagetitle);
$PAGE->set_heading($pagetitle);
if (!isguestuser()) { // Skip default home page for guests
if (get_home_page() != HOMEPAGE_MY) {
if (optional_param('setdefaulthome', false, PARAM_BOOL)) {
set_user_preference('user_home_page_preference', HOMEPAGE_MY);
} else if (!empty($CFG->defaulthomepage) && $CFG->defaulthomepage == HOMEPAGE_USER) {
$frontpagenode = $PAGE->settingsnav->add(get_string('frontpagesettings'), null, navigation_node::TYPE_SETTING, null);
$frontpagenode->force_open();
$frontpagenode->add(get_string('makethismyhome'), new moodle_url('/my/', array('setdefaulthome' => true)),
navigation_node::TYPE_SETTING);
}
}
}
// Toggle the editing state and switches
if (empty($CFG->forcedefaultmymoodle) && $PAGE->user_allowed_editing()) {
if ($reset !== null) {
if (!is_null($userid)) {
require_sesskey();
if (!$currentpage = my_reset_page($userid, MY_PAGE_PRIVATE)) {
throw new \moodle_exception('reseterror', 'my');
}
redirect(new moodle_url('/my'));
}
} else if ($edit !== null) { // Editing state was specified
$USER->editing = $edit; // Change editing state
} else { // Editing state is in session
if ($currentpage->userid) { // It's a page we can edit, so load from session
if (!empty($USER->editing)) {
$edit = 1;
} else {
$edit = 0;
}
} else {
// For the page to display properly with the user context header the page blocks need to
// be copied over to the user context.
if (!$currentpage = my_copy_page($USER->id, MY_PAGE_PRIVATE)) {
throw new \moodle_exception('mymoodlesetup');
}
$context = context_user::instance($USER->id);
$PAGE->set_context($context);
$PAGE->set_subpage($currentpage->id);
// It's a system page and they are not allowed to edit system pages
$USER->editing = $edit = 0; // Disable editing completely, just to be safe
}
}
// Add button for editing page
$params = array('edit' => !$edit);
$resetbutton = '';
$resetstring = get_string('resetpage', 'my');
$reseturl = new moodle_url("$CFG->wwwroot/my/index.php", array('edit' => 1, 'reset' => 1));
if (!$currentpage->userid) {
// viewing a system page -- let the user customise it
$editstring = get_string('updatemymoodleon');
$params['edit'] = 1;
} else if (empty($edit)) {
$editstring = get_string('updatemymoodleon');
} else {
$editstring = get_string('updatemymoodleoff');
$resetbutton = $OUTPUT->single_button($reseturl, $resetstring);
}
$url = new moodle_url("$CFG->wwwroot/my/index.php", $params);
$button = '';
if (!$PAGE->theme->haseditswitch) {
$button = $OUTPUT->single_button($url, $editstring);
}
$PAGE->set_button($resetbutton . $button);
} else {
$USER->editing = $edit = 0;
}
echo $OUTPUT->header();
if (core_userfeedback::should_display_reminder()) {
core_userfeedback::print_reminder_block();
}
echo $OUTPUT->addblockbutton('content');
echo $OUTPUT->custom_block_region('content');
echo $OUTPUT->footer();
// Trigger dashboard has been viewed event.
$eventparams = array('context' => $context);
$event = \core\event\dashboard_viewed::create($eventparams);
$event->trigger();
+95
View File
@@ -0,0 +1,95 @@
<?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/>.
/**
* My Moodle -- a user's personal dashboard
*
* - each user can currently have their own page (cloned from system and then customised)
* - only the user can see their own dashboard
* - users can add any blocks they want
* - the administrators can define a default site dashboard for users who have
* not created their own dashboard
*
* This script implements the user's view of the dashboard, and allows editing
* of the dashboard.
*
* @package moodlecore
* @subpackage my
* @copyright 2010 Remote-Learner.net
* @author Hubert Chathi <hubert@remote-learner.net>
* @author Olav Jordan <olav.jordan@remote-learner.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
define('NO_OUTPUT_BUFFERING', true);
require_once(__DIR__ . '/../config.php');
require_once($CFG->dirroot . '/my/lib.php');
require_once($CFG->libdir.'/adminlib.php');
redirect_if_major_upgrade_required();
$resetall = optional_param('resetall', false, PARAM_BOOL);
$pagetitle = get_string('mypage', 'admin');
$PAGE->set_secondary_active_tab('appearance');
$PAGE->set_blocks_editing_capability('moodle/my:configsyspages');
$PAGE->set_url(new moodle_url('/my/indexsys.php'));
admin_externalpage_setup('mypage', '', null, '', ['pagelayout' => 'mydashboard', 'nosearch' => true]);
$PAGE->add_body_class('limitedwidth');
$PAGE->set_pagetype('my-index');
$PAGE->blocks->add_region('content');
$PAGE->set_title($pagetitle);
$PAGE->set_heading($pagetitle);
$PAGE->set_secondary_navigation(false);
$PAGE->set_primary_active_tab('myhome');
// If we are resetting all, just output a progress bar.
if ($resetall && confirm_sesskey()) {
echo $OUTPUT->header($pagetitle);
echo $OUTPUT->heading(get_string('resettingdashboards', 'my'), 3);
$progressbar = new progress_bar();
$progressbar->create();
\core\session\manager::write_close();
my_reset_page_for_all_users(MY_PAGE_PRIVATE, 'my-index', $progressbar);
core\notification::success(get_string('alldashboardswerereset', 'my'));
echo $OUTPUT->continue_button($PAGE->url);
echo $OUTPUT->footer();
die();
}
// Get the My Moodle page info. Should always return something unless the database is broken.
if (!$currentpage = my_get_page(null, MY_PAGE_PRIVATE)) {
throw new \moodle_exception('mymoodlesetup');
}
$PAGE->set_subpage($currentpage->id);
// Display a button to reset everyone's dashboard.
$url = $PAGE->url;
$url->params(['resetall' => true, 'sesskey' => sesskey()]);
$button = $OUTPUT->single_button($url, get_string('reseteveryonesdashboard', 'my'));
$PAGE->set_button($button . $PAGE->button);
echo $OUTPUT->header();
echo $OUTPUT->addblockbutton('content');
echo $OUTPUT->custom_block_region('content');
echo $OUTPUT->footer();
+333
View File
@@ -0,0 +1,333 @@
<?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/>.
/**
* My Moodle -- a user's personal dashboard
*
* This file contains common functions for the dashboard and profile pages.
*
* @package moodlecore
* @subpackage my
* @copyright 2010 Remote-Learner.net
* @author Hubert Chathi <hubert@remote-learner.net>
* @author Olav Jordan <olav.jordan@remote-learner.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
define('MY_PAGE_PUBLIC', 0);
define('MY_PAGE_PRIVATE', 1);
define('MY_PAGE_DEFAULT', '__default');
define('MY_PAGE_COURSES', '__courses');
require_once("$CFG->libdir/blocklib.php");
/**
* For a given user, this returns the $page information for their My Moodle page
*
* @param int|null $userid the id of the user whose page should be retrieved
* @param int|null $private either MY_PAGE_PRIVATE or MY_PAGE_PUBLIC
* @param string|null $pagename Differentiate between standard /my or /courses pages.
*/
function my_get_page(?int $userid, int $private = MY_PAGE_PRIVATE, string $pagename = MY_PAGE_DEFAULT) {
global $DB, $CFG;
if (empty($CFG->forcedefaultmymoodle) && $userid) { // Ignore custom My Moodle pages if admin has forced them
// Does the user have their own page defined? If so, return it.
if ($customised = $DB->get_record(
'my_pages',
array('userid' => $userid, 'private' => $private, 'name' => $pagename),
'*',
IGNORE_MULTIPLE
)) {
return $customised;
}
}
// Otherwise return the system default page
return $DB->get_record('my_pages', array('userid' => null, 'name' => $pagename, 'private' => $private), '*', IGNORE_MULTIPLE);
}
/**
* This copies a system default page to the current user
*
* @param int $userid the id of the user whose page should be reset
* @param int $private either MY_PAGE_PRIVATE or MY_PAGE_PUBLIC
* @param string $pagetype either my-index or user-profile
* @param string $pagename Differentiate between standard /my or /courses pages.
*/
function my_copy_page(
int $userid,
int $private = MY_PAGE_PRIVATE,
string $pagetype = 'my-index',
string $pagename = MY_PAGE_DEFAULT
) {
global $DB;
if ($customised = $DB->get_record(
'my_pages',
array('userid' => $userid, 'name' => $pagename, 'private' => $private),
'*',
IGNORE_MULTIPLE
)) {
return $customised; // We're done!
}
// Get the system default page
if (!$systempage = $DB->get_record(
'my_pages',
array('userid' => null, 'name' => $pagename, 'private' => $private),
'*',
IGNORE_MULTIPLE
)) {
return false; // error
}
// Clone the basic system page record
$page = clone($systempage);
unset($page->id);
$page->userid = $userid;
$page->id = $DB->insert_record('my_pages', $page);
// Clone ALL the associated blocks as well
$systemcontext = context_system::instance();
$usercontext = context_user::instance($userid);
$blockinstances = $DB->get_records('block_instances', array('parentcontextid' => $systemcontext->id,
'pagetypepattern' => $pagetype,
'subpagepattern' => $systempage->id));
$roles = get_all_roles();
$newblockinstanceids = [];
foreach ($blockinstances as $instance) {
$originalid = $instance->id;
$originalcontext = context_block::instance($originalid);
unset($instance->id);
$instance->parentcontextid = $usercontext->id;
$instance->subpagepattern = $page->id;
$instance->timecreated = time();
$instance->timemodified = $instance->timecreated;
$instance->id = $DB->insert_record('block_instances', $instance);
$newblockinstanceids[$originalid] = $instance->id;
$blockcontext = context_block::instance($instance->id); // Just creates the context record
$block = block_instance($instance->blockname, $instance);
if (empty($block) || !$block->instance_copy($originalid)) {
debugging("Unable to copy block-specific data for original block
instance: $originalid to new block instance: $instance->id for
block: $instance->blockname", DEBUG_DEVELOPER);
}
// Check if there are any overrides on this block instance.
// We check against all roles, not just roles assigned to the user.
// This is so any overrides that are applied to the system default page
// will be applied to the user's page as well, even if their role assignment changes in the future.
foreach ($roles as $role) {
$rolecapabilities = get_capabilities_from_role_on_context($role, $originalcontext);
// If there are overrides, then apply them to the new block instance.
foreach ($rolecapabilities as $rolecapability) {
role_change_permission(
$rolecapability->roleid,
$blockcontext,
$rolecapability->capability,
$rolecapability->permission
);
}
}
}
// Clone block position overrides.
if ($blockpositions = $DB->get_records('block_positions',
['subpage' => $systempage->id, 'pagetype' => $pagetype, 'contextid' => $systemcontext->id])) {
foreach ($blockpositions as &$positions) {
$positions->subpage = $page->id;
$positions->contextid = $usercontext->id;
if (array_key_exists($positions->blockinstanceid, $newblockinstanceids)) {
// For block instances that were defined on the default dashboard and copied to the user dashboard
// use the new blockinstanceid.
$positions->blockinstanceid = $newblockinstanceids[$positions->blockinstanceid];
}
unset($positions->id);
}
$DB->insert_records('block_positions', $blockpositions);
}
return $page;
}
/**
* For a given user, this deletes their My Moodle page and returns them to the system default.
*
* @param int $userid the id of the user whose page should be reset
* @param int $private either MY_PAGE_PRIVATE or MY_PAGE_PUBLIC
* @param string $pagetype either my-index or user-profile
* @param string $pagename Differentiate between standard /my or /courses pages.
* @return mixed system page, or false on error
*/
function my_reset_page(
int $userid,
int $private = MY_PAGE_PRIVATE,
string $pagetype='my-index',
string $pagename = MY_PAGE_DEFAULT
) {
global $DB, $CFG;
$page = my_get_page($userid, $private, $pagename);
if ($page->userid == $userid) {
$context = context_user::instance($userid);
if ($blocks = $DB->get_records('block_instances', array('parentcontextid' => $context->id,
'pagetypepattern' => $pagetype))) {
foreach ($blocks as $block) {
if (is_null($block->subpagepattern) || $block->subpagepattern == $page->id) {
blocks_delete_instance($block);
}
}
}
$DB->delete_records('block_positions', ['subpage' => $page->id, 'pagetype' => $pagetype, 'contextid' => $context->id]);
$DB->delete_records('my_pages', array('id' => $page->id, 'name' => $pagename));
}
// Get the system default page
if (!$systempage = $DB->get_record(
'my_pages',
array('userid' => null, 'name' => $pagename, 'private' => $private),
'*',
IGNORE_MULTIPLE
)) {
return false; // error
}
// Trigger dashboard has been reset event.
$eventparams = array(
'context' => context_user::instance($userid),
'other' => array(
'private' => $private,
'pagetype' => $pagetype,
),
);
$event = \core\event\dashboard_reset::create($eventparams);
$event->trigger();
return $systempage;
}
/**
* Resets the page customisations for all users.
*
* @param int $private Either MY_PAGE_PRIVATE or MY_PAGE_PUBLIC.
* @param string $pagetype Either my-index or user-profile.
* @param progress_bar|null $progressbar A progress bar to update.
* @param string $pagename Differentiate between standard /my or /courses pages.
* @return void
*/
function my_reset_page_for_all_users(
int $private = MY_PAGE_PRIVATE,
string $pagetype = 'my-index',
?progress_bar $progressbar = null,
string $pagename = MY_PAGE_DEFAULT
) {
global $DB;
// This may take a while. Raise the execution time limit.
core_php_time_limit::raise();
$users = $DB->get_fieldset_select(
'my_pages',
'DISTINCT(userid)',
'userid IS NOT NULL AND private = :private',
['private' => $private]
);
$chunks = array_chunk($users, 20);
if (!empty($progressbar) && count($chunks) > 0) {
$count = count($chunks);
$message = get_string('inprogress');
$progressbar->update(0, $count, $message);
}
foreach ($chunks as $key => $userchunk) {
list($infragment, $inparams) = $DB->get_in_or_equal($userchunk, SQL_PARAMS_NAMED);
// Find all the user pages and all block instances in them.
$sql = "SELECT bi.id
FROM {my_pages} p
JOIN {context} ctx ON ctx.instanceid = p.userid AND ctx.contextlevel = :usercontextlevel
JOIN {block_instances} bi ON bi.parentcontextid = ctx.id
AND bi.pagetypepattern = :pagetypepattern
AND (bi.subpagepattern IS NULL OR bi.subpagepattern = " . $DB->sql_cast_to_char('p.id') . ")
WHERE p.private = :private
AND p.name = :name
AND p.userid $infragment";
$params = array_merge([
'private' => $private,
'usercontextlevel' => CONTEXT_USER,
'pagetypepattern' => $pagetype,
'name' => $pagename
], $inparams);
$blockids = $DB->get_fieldset_sql($sql, $params);
// Wrap the SQL queries in a transaction.
$transaction = $DB->start_delegated_transaction();
// Delete the block instances.
if (!empty($blockids)) {
blocks_delete_instances($blockids);
}
// Finally delete the pages.
$DB->delete_records_select(
'my_pages',
"userid $infragment AND private = :private",
array_merge(['private' => $private], $inparams)
);
// We should be good to go now.
$transaction->allow_commit();
if (!empty($progressbar)) {
$progressbar->update(((int) $key + 1), $count, $message);
}
}
// Trigger dashboard has been reset event.
$eventparams = array(
'context' => context_system::instance(),
'other' => array(
'private' => $private,
'pagetype' => $pagetype,
),
);
$event = \core\event\dashboards_reset::create($eventparams);
$event->trigger();
if (!empty($progressbar)) {
$progressbar->update(1, 1, get_string('completed'));
}
}
class my_syspage_block_manager extends block_manager {
// HACK WARNING!
// TODO: figure out a better way to do this
/**
* Load blocks using the system context, rather than the user's context.
*
* This is needed because the My Moodle pages set the page context to the
* user's context for access control, etc. But the blocks for the system
* pages are stored in the system context.
*/
public function load_blocks($includeinvisible = null) {
$origcontext = $this->page->context;
$this->page->context = context_system::instance();
parent::load_blocks($includeinvisible);
$this->page->context = $origcontext;
}
}
+45
View File
@@ -0,0 +1,45 @@
{{!
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/>.
}}
{{!
@template my/dropdown
Simple dropdown for the my/courses page
Example context (json):
{
"newcourseurl": "https://moodle.test/course/edit.php?category=1",
"manageurl": "https://moodle.test/course/management.php?categoryid=1",
"courserequesturl": "https://moodle.test/course/request.php?categoryid=1"
}
}}
<div class="btn-group{{#manageurl}} course-manage{{/manageurl}}{{#courserequesturl}} course-request{{/courserequesturl}}">
<!-- Set as a link to appease BrowserKit behat. -->
<a href="#" class="btn btn-link btn-icon icon-size-3 rounded-circle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" title="{{#str}}coursemanagementoptions, my{{/str}}">
<i class="fa fa-ellipsis-v text-dark py-2" aria-hidden="true"></i>
</a>
<div class="dropdown-menu dropdown-menu-right">
{{#newcourseurl}}
<a class="dropdown-item" href="{{newcourseurl}}">{{#str}}newcourse, core{{/str}}</a>
{{/newcourseurl}}
{{#manageurl}}
<a class="dropdown-item" href="{{manageurl}}">{{#str}}managecourses, core{{/str}}</a>
{{/manageurl}}
{{#courserequesturl}}
<a class="dropdown-item" href="{{courserequesturl}}">{{#str}}requestcourse, core{{/str}}</a>
{{/courserequesturl}}
</div>
</div>
+28
View File
@@ -0,0 +1,28 @@
@core @core_my
Feature: Add blocks to dashboard page
In order to add more functionality to dashboard page
As a user
I need to add blocks to dashboard page
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| student1 | Student | 1 | student1@example.com |
| student2 | Student | 2 | student2@example.com |
And the following "courses" exist:
| fullname | shortname | format |
| Course 1 | C1 | topics |
And the following "course enrolments" exist:
| user | course | role |
| student1 | C1 | student |
| student2 | C1 | student |
And I log in as "student1"
Scenario: Add blocks to page
When I turn editing mode on
And I add the "Latest announcements" block
And I turn editing mode off
Then I should see "Latest announcements" in the "Latest announcements" "block"
And I should see "Timeline" in the "Timeline" "block"
And I should see "Calendar" in the "Calendar" "block"
And I should not see "Upcoming events"
+141
View File
@@ -0,0 +1,141 @@
@core @core_my
Feature: Run tests over my courses.
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| user1 | User | 1 | user1@example.com |
And the following "categories" exist:
| name | category | idnumber |
| CatA | 0 | cata |
And the following "roles" exist:
| shortname | name | archetype |
| role1 | Role 1 | |
And the following "system role assigns" exist:
| user | role | contextlevel | reference |
| user1 | role1 | Category | CatA |
Scenario: Admin can add new courses or manage them from my courses
Given I am on the "My courses" page logged in as "admin"
And I click on "Course management options" "link"
And I click on "New course" "link"
And I wait to be redirected
Then I should see "Add a new course"
And I am on the "My courses" page
And I click on "Course management options" "link"
And I click on "Manage courses" "link"
And I should see "Manage course categories and courses"
Scenario: User without creating a course and managing category permissions cannot see any link
Given I am on the "My courses" page logged in as "user1"
Then "Course management options" "link" should not exist
Scenario: User without capability to browse courses cannot see any link
Given the following "permission overrides" exist:
| capability | permission | role | contextlevel | reference |
| moodle/category:viewcourselist | Prevent | user | System | |
Given I am on the "My courses" page logged in as "user1"
Then "Course management options" "link" should not exist
@javascript
Scenario: User with creating a course permission can see the Create course link only
Given the following "permission overrides" exist:
| capability | permission | role | contextlevel | reference |
| moodle/course:create | Allow | role1 | Category | cata |
When I am on the "My courses" page logged in as "user1"
Then "Course management options" "link" should exist
And I click on "Course management options" "link"
And I should see "New course"
And I should not see "Manage courses"
And I click on "New course" "link"
And I wait to be redirected
And I should see "Add a new course"
And "CatA" "autocomplete_selection" should exist
@javascript
Scenario: User with managing a category permission can see the Manage course link only
Given the following "permission overrides" exist:
| capability | permission | role | contextlevel | reference |
| moodle/category:manage | Allow | role1 | Category | cata |
When I am on the "My courses" page logged in as "user1"
Then "Course management options" "link" should exist
And I click on "Course management options" "link"
And I should not see "New course"
And I should see "Manage courses"
And I click on "Manage courses" "link"
And I wait to be redirected
And I should see "Manage course categories and courses"
@javascript
Scenario: User with both creating a course and managing a category permission can see both links
Given the following "permission overrides" exist:
| capability | permission | role | contextlevel | reference |
| moodle/course:create | Allow | role1 | Category | cata |
| moodle/category:manage | Allow | role1 | Category | cata |
When I am on the "My courses" page logged in as "user1"
Then "Course management options" "link" should exist
And I click on "Course management options" "link"
And I should see "New course"
And I should see "Manage courses"
And I click on "New course" "link"
And I wait to be redirected
And I should see "Add a new course"
And "CatA" "autocomplete_selection" should exist
And I am on the "My courses" page
And I click on "Course management options" "link"
And I click on "Manage courses" "link"
And I wait to be redirected
And I should see "Manage course categories and courses"
@javascript
Scenario: Admin can see relevant blocks but not add or move them
Given I log in as "admin"
And I am on site homepage
And I turn editing mode on
And I add the "Text" block to the default region with:
| Text block title | Text on all pages |
| Content | This is visible on all pages |
And I configure the "Text on all pages" block
And I set the following fields to these values:
| Page contexts | Display throughout the entire site |
| Default region | Right |
And I click on "Save changes" "button" in the "Configure Text on all pages block" "dialogue"
And I should see "This is visible on all pages"
And "Move Text on all pages block" "menuitem" should exist in the "Text on all pages" "block"
When I am on the "My courses" page
# Check blocks visible but are "locked" in place.
Then "Course overview" "text" should exist in the "region-main" "region"
And I should not see "Add a block"
And I should see "This is visible on all pages"
And "Move Text on all pages block" "menuitem" should not exist in the "Text on all pages" "block"
And "Move Course overview block" "menuitem" should not exist in the "Course overview" "block"
And I click on "Actions menu" "icon" in the "Course overview" "block"
And I should not see "Delete Course overview block"
@javascript
Scenario: User with creating a course permission can't see the Request course link
Given the following "permission overrides" exist:
| capability | permission | role | contextlevel | reference |
| moodle/course:request | Allow | user | System | |
When I am on the "My courses" page logged in as "admin"
And I click on "Course management options" "link"
And I should see "New course"
Then I should not see "Request a course"
@javascript
Scenario: User without creating a course but with course request permission could see the Request course link
Given the following "permission overrides" exist:
| capability | permission | role | contextlevel | reference |
| moodle/course:request | Allow | user | System | |
When I am on the "My courses" page logged in as "user1"
And I click on "Course management options" "link"
And I should not see "New course"
Then I should see "Request a course"
And the following config values are set as admin:
| enablecourserequests | 0 |
And I am on the "My courses" page logged in as "user1"
And "Course management options" "link" should not exist
Scenario: User without creating nor course request permission shouldn't see any Request course link
Given I am on the "My courses" page logged in as "user1"
Then "Course management options" "link" should not exist
@@ -0,0 +1,106 @@
@core @core_my @javascript
Feature: Navigate and use preferences page
In order to navigate through preferences page
As a user
I need to be able to use preferences page
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| student1 | Sam | Student | s1@example.com |
And the following "courses" exist:
| fullname | shortname | format |
| Course 1 | C1 | topics |
And the following "course enrolments" exist:
| user | course | role |
| student1 | C1 | student |
And I log in as "admin"
Scenario Outline: Navigating through user menu Preferences
When I follow "Preferences" in the user menu
# Click each link in the 'Preferences' page.
And I click on "<userprefpage>" "link" in the "#page-content" "css_element"
# Confirm that each redirected page has 'Preferences' in the breadcrumbs.
And "Users" "link" should not exist in the ".breadcrumb" "css_element"
Then "Preferences" "link" should exist in the ".breadcrumb" "css_element"
# Additional confirmation that breadcrumbs is correct.
And "<userprefpage>" "text" should exist in the ".breadcrumb" "css_element"
# Confirm that user name and profile picture are displayed in header section.
And I should see "Admin User" in the ".page-header-headings" "css_element"
And ".page-header-image" "css_element" should exist in the "#page-header" "css_element"
Examples:
| userprefpage |
| Edit profile |
| Change password |
| Preferred language |
| Forum preferences |
| Editor preferences |
| Calendar preferences |
| Content bank preferences |
| Message preferences |
| Notification preferences |
| Manage badges |
| Badge preferences |
| Backpack settings |
| This user's role assignments |
| Permissions |
| Check permissions |
| Blog preferences |
| External blogs |
| Register an external blog |
Scenario Outline: Navigating through course participant preferences
Given I am on "Course 1" course homepage
And I navigate to course participants
And I follow "Sam Student"
When I click on "Preferences" "link" in the "#region-main-box" "css_element"
Then I should see "Sam Student" in the ".page-header-headings" "css_element"
And ".page-header-image" "css_element" should exist in the "#page-header" "css_element"
# Click each link in the 'Preferences' page.
And I click on "<courseprefpage>" "link" in the "#page-content" "css_element"
# Confirm that each redirected page has 'Users/{user}/Preferences' in the breadcrumbs.
Then "Users" "link" should exist in the ".breadcrumb" "css_element"
And "Sam Student" "link" should exist in the ".breadcrumb" "css_element"
And "Preferences" "link" should exist in the ".breadcrumb" "css_element"
# Additional confirmation that breadcrumbs is correct.
And "<courseprefpage>" "text" should exist in the ".breadcrumb" "css_element"
# Confirm that user name and profile picture are displayed in header section.
And I should see "Sam Student" in the ".page-header-headings" "css_element"
And ".page-header-image" "css_element" should exist in the "#page-header" "css_element"
Examples:
| courseprefpage |
| Edit profile |
| Preferred language |
| Forum preferences |
| Editor preferences |
| Calendar preferences |
| Content bank preferences |
| Message preferences |
| Notification preferences |
| This user's role assignments |
| Permissions |
| Check permissions |
Scenario: Navigation with Event monitoring enabled
Given I navigate to "Reports > Event monitoring rules" in site administration
And I click on "Enable" "link"
And I press "Add a new rule"
And I set the following fields to these values:
| Rule name | Testing1 |
| Area to monitor | Subsystem (core) |
| Event | Allow role override |
And I press "Save changes"
When I follow "Preferences" in the user menu
# Confirm that Event monitoring is visible and clickable.
Then I should see "Miscellaneous"
And I follow "Event monitoring"
# Confirm that user can subscribe to new rule.
And "Subscribe to rule \"Testing1\"" "link" should exist
And I am on "Course 1" course homepage
And I navigate to course participants
And I follow "Sam Student"
And I click on "Preferences" "link" in the "#region-main-box" "css_element"
# Confirm that admin cannot change student's event monitor subscription.
And I should not see "Event monitoring"
+113
View File
@@ -0,0 +1,113 @@
@core @core_my
Feature: Reset all personalised pages to default
In order to reset everyone's personalised pages
As an admin
I need to press a button on the pages to customise the default pages
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| student1 | Student | 1 | student1@example.com |
| student2 | Student | 2 | student2@example.com |
| student3 | Student | 3 | student3@example.com |
And the following "role capability" exists:
| role | user |
| moodle/block:edit | allow |
| block/myprofile:addinstance | allow |
And the following "blocks" exist:
| blockname | contextlevel | reference | pagetypepattern | defaultregion |
| comments | User | student1 | my-index | side-pre |
| myprofile | User | student2 | user-profile | side-pre |
And I log in as "student1"
And I should see "Comments"
And I log out
And I log in as "student2"
And I follow "Profile" in the user menu
And I should see "Logged in user"
And I log out
And I log in as "student3"
And I should not see "Comments"
And I follow "Profile" in the user menu
And I should not see "Logged in user"
And I log out
Scenario: Reset Dashboard for all users
Given I log in as "admin"
And I navigate to "Appearance > Default Dashboard page" in site administration
And I turn editing mode on
And I add the "Latest announcements" block
And I open the "Timeline" blocks action menu
And I follow "Delete Timeline block"
And I press "Yes"
And I turn editing mode off
And I log out
And I log in as "student1"
And I should not see "Latest announcements"
And I should see "Timeline"
And I log out
And I log in as "student3"
And I should not see "Latest announcements"
And I should see "Timeline"
And I log out
And I log in as "admin"
And I navigate to "Appearance > Default Dashboard page" in site administration
When I press "Reset Dashboard for all users"
And I should see "All Dashboard pages have been reset to default."
And I log out
And I log in as "student1"
Then I should see "Latest announcements"
And I should not see "Comments"
And I should not see "Timeline"
And I log out
And I log in as "student3"
And I should see "Latest announcements"
And I should not see "Timeline"
And I log out
# Check that this did not affect the customised profiles.
And I am on the "student2" "user > profile" page logged in as student2
And I should see "Logged in user"
And I should not see "Latest announcements"
Scenario: Reset profile for all users
Given I log in as "admin"
And I navigate to "Appearance > Default profile page" in site administration
And I turn editing mode on
And I add the "Latest announcements" block
And I log out
And I am on the "student2" "user > profile" page logged in as student2
And I should not see "Latest announcements"
And I log out
And I am on the "student3" "user > profile" page logged in as student3
And I should not see "Latest announcements"
And I log out
And I log in as "admin"
And I navigate to "Appearance > Default profile page" in site administration
When I press "Reset profile for all users"
And I should see "All profile pages have been reset to default."
And I log out
And I am on the "student2" "user > profile" page logged in as student2
Then I should see "Latest announcements"
And I should not see "Logged in user"
And I log out
And I am on the "student3" "user > profile" page logged in as student3
And I should see "Latest announcements"
And I log out
# Check that this did not affect the customised dashboards.
And I log in as "student1"
And I should see "Comments"
And I should not see "Latest announcements"
+31
View File
@@ -0,0 +1,31 @@
@core @core_my
Feature: Reset dashboard page to default
In order to remove customisations from dashboard page
As a user
I need to reset dashboard page
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| student1 | Student | 1 | student1@example.com |
| student2 | Student | 2 | student2@example.com |
And the following "courses" exist:
| fullname | shortname | format |
| Course 1 | C1 | topics |
And the following "course enrolments" exist:
| user | course | role |
| student1 | C1 | student |
| student2 | C1 | student |
And I log in as "student1"
Scenario: Add blocks to page and reset
When I turn editing mode on
And I add the "Latest announcements" block
And I add the "Comments" block
And I press "Reset page to default"
Then I should not see "Latest announcements"
And I should see "Timeline"
And I should see "Calendar"
And I should not see "Upcoming events"
And I should not see "Comments"
And I should not see "Reset page to default"
@@ -0,0 +1,37 @@
@core @core_my
Feature: Restrict which blocks can be added to Dashboard
In order to restrict which blocks can be added
As a student I need to ensure I can add the blocks
As an admin I need to remove the capability to add a blocks
As a student I need to ensure I can't add the blocks any more
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| student1 | Student | 1 | student1@example.com |
And the following "courses" exist:
| fullname | shortname | format |
| Course 1 | C1 | topics |
And the following "course enrolments" exist:
| user | course | role |
| student1 | C1 | student |
Scenario: The comments block can be added to Dashboard by default
And I log in as "student1"
And I turn editing mode on
Then the add block selector should contain "Comments" block
And the add block selector should contain "Text" block
And the add block selector should contain "Tags" block
Scenario: Remove the ability to add the comments block to Dashboard
Given the following "role capability" exists:
| role | user |
| block/comments:myaddinstance | prohibit |
| block/course_list:myaddinstance | prohibit |
| block/html:myaddinstance | prohibit |
When I log in as "student1"
And I turn editing mode on
Then the add block selector should not contain "Comments" block
And the add block selector should not contain "Courses" block
And the add block selector should not contain "Text" block
And the add block selector should contain "Tags" block
+49
View File
@@ -0,0 +1,49 @@
@core @core_my
Feature: Welcome message
In order to welcome new or existing user
As a user
I will see welcome message when I log into moodle
Scenario: Log in and being redirected to course page
Given the following "users" exist:
| username | password | firstname | lastname | email |
| wf | test | Fei | Wang | fei@example.com |
And the following "courses" exist:
| fullname | shortname |
| Math 101 | M1O1 |
When I am on "Math 101" course homepage
And I should see "You are not logged in" in the "page-footer" "region"
And I set the field "Username" to "wf"
And I set the field "Password" to "test"
And I press "Log in"
And I should see "Math 101" in the "page-header" "region"
And I should not see "Welcome, Fei!" in the "page-header" "region"
And I follow "Dashboard"
Then I should see "Welcome, Fei!" in the "page-header" "region"
@javascript
Scenario: Log in and being redirected to default home page
When I log in as "admin"
And I should see "You are logged in as Admin User" in the "page-footer" "region"
And I should see "Welcome, Admin!" in the "page-header" "region"
And I log out
And I should see "You are not logged in" in the "page-footer" "region"
And I log in as "admin"
Then I should see "Hi, Admin!" in the "page-header" "region"
@accessibility @javascript
Scenario Outline: The start page must meet accessibility standards when the welcome message is displayed
Given the following config values are set as admin:
| defaulthomepage | <defaulthomepage> |
When I log in as "admin"
Then I should see "Welcome, Admin!" in the "page-header" "region"
And the page should meet accessibility standards
Examples:
| defaulthomepage |
# Home.
| 0 |
# Dashboard.
| 1 |
# My courses.
| 2 |
+213
View File
@@ -0,0 +1,213 @@
<?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 core_my\event;
use context_system;
use context_user;
/**
* Unit tests for the dashboard events.
*
* @package core
* @category test
* @copyright 2016 Stephen Bourget
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class events_test extends \advanced_testcase {
/** @var user cobject */
protected $user;
/**
* Setup often used objects for the following tests.
*/
protected function setUp(): void {
global $USER;
$this->resetAfterTest();
// The user we are going to test this on.
$this->setAdminUser();
$this->user = $USER;
}
/**
* Test the dashboard viewed event.
*
* There is no external API for viewing the dashboard, so the unit test will simply
* create and trigger the event and ensure data is returned as expected.
*/
public function test_dashboard_viewed(): void {
$user = $this->user;
// Trigger an event: dashboard viewed.
$eventparams = array(
'context' => $context = \context_user::instance($user->id)
);
$event = \core\event\dashboard_viewed::create($eventparams);
// Trigger and capture the event.
$sink = $this->redirectEvents();
$event->trigger();
$events = $sink->get_events();
$event = reset($events);
// Check that the event data is valid.
$this->assertInstanceOf('\core\event\dashboard_viewed', $event);
$this->assertEquals($user->id, $event->userid);
$this->assertDebuggingNotCalled();
}
/**
* Test the dashboard reset event.
*
* We will reset the user dashboard to
* trigger the event and ensure data is returned as expected.
*
* @covers ::my_reset_page
*/
public function test_dashboard_reset(): void {
global $CFG, $DB;
require_once($CFG->dirroot . '/my/lib.php');
$user = $this->user;
$usercontext = context_user::instance($this->user->id);
// Create at least one dashboard.
my_copy_page($this->user->id);
$this->assertNotEmpty($DB->get_records('my_pages', ['userid' => $this->user->id, 'private' => MY_PAGE_PRIVATE,
'name' => MY_PAGE_DEFAULT]));
$this->assertNotEmpty($DB->get_records('block_instances', ['parentcontextid' => $usercontext->id]));
// Reset the dashboard.
$sink = $this->redirectEvents();
my_reset_page($user->id);
// Assert that the page and all th blocks were deleted.
$this->assertEmpty($DB->get_records('my_pages', ['userid' => $this->user->id, 'private' => MY_PAGE_PRIVATE,
'name' => MY_PAGE_DEFAULT]));
$this->assertEmpty($DB->get_records('block_instances', ['parentcontextid' => $usercontext->id]));
// Trigger and capture the event.
$events = $sink->get_events();
$event = reset($events);
$sink->close();
// Check that the event data is valid.
$this->assertInstanceOf('\core\event\dashboard_reset', $event);
$this->assertEquals($user->id, $event->userid);
$this->assertEquals(MY_PAGE_PRIVATE, $event->other['private']);
$this->assertEquals('my-index', $event->other['pagetype']);
$this->assertDebuggingNotCalled();
// Reset the dashboard with private parameter is set to MY_PAGE_PUBLIC and pagetype set to 'user-profile'.
$systempage = $DB->get_record('my_pages', ['userid' => null, 'name' => MY_PAGE_DEFAULT, 'private' => MY_PAGE_PUBLIC]);
$this->getDataGenerator()->create_block('online_users', [
'parentcontextid' => context_system::instance()->id,
'pagetypepattern' => 'user-profile',
'subpagepattern' => $systempage->id,
]);
my_copy_page($this->user->id, MY_PAGE_PUBLIC, 'user-profile');
$this->assertNotEmpty($DB->get_records('my_pages', ['userid' => $this->user->id, 'private' => MY_PAGE_PUBLIC,
'name' => MY_PAGE_DEFAULT]));
$this->assertNotEmpty($DB->get_records('block_instances', ['parentcontextid' => $usercontext->id]));
$sink = $this->redirectEvents();
my_reset_page($user->id, MY_PAGE_PUBLIC, 'user-profile');
$this->assertEmpty($DB->get_records('my_pages', ['userid' => $this->user->id, 'private' => MY_PAGE_PUBLIC,
'name' => MY_PAGE_DEFAULT]));
$this->assertEmpty($DB->get_records('block_instances', ['parentcontextid' => $usercontext->id]));
// Trigger and capture the event.
$events = $sink->get_events();
$event = reset($events);
$sink->close();
$this->assertEquals(MY_PAGE_PUBLIC, $event->other['private']);
$this->assertEquals('user-profile', $event->other['pagetype']);
}
/**
* Test the dashboards reset event.
*
* We will reset all user dashboards to
* trigger the event and ensure data is returned as expected.
*
* @covers ::my_reset_page_for_all_users
*/
public function test_dashboards_reset(): void {
global $CFG, $USER, $DB;
require_once($CFG->dirroot . '/my/lib.php');
$usercontext = context_user::instance($this->user->id);
// Create at least one dashboard.
my_copy_page($this->user->id);
$this->assertNotEmpty($DB->get_records('my_pages', ['userid' => $this->user->id, 'private' => MY_PAGE_PRIVATE,
'name' => MY_PAGE_DEFAULT]));
$this->assertNotEmpty($DB->get_records('block_instances', ['parentcontextid' => $usercontext->id]));
// Reset all dashbaords.
$sink = $this->redirectEvents();
my_reset_page_for_all_users();
// Assert that the page and all th blocks were deleted.
$this->assertEmpty($DB->get_records('my_pages', ['userid' => $this->user->id, 'private' => MY_PAGE_PRIVATE,
'name' => MY_PAGE_DEFAULT]));
$this->assertEmpty($DB->get_records('block_instances', ['parentcontextid' => $usercontext->id]));
// Trigger and capture the event.
$events = $sink->get_events();
$event = reset($events);
$sink->close();
// Check that the event data is valid.
$this->assertInstanceOf('\core\event\dashboards_reset', $event);
$this->assertEquals($USER->id, $event->userid);
$this->assertEquals(MY_PAGE_PRIVATE, $event->other['private']);
$this->assertEquals('my-index', $event->other['pagetype']);
$this->assertDebuggingNotCalled();
// Reset the dashboards with private parameter is set to MY_PAGE_PUBLIC and pagetype set to 'user-profile'.
$systempage = $DB->get_record('my_pages', ['userid' => null, 'name' => MY_PAGE_DEFAULT, 'private' => MY_PAGE_PUBLIC]);
$this->getDataGenerator()->create_block('online_users', [
'parentcontextid' => context_system::instance()->id,
'pagetypepattern' => 'user-profile',
'subpagepattern' => $systempage->id,
]);
my_copy_page($this->user->id, MY_PAGE_PUBLIC, 'user-profile');
$this->assertNotEmpty($DB->get_records('my_pages', ['userid' => $this->user->id, 'private' => MY_PAGE_PUBLIC,
'name' => MY_PAGE_DEFAULT]));
$this->assertNotEmpty($DB->get_records('block_instances', ['parentcontextid' => $usercontext->id]));
$sink = $this->redirectEvents();
my_reset_page_for_all_users(MY_PAGE_PUBLIC, 'user-profile');
$this->assertEmpty($DB->get_records('my_pages', ['userid' => $this->user->id, 'private' => MY_PAGE_PUBLIC,
'name' => MY_PAGE_DEFAULT]));
$this->assertEmpty($DB->get_records('block_instances', ['parentcontextid' => $usercontext->id]));
// Trigger and capture the event.
$events = $sink->get_events();
$event = reset($events);
$sink->close();
$this->assertEquals(MY_PAGE_PUBLIC, $event->other['private']);
$this->assertEquals('user-profile', $event->other['pagetype']);
}
}
+89
View File
@@ -0,0 +1,89 @@
<?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 core_my\external;
use externallib_advanced_testcase;
defined('MOODLE_INTERNAL') || die();
global $CFG;
require_once($CFG->dirroot . '/webservice/tests/helpers.php');
/**
* Test Class for external function core_my_view_page.
*
* @package core_my
* @category external
* @copyright 2023 Rodrigo Mady <rodrigo.mady@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @since Moodle 4.3
* @covers \core_my\external\view_page
*/
class view_page_test extends externallib_advanced_testcase {
/**
* Set up for every test.
*/
public function setUp(): void {
$this->resetAfterTest();
}
/**
* Helper.
*
* @param string $page
* @return array
*/
protected function view_page(string $page): array {
$result = view_page::execute($page);
return \core_external\external_api::clean_returnvalue(view_page::execute_returns(), $result);
}
/**
* Test for webservice my view page.
*/
public function test_view_page(): void {
$user = $this->getDataGenerator()->create_user();
$this->setUser($user);
// Trigger and capture the event.
$sink = $this->redirectEvents();
// Request to trigger the view event in my.
$result = $this->view_page('my');
$this->assertTrue($result['status']);
$this->assertEmpty($result['warnings']);
// Request to trigger the view event in dashboard.
$result = $this->view_page('dashboard');
$this->assertTrue($result['status']);
$this->assertEmpty($result['warnings']);
// Wrong page to trigger the event.
$result = $this->view_page('test');
$this->assertFalse($result['status']);
$this->assertNotEmpty($result['warnings']);
$events = $sink->get_events();
// Check if the log still with two rows.
$this->assertCount(2, $events);
$this->assertInstanceOf('\core\event\mycourses_viewed', $events[0]);
$this->assertInstanceOf('\core\event\dashboard_viewed', $events[1]);
$sink->close();
}
}
+74
View File
@@ -0,0 +1,74 @@
<?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/>.
/**
* Unit tests for the core_my implementation of the privacy API.
*
* @package core_my
* @category test
* @copyright 2018 Zig Tan <zig@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_my\privacy;
defined('MOODLE_INTERNAL') || die();
use core_privacy\local\request\writer;
use core_my\privacy\provider;
/**
* Unit tests for the core_my implementation of the privacy API.
*
* @copyright 2018 Zig Tan <zig@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class provider_test extends \core_privacy\tests\provider_testcase {
/**
* Test for provider::test_export_user_preferences().
*/
public function test_export_user_preferences(): void {
global $DB;
// Test setup.
$this->resetAfterTest(true);
$user = $this->getDataGenerator()->create_user();
$this->setUser($user);
// Add a user home page preference for the User.
set_user_preference('user_home_page_preference', HOMEPAGE_MY);
// Test the user preference exists.
$params = [
'userid' => $user->id,
'name' => 'user_home_page_preference'
];
$preferences = $DB->get_record('user_preferences', $params);
$this->assertEquals('user_home_page_preference', $preferences->name);
// Test the user preferences export contains 1 user preference record for the User.
provider::export_user_preferences($user->id);
$contextuser = \context_user::instance($user->id);
$writer = writer::with_context($contextuser);
$this->assertTrue($writer->has_any_data());
$prefs = $writer->get_user_preferences('core_my');
$this->assertCount(1, (array) $prefs);
$this->assertEquals(HOMEPAGE_MY, $prefs->user_home_page_preference->value);
}
}
+4
View File
@@ -0,0 +1,4 @@
This files describes changes in the my system.
=== 4.0 ===
* Introduce a new /courses page
* Tighten up the typing within the lib file