Merge branch 'MDL-74506-master' of https://github.com/andrewnicols/moodle

This commit is contained in:
Jun Pataleta 2022-04-16 19:14:01 +08:00
commit e25d806abc
10 changed files with 217 additions and 11 deletions

View File

@ -67,5 +67,10 @@ function xmldb_block_calendar_month_upgrade($oldversion, $block) {
upgrade_block_savepoint(true, 2022030200, 'calendar_month', false);
}
if ($oldversion < 2022041901) {
upgrade_block_set_my_user_parent_context('calendar_month', '__default', 'my-index');
upgrade_block_savepoint(true, 2022041901, 'calendar_month', false);
}
return true;
}

View File

@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2022041900; // The current plugin version (Date: YYYYMMDDXX).
$plugin->version = 2022041901; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2022041200; // Requires this Moodle version.
$plugin->component = 'block_calendar_month'; // Full name of the plugin (used for diagnostics)

View File

@ -115,5 +115,10 @@ function xmldb_block_myoverview_upgrade($oldversion) {
upgrade_block_savepoint(true, 2021052504, 'myoverview', false);
}
if ($oldversion < 2022041901) {
upgrade_block_set_my_user_parent_context('myoverview', '__default', 'my-index');
upgrade_block_savepoint(true, 2022041901, 'myoverview', false);
}
return true;
}

View File

@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2022041900; // The current plugin version (Date: YYYYMMDDXX).
$plugin->version = 2022041901; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2022041200; // Requires this Moodle version.
$plugin->component = 'block_myoverview'; // Full name of the plugin (used for diagnostics).

View File

@ -83,5 +83,10 @@ function xmldb_block_recentlyaccesseditems_upgrade($oldversion, $block) {
upgrade_block_savepoint(true, 2022030200, 'recentlyaccesseditems', false);
}
if ($oldversion < 2022041901) {
upgrade_block_set_my_user_parent_context('recentlyaccesseditems', '__default', 'my-index');
upgrade_block_savepoint(true, 2022041901, 'recentlyaccesseditems', false);
}
return true;
}

View File

@ -22,6 +22,6 @@
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2022041900; // The current plugin version (Date: YYYYMMDDXX).
$plugin->version = 2022041901; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2022041200; // Requires this Moodle version.
$plugin->component = 'block_recentlyaccesseditems'; // Full name of the plugin (used for diagnostics).

View File

@ -66,5 +66,10 @@ function xmldb_block_timeline_upgrade($oldversion, $block) {
upgrade_block_savepoint(true, 2022030200, 'timeline', false);
}
if ($oldversion < 2022041901) {
upgrade_block_set_my_user_parent_context('timeline', '__default', 'my-index');
upgrade_block_savepoint(true, 2022041901, 'timeline', false);
}
return true;
}

View File

@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2022041900; // The current plugin version (Date: YYYYMMDDXX).
$plugin->version = 2022041901; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2022041200; // Requires this Moodle version.
$plugin->component = 'block_timeline'; // Full name of the plugin (used for diagnostics).

View File

@ -1338,7 +1338,7 @@ function upgrade_block_set_defaultregion(
timemodified
) SELECT
:selectblockname AS blockname,
:selectparentcontext AS parentcontextid,
c.id AS parentcontextid,
0 AS showinsubcontexts,
:selectpagetypepattern AS pagetypepattern,
mp.id AS subpagepattern,
@ -1347,6 +1347,7 @@ function upgrade_block_set_defaultregion(
:selecttimecreated AS timecreated,
:selecttimemodified AS timemodified
FROM {my_pages} mp
JOIN {context} c ON c.instanceid = mp.userid AND c.contextlevel = :contextuser
WHERE mp.id NOT IN (
SELECT mpi.id FROM {my_pages} mpi
JOIN {block_instances} bi
@ -1359,10 +1360,9 @@ function upgrade_block_set_defaultregion(
AND mp.name = :pagename
EOF;
$context = context_system::instance();
$result = $DB->execute($sql, [
$DB->execute($sql, [
'selectblockname' => $blockname,
'selectparentcontext' => $context->id,
'contextuser' => CONTEXT_USER,
'selectpagetypepattern' => $pagetypepattern,
'selectdefaultregion' => $newdefaultregion,
'selecttimecreated' => time(),
@ -1511,3 +1511,89 @@ function upgrade_block_delete_instances(
$deleteblockinstances($instanceselect, $params);
}
/**
* Update the block instance parentcontext to point to the correct user context id for the specified block on a my page.
*
* @param string $blockname
* @param string $pagename
* @param string $pagetypepattern
*/
function upgrade_block_set_my_user_parent_context(
string $blockname,
string $pagename,
string $pagetypepattern
): void {
global $DB;
$subpagepattern = $DB->sql_cast_char2int('bi.subpagepattern');
// Look for any and all instances of the block in customised /my pages.
$subpageempty = $DB->sql_isnotempty('block_instances', 'bi.subpagepattern', true, false);
$dbman = $DB->get_manager();
$temptablename = 'block_instance_context';
$xmldbtable = new \xmldb_table($temptablename);
$xmldbtable->add_field('instanceid', XMLDB_TYPE_INTEGER, 10, null, XMLDB_NOTNULL, null, null);
$xmldbtable->add_field('contextid', XMLDB_TYPE_INTEGER, 10, null, XMLDB_NOTNULL, null, null);
$xmldbtable->add_key('primary', XMLDB_KEY_PRIMARY, ['instanceid']);
$dbman->create_temp_table($xmldbtable);
$sql = <<<EOF
INSERT INTO {block_instance_context} (
instanceid,
contextid
) SELECT
bi.id as instanceid,
c.id as contextid
FROM {my_pages} mp
JOIN {context} c ON c.instanceid = mp.userid AND c.contextlevel = :contextuser
JOIN {block_instances} bi
ON bi.blockname = :blockname
AND bi.subpagepattern IS NOT NULL AND {$subpageempty}
AND bi.pagetypepattern = :pagetypepattern
AND {$subpagepattern} = mp.id
WHERE mp.name = :pagename AND bi.parentcontextid <> c.id
EOF;
$DB->execute($sql, [
'blockname' => $blockname,
'pagetypepattern' => $pagetypepattern,
'contextuser' => CONTEXT_USER,
'pagename' => $pagename,
]);
$dbfamily = $DB->get_dbfamily();
if ($dbfamily === 'mysql') {
// MariaDB and MySQL.
$sql = <<<EOF
UPDATE {block_instances} bi, {block_instance_context} bic
SET bi.parentcontextid = bic.contextid
WHERE bi.id = bic.instanceid
EOF;
} else if ($dbfamily === 'oracle') {
$sql = <<<EOF
UPDATE {block_instances} bi
SET (bi.parentcontextid) = (
SELECT bic.contextid
FROM {block_instance_context} bic
WHERE bic.instanceid = bi.id
) WHERE EXISTS (
SELECT 'x'
FROM {block_instance_context} bic
WHERE bic.instanceid = bi.id
)
EOF;
} else {
// Postgres and sqlsrv.
$sql = <<<EOF
UPDATE {block_instances}
SET parentcontextid = bic.contextid
FROM {block_instance_context} bic
WHERE {block_instances}.id = bic.instanceid
EOF;
}
$DB->execute($sql);
$dbman->drop_table($xmldbtable);
}

View File

@ -180,7 +180,7 @@ class upgradelib_test extends \advanced_testcase {
// Any dashboards which are missing the block will have it created by the operation.
upgrade_block_set_defaultregion('calendar_month', '__default', 'my-index', 'content');
// Each of the dashboards should not have a block instance of the calendar_month block in the 'content' region
// Each of the dashboards should now have a block instance of the calendar_month block in the 'content' region
// on 'my-index' only.
foreach ($dashboards as $dashboardid) {
// Only one block should have been created.
@ -193,6 +193,12 @@ class upgradelib_test extends \advanced_testcase {
$this->assertEquals('calendar_month', $theblock->blockname);
$this->assertEquals('content', $theblock->defaultregion);
$this->assertEquals('my-index', $theblock->pagetypepattern);
// Fetch the user details.
$dashboard = $DB->get_record('my_pages', ['id' => $dashboardid]);
$usercontext = \context_user::instance($dashboard->userid);
$this->assertEquals($usercontext->id, $theblock->parentcontextid);
}
// Enusre that there are no blocks on the mycourses page.
@ -232,7 +238,6 @@ class upgradelib_test extends \advanced_testcase {
], 'id')->id;
$dashboards = [];
$mycourses = [];
$unchanged = [];
$unchangedcontexts = [];
$unchangedpreferences = [];
@ -303,7 +308,6 @@ class upgradelib_test extends \advanced_testcase {
'name' => '__courses',
'private' => MY_PAGE_PRIVATE,
]);
$mycourses[] = $usermycoursesid;
// These are on the my-index above, but are not the block being updated.
$userunchangedblocks[] = $this->getDataGenerator()->create_block('online_users', [
@ -439,4 +443,100 @@ class upgradelib_test extends \advanced_testcase {
]));
}
}
/**
* Ensrue that the upgrade_block_set_my_user_parent_context function performs as expected.
*
* @covers ::upgrade_block_set_my_user_parent_context
*/
public function test_upgrade_block_set_my_user_parent_context(): void {
global $DB;
$this->resetAfterTest();
$this->preventResetByRollback();
$systemcontext = \context_system::instance();
$dashboards = [];
$otherblocknames = [
'online_users',
'myoverview',
'calendar_month',
];
$affectedblockname = 'timeline';
// Create dashboard pages for a number of users.
while (count($dashboards) < 10) {
$user = $this->getDataGenerator()->create_user();
$dashboard = $DB->insert_record('my_pages', (object) [
'userid' => $user->id,
'name' => '__default',
'private' => MY_PAGE_PRIVATE,
]);
$dashboards[] = $dashboard;
$mycourse = $DB->insert_record('my_pages', (object) [
'userid' => $user->id,
'name' => '__courses',
'private' => MY_PAGE_PRIVATE,
]);
// These are on the my-index above, but are not the block being updated.
foreach ($otherblocknames as $blockname) {
$unchanged[] = $this->getDataGenerator()->create_block($blockname, [
'parentcontextid' => $systemcontext->id,
'pagetypepattern' => 'my-index',
'subpagepattern' => $dashboard,
]);
}
// This is on a my-index page, and is the affected block, but is on the mycourses page, not the dashboard.
$unchanged[] = $this->getDataGenerator()->create_block($affectedblockname, [
'parentcontextid' => $systemcontext->id,
'pagetypepattern' => 'my-index',
'subpagepattern' => $mycourse,
]);
// This is on the default dashboard, and is the affected block, but not a my-index page.
$unchanged[] = $this->getDataGenerator()->create_block($affectedblockname, [
'parentcontextid' => $systemcontext->id,
'pagetypepattern' => 'not-my-index',
'subpagepattern' => $dashboard,
]);
// This is the match which should be changed.
$changed[] = $this->getDataGenerator()->create_block($affectedblockname, [
'parentcontextid' => $systemcontext->id,
'pagetypepattern' => 'my-index',
'subpagepattern' => $dashboard,
]);
}
// Perform the operation.
// Target all affected blocks matching 'my-index' and correct the context to the relevant user's contexct.
// Only the '__default' dashboard on the 'my-index' my_page should be affected.
upgrade_block_set_my_user_parent_context($affectedblockname, '__default', 'my-index');
// Ensure that the relevant blocks remain unchanged.
foreach ($unchanged as $original) {
$block = $DB->get_record('block_instances', ['id' => $original->id]);
$this->assertEquals($original, $block);
}
// Ensure that only the expected blocks were changed.
foreach ($changed as $original) {
$block = $DB->get_record('block_instances', ['id' => $original->id]);
$this->assertNotEquals($original, $block);
// Fetch the my page and user details.
$dashboard = $DB->get_record('my_pages', ['id' => $original->subpagepattern]);
$usercontext = \context_user::instance($dashboard->userid);
// Only the contextid should be updated to the relevant user's context.
// No other changes are expected.
$expected = (object) $original;
$expected->parentcontextid = $usercontext->id;
$this->assertEquals($expected, $block);
}
}
}