Merge branch 'MDL-46878-master' of git://github.com/FMCorz/moodle

This commit is contained in:
Andrew Nicols 2015-09-21 12:05:32 +08:00
commit 28eca8cf5b
7 changed files with 293 additions and 2 deletions

View File

@ -30,7 +30,11 @@ $string['pinblocksexplan'] = 'Any block settings you configure here will be visi
$string['defaultpage'] = 'Default My Moodle page';
$string['defaultprofilepage'] = 'Default profile page';
$string['addpage'] = 'Add page';
$string['alldashboardswerereset'] = 'All Dashboard pages have been reset to default.';
$string['allprofileswerereset'] = 'All profile pages have been reset to default.';
$string['delpage'] = 'Delete page';
$string['managepages'] = 'Manage pages';
$string['reseteveryonesdashboard'] = 'Reset Dashboard for all users';
$string['reseteveryonesprofile'] = 'Reset profile for all users';
$string['resetpage'] = 'Reset page to default';
$string['reseterror'] = 'There was an error resetting your page';

View File

@ -2055,6 +2055,31 @@ function blocks_delete_instance($instance, $nolongerused = false, $skipblockstab
}
}
/**
* Delete multiple blocks at once.
*
* @param array $instanceids A list of block instance ID.
*/
function blocks_delete_instances($instanceids) {
global $DB;
$instances = $DB->get_recordset_list('block_instances', 'id', $instanceids);
foreach ($instances as $instance) {
blocks_delete_instance($instance, false, true);
}
$instances->close();
$DB->delete_records_list('block_positions', 'blockinstanceid', $instanceids);
$DB->delete_records_list('block_instances', 'id', $instanceids);
$preferences = array();
foreach ($instanceids as $instanceid) {
$preferences[] = 'block' . $instanceid . 'hidden';
$preferences[] = 'docked_block_instance_' . $instanceid;
}
$DB->delete_records_list('user_preferences', 'name', $preferences);
}
/**
* Delete all the blocks that belong to a particular context.
*

View File

@ -478,6 +478,70 @@ class core_blocklib_testcase extends advanced_testcase {
$expected = array('user-profile', 'user-profile-*', 'user-*', '*');
$this->assertEquals($expected, array_values(matching_page_type_patterns_from_pattern($pattern)));
}
public function test_delete_instances() {
global $DB;
$this->purge_blocks();
$this->setAdminUser();
$regionname = 'a-region';
$blockname = $this->get_a_known_block_type();
$context = context_system::instance();
list($page, $blockmanager) = $this->get_a_page_and_block_manager(array($regionname),
$context, 'page-type');
$blockmanager->add_blocks(array($regionname => array($blockname, $blockname, $blockname)), null, null, false, 3);
$blockmanager->load_blocks();
$blocks = $blockmanager->get_blocks_for_region($regionname);
$blockids = array();
$preferences = array();
// Create block related data.
foreach ($blocks as $block) {
$instance = $block->instance;
$pref = 'block' . $instance->id . 'hidden';
set_user_preference($pref, '123', 123);
$preferences[] = $pref;
$pref = 'docked_block_instance_' . $instance->id;
set_user_preference($pref, '123', 123);
$preferences[] = $pref;
blocks_set_visibility($instance, $page, 1);
$blockids[] = $instance->id;
}
// Confirm what has been set.
$this->assertCount(3, $blockids);
list($insql, $inparams) = $DB->get_in_or_equal($blockids);
$this->assertEquals(3, $DB->count_records_select('block_positions', "blockinstanceid $insql", $inparams));
list($insql, $inparams) = $DB->get_in_or_equal($preferences);
$this->assertEquals(6, $DB->count_records_select('user_preferences', "name $insql", $inparams));
// Keep a block on the side.
$allblockids = $blockids;
$tokeep = array_pop($blockids);
// Delete and confirm what should have happened.
blocks_delete_instances($blockids);
// Reload the manager.
list($page, $blockmanager) = $this->get_a_page_and_block_manager(array($regionname),
$context, 'page-type');
$blockmanager->load_blocks();
$blocks = $blockmanager->get_blocks_for_region($regionname);
$this->assertCount(1, $blocks);
list($insql, $inparams) = $DB->get_in_or_equal($allblockids);
$this->assertEquals(1, $DB->count_records_select('block_positions', "blockinstanceid $insql", $inparams));
list($insql, $inparams) = $DB->get_in_or_equal($preferences);
$this->assertEquals(2, $DB->count_records_select('user_preferences', "name $insql", $inparams));
$this->assertFalse(context_block::instance($blockids[0], IGNORE_MISSING));
$this->assertFalse(context_block::instance($blockids[1], IGNORE_MISSING));
context_block::instance($tokeep); // Would throw an exception if it was deleted.
}
}
/**

View File

@ -39,7 +39,7 @@ require_once(dirname(__FILE__) . '/../config.php');
require_once($CFG->dirroot . '/my/lib.php');
require_once($CFG->libdir.'/adminlib.php');
$edit = optional_param('edit', null, PARAM_BOOL); // Turn editing on and off
$resetall = optional_param('resetall', null, PARAM_BOOL);
require_login();
@ -48,6 +48,11 @@ $header = "$SITE->shortname: ".get_string('myhome')." (".get_string('mypage', 'a
$PAGE->set_blocks_editing_capability('moodle/my:configsyspages');
admin_externalpage_setup('mypage', '', null, '', array('pagelayout' => 'mydashboard'));
if ($resetall && confirm_sesskey()) {
my_reset_page_for_all_users(MY_PAGE_PRIVATE, 'my-index');
redirect($PAGE->url, get_string('alldashboardswerereset', 'my'));
}
// Override pagetype to show blocks properly.
$PAGE->set_pagetype('my-index');
@ -61,6 +66,11 @@ if (!$currentpage = my_get_page(null, MY_PAGE_PRIVATE)) {
}
$PAGE->set_subpage($currentpage->id);
// Display a button to reset everyone's dashboard.
$url = new moodle_url($PAGE->url, array('resetall' => 1));
$button = $OUTPUT->single_button($url, get_string('reseteveryonesdashboard', 'my'));
$PAGE->set_button($button . $PAGE->button);
echo $OUTPUT->header();
echo $OUTPUT->custom_block_region('content');

View File

@ -136,6 +136,57 @@ function my_reset_page($userid, $private=MY_PAGE_PRIVATE, $pagetype='my-index')
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.
* @return void
*/
function my_reset_page_for_all_users($private = MY_PAGE_PRIVATE, $pagetype = 'my-index') {
global $DB;
// Find all the user pages.
$where = 'userid IS NOT NULL AND private = :private';
$params = array('private' => $private);
$pages = $DB->get_recordset_select('my_pages', $where, $params, 'id, userid');
$pageids = array();
$blockids = array();
foreach ($pages as $page) {
$pageids[] = $page->id;
$usercontext = context_user::instance($page->userid);
// Find all block instances in that page.
$blocks = $DB->get_recordset('block_instances', array('parentcontextid' => $usercontext->id,
'pagetypepattern' => $pagetype), '', 'id, subpagepattern');
foreach ($blocks as $block) {
if (is_null($block->subpagepattern) || $block->subpagepattern == $page->id) {
$blockids[] = $block->id;
}
}
$blocks->close();
}
$pages->close();
// 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.
if (!empty($pageids)) {
list($insql, $inparams) = $DB->get_in_or_equal($pageids);
$DB->delete_records_select('my_pages', "id $insql", $pageids);
}
// We should be good to go now.
$transaction->allow_commit();
}
class my_syspage_block_manager extends block_manager {
// HACK WARNING!
// TODO: figure out a better way to do this

View File

@ -0,0 +1,129 @@
@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 I log in as "admin"
And I set the following system permissions of "Authenticated user" role:
| block/myprofile:addinstance | Allow |
| moodle/block:edit | Allow |
And I log out
And I log in as "student1"
And I follow "Dashboard" in the user menu
And I press "Customise this page"
And I add the "Comments" block
And I press "Stop customising this page"
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 not see "Logged in user"
And I press "Customise this page"
And I add the "Logged in user" block
And I press "Stop customising this page"
And I should see "Logged in user"
And I log out
And I log in as "student3"
And I follow "Dashboard" in the user menu
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 "Default Dashboard page" node in "Site administration > Appearance"
And I press "Blocks editing on"
And I add the "Latest news" block
And I open the "Online users" blocks action menu
And I follow "Delete Online users"
And I press "Yes"
And I press "Blocks editing off"
And I log out
And I log in as "student1"
And I follow "Dashboard" in the user menu
And I should not see "Latest news"
And I should see "Online users"
And I log out
And I log in as "student3"
And I follow "Dashboard" in the user menu
And I should not see "Latest news"
And I should see "Online users"
And I log out
And I log in as "admin"
And I navigate to "Default Dashboard page" node in "Site administration > Appearance"
When I press "Reset Dashboard for all users"
And I follow "Continue"
And I log out
And I log in as "student1"
And I follow "Dashboard" in the user menu
Then I should see "Latest news"
And I should not see "Comments"
And I should not see "Online users"
And I log out
And I log in as "student3"
And I follow "Dashboard" in the user menu
And I should see "Latest news"
And I should not see "Online users"
And I log out
# Check that this did not affect the customised profiles.
And I log in as "student2"
And I follow "Profile" in the user menu
And I should see "Logged in user"
And I should not see "Latest news"
Scenario: Reset profile for all users
Given I log in as "admin"
And I navigate to "Default profile page" node in "Site administration > Appearance"
And I press "Blocks editing on"
And I add the "Latest news" block
And I log out
And I log in as "student2"
And I follow "Profile" in the user menu
And I should not see "Latest news"
And I log out
And I log in as "student3"
And I follow "Profile" in the user menu
And I should not see "Latest news"
And I log out
And I log in as "admin"
And I navigate to "Default profile page" node in "Site administration > Appearance"
When I press "Reset profile for all users"
And I follow "Continue"
And I log out
And I log in as "student2"
And I follow "Profile" in the user menu
Then I should see "Latest news"
And I should not see "Logged in user"
And I log out
And I log in as "student3"
And I follow "Profile" in the user menu
And I should see "Latest news"
And I log out
# Check that this did not affect the customised dashboards.
And I log in as "student1"
And I follow "Dashboard" in the user menu
And I should see "Comments"
And I should not see "Latest news"

View File

@ -31,7 +31,7 @@ require_once(dirname(__FILE__) . '/../config.php');
require_once($CFG->dirroot . '/my/lib.php');
require_once($CFG->libdir.'/adminlib.php');
$edit = optional_param('edit', null, PARAM_BOOL); // Turn editing on and off.
$resetall = optional_param('resetall', null, PARAM_BOOL);
require_login();
@ -40,6 +40,11 @@ $header = "$SITE->shortname: ".get_string('publicprofile')." (".get_string('mypr
$PAGE->set_blocks_editing_capability('moodle/my:configsyspages');
admin_externalpage_setup('profilepage', '', null, '', array('pagelayout' => 'mypublic'));
if ($resetall && confirm_sesskey()) {
my_reset_page_for_all_users(MY_PAGE_PUBLIC, 'user-profile');
redirect($PAGE->url, get_string('allprofileswerereset', 'my'));
}
// Override pagetype to show blocks properly.
$PAGE->set_pagetype('user-profile');
@ -53,6 +58,9 @@ if (!$currentpage = my_get_page(null, MY_PAGE_PUBLIC)) {
}
$PAGE->set_subpage($currentpage->id);
$url = new moodle_url($PAGE->url, array('resetall' => 1));
$button = $OUTPUT->single_button($url, get_string('reseteveryonesprofile', 'my'));
$PAGE->set_button($button . $PAGE->button);
echo $OUTPUT->header();