public static function update_shipped_tours() {
        global $DB, $CFG;

        // A list of tours that are shipped with Moodle. They are in
        // the format filename => version. The version value needs to
        // be increased if the tour has been updated.
        $shippedtours = [
            '36_dashboard.json' => 3
        ];

        // These are tours that we used to ship but don't ship any longer.
        // We do not remove them, but we do disable them.
        $unshippedtours = [
            'boost_administrator.json' => 1,
            'boost_course_view.json' => 1,
        ];

        if ($CFG->messaging) {
            $shippedtours['36_messaging.json'] = 3;
        } else {
            $unshippedtours['36_messaging.json'] = 3;
        }

        $existingtourrecords = $DB->get_recordset('tool_usertours_tours');

        // Get all of the existing shipped tours and check if they need to be
        // updated.
        foreach ($existingtourrecords as $tourrecord) {
            $tour = tour::load_from_record($tourrecord);

            if (!empty($tour->get_config(self::CONFIG_SHIPPED_TOUR))) {
                $filename = $tour->get_config(self::CONFIG_SHIPPED_FILENAME);
                $version = $tour->get_config(self::CONFIG_SHIPPED_VERSION);

                // If we know about this tour (otherwise leave it as is).
                if (isset($shippedtours[$filename])) {
                    // And the version in the DB is an older version.
                    if ($version < $shippedtours[$filename]) {
                        // Remove the old version because it's been updated
                        // and needs to be recreated.
                        $tour->remove();
                    } else {
                        // The tour has not been updated so we don't need to
                        // do anything with it.
                        unset($shippedtours[$filename]);
                    }
                }

                if (isset($unshippedtours[$filename])) {
                    if ($version <= $unshippedtours[$filename]) {
                        $tour = tour::instance($tour->get_id());
                        $tour->set_enabled(tour::DISABLED);
                        $tour->persist();
                    }
                }
            }
        }
        $existingtourrecords->close();

        foreach (array_reverse($shippedtours) as $filename => $version) {
            $filepath = $CFG->dirroot . "/{$CFG->admin}/tool/usertours/tours/" . $filename;
            $tourjson = file_get_contents($filepath);
            $tour = self::import_tour_from_json($tourjson);

            // Set some additional config data to record that this tour was
            // added as a shipped tour.
            $tour->set_config(self::CONFIG_SHIPPED_TOUR, true);
            $tour->set_config(self::CONFIG_SHIPPED_FILENAME, $filename);
            $tour->set_config(self::CONFIG_SHIPPED_VERSION, $version);

            // Bump new tours to the top of the list.
            while ($tour->get_sortorder() > 0) {
                self::_move_tour($tour, helper::MOVE_UP);
            }

            if (defined('BEHAT_SITE_RUNNING') || (defined('PHPUNIT_TEST') && PHPUNIT_TEST)) {
                // Disable this tour if this is behat or phpunit.
                $tour->set_enabled(false);
            }

            $tour->persist();
        }
    }