diff --git a/admin/tool/usertours/classes/manager.php b/admin/tool/usertours/classes/manager.php index 40d2595ebc2..8eef2d8dfe8 100644 --- a/admin/tool/usertours/classes/manager.php +++ b/admin/tool/usertours/classes/manager.php @@ -762,6 +762,13 @@ class manager { * @param int $direction */ protected static function _move_tour(tour $tour, $direction) { + // We can't move the first tour higher, nor the last tour any lower. + if (($tour->is_first_tour() && $direction == helper::MOVE_UP) || + ($tour->is_last_tour() && $direction == helper::MOVE_DOWN)) { + + return; + } + $currentsortorder = $tour->get_sortorder(); $targetsortorder = $currentsortorder + $direction; @@ -890,6 +897,9 @@ class manager { } $existingtourrecords->close(); + // Ensure we correct the sortorder in any existing tours, prior to adding latest shipped tours. + helper::reset_tour_sortorder(); + foreach (array_reverse($shippedtours) as $filename => $version) { $filepath = $CFG->dirroot . "/{$CFG->admin}/tool/usertours/tours/" . $filename; $tourjson = file_get_contents($filepath); diff --git a/admin/tool/usertours/db/upgrade.php b/admin/tool/usertours/db/upgrade.php index a6855ea908c..db3ccd8a116 100644 --- a/admin/tool/usertours/db/upgrade.php +++ b/admin/tool/usertours/db/upgrade.php @@ -61,5 +61,12 @@ function xmldb_tool_usertours_upgrade($oldversion) { // Automatically generated Moodle v3.8.0 release upgrade line. // Put any upgrade step following this. + if ($oldversion < 2020031900) { + // Updating shipped tours will fix broken sortorder records in existing tours. + manager::update_shipped_tours(); + + upgrade_plugin_savepoint(true, 2020031900, 'tool', 'usertours'); + } + return true; } diff --git a/admin/tool/usertours/tests/manager_test.php b/admin/tool/usertours/tests/manager_test.php index bffecb32f7c..913c3e1b86e 100644 --- a/admin/tool/usertours/tests/manager_test.php +++ b/admin/tool/usertours/tests/manager_test.php @@ -122,6 +122,83 @@ class tool_usertours_manager_testcase extends advanced_testcase { $rcm->invokeArgs($manager, $arguments); } + /** + * Data provider for test_move_tour + * + * @return array + */ + public function move_tour_provider() { + $alltours = [ + ['name' => 'Tour 1'], + ['name' => 'Tour 2'], + ['name' => 'Tour 3'], + ]; + + return [ + 'Move up' => [ + $alltours, + 'Tour 2', + \tool_usertours\helper::MOVE_UP, + 0, + ], + 'Move down' => [ + $alltours, + 'Tour 2', + \tool_usertours\helper::MOVE_DOWN, + 2, + ], + 'Move up (first)' => [ + $alltours, + 'Tour 1', + \tool_usertours\helper::MOVE_UP, + 0, + ], + 'Move down (last)' => [ + $alltours, + 'Tour 3', + \tool_usertours\helper::MOVE_DOWN, + 2, + ], + ]; + } + + /** + * Test moving tours (changing sortorder) + * + * @dataProvider move_tour_provider + * + * @param array $alltours + * @param string $movetourname + * @param int $direction + * @param int $expectedsortorder + * @return void + */ + public function test_move_tour($alltours, $movetourname, $direction, $expectedsortorder) { + global $DB; + + $this->resetAfterTest(); + + // Clear out existing tours so ours are the only ones, otherwise we can't predict the sortorder. + $DB->delete_records('tool_usertours_tours'); + + foreach ($alltours as $tourconfig) { + $this->helper_create_tour((object) $tourconfig); + } + + // Load our tour to move. + $record = $DB->get_record('tool_usertours_tours', ['name' => $movetourname]); + $tour = \tool_usertours\tour::load_from_record($record); + + // Call protected method via reflection. + $class = new ReflectionClass(\tool_usertours\manager::class); + $method = $class->getMethod('_move_tour'); + $method->setAccessible(true); + $method->invokeArgs(null, [$tour, $direction]); + + // Assert expected sortorder. + $this->assertEquals($expectedsortorder, $tour->get_sortorder()); + } + /** * Data Provider for get_matching_tours tests. * diff --git a/admin/tool/usertours/version.php b/admin/tool/usertours/version.php index c56c1ff033f..aa140f9b068 100644 --- a/admin/tool/usertours/version.php +++ b/admin/tool/usertours/version.php @@ -24,6 +24,6 @@ defined('MOODLE_INTERNAL') || die(); -$plugin->version = 2019120400; // The current module version (Date: YYYYMMDDXX). +$plugin->version = 2020031900; // The current module version (Date: YYYYMMDDXX). $plugin->requires = 2019111200; // Requires this Moodle version. $plugin->component = 'tool_usertours'; // Full name of the plugin (used for diagnostics).