diff --git a/admin/cli/install.php b/admin/cli/install.php index 2c2ff880728..bb9441ee0a2 100644 --- a/admin/cli/install.php +++ b/admin/cli/install.php @@ -74,6 +74,7 @@ Options: --adminpass=PASSWORD Password for the moodle admin account, required in non-interactive mode. --adminemail=STRING Email address for the moodle admin account. +--sitepreset=STRING Admin site preset to be applied during the installation process. --upgradekey=STRING The upgrade key to be set in the config.php, leave empty to not set it. --non-interactive No interactive questions, installation fails if any problem encountered. @@ -254,6 +255,7 @@ list($options, $unrecognized) = cli_get_params( 'adminuser' => 'admin', 'adminpass' => '', 'adminemail' => '', + 'sitepreset' => '', 'upgradekey' => '', 'non-interactive' => false, 'agree-license' => false, @@ -276,6 +278,12 @@ if (array_key_exists($lang, $languages)) { $CFG->lang = $lang; } +// Set up site admin preset. +$sitepreset = clean_param($options['sitepreset'], PARAM_RAW); +if (!empty($sitepreset)) { + $CFG->setsitepresetduringinstall = $sitepreset; +} + if ($unrecognized) { $unrecognized = implode("\n ", $unrecognized); cli_error(get_string('cliunknowoption', 'admin', $unrecognized)); diff --git a/admin/index.php b/admin/index.php index f9643fa8324..e842ba8574d 100644 --- a/admin/index.php +++ b/admin/index.php @@ -719,6 +719,12 @@ if (during_initial_install()) { set_config('rolesactive', 1); // after this, during_initial_install will return false. set_config('adminsetuppending', 1); set_config('registrationpending', 1); // Remind to register site after all other setup is finished. + + // Apply default preset, if it is defined in $CFG and has a valid value. + if (!empty($CFG->setsitepresetduringinstall)) { + \tool_admin_presets\helper::change_default_preset($CFG->setsitepresetduringinstall); + } + // we need this redirect to setup proper session upgrade_finished("index.php?sessionstarted=1&lang=$CFG->lang"); } diff --git a/admin/tool/admin_presets/classes/helper.php b/admin/tool/admin_presets/classes/helper.php index 67d911be3b9..6e65815c669 100644 --- a/admin/tool/admin_presets/classes/helper.php +++ b/admin/tool/admin_presets/classes/helper.php @@ -117,4 +117,46 @@ class helper { return $pluginid; } + + /** + * Apply the given preset. If it's a filename, the preset will be imported and then applied. + * + * @param string $presetnameorfile The preset name to be applied or a valid preset file to be imported and applied. + * @return int|null The preset identifier that has been applied or null if the given value was not valid. + */ + public static function change_default_preset(string $presetnameorfile): ?int { + global $DB; + + $presetid = null; + + // Check if the given variable points to a valid preset file to be imported and applied. + if (is_readable($presetnameorfile)) { + $xmlcontent = file_get_contents($presetnameorfile); + $manager = new manager(); + list($xmlnotused, $preset) = $manager->import_preset($xmlcontent); + if (!is_null($preset)) { + list($applied) = $manager->apply_preset($preset->id); + if (!empty($applied)) { + $presetid = $preset->id; + } + } + } else { + // Check if the given preset exists; if that's the case, it will be applied. + $stringmanager = get_string_manager(); + if ($stringmanager->string_exists($presetnameorfile . 'preset', 'tool_admin_presets')) { + $params = ['name' => get_string($presetnameorfile . 'preset', 'tool_admin_presets')]; + } else { + $params = ['name' => $presetnameorfile]; + } + if ($preset = $DB->get_record('tool_admin_presets', $params)) { + $manager = new manager(); + list($applied) = $manager->apply_preset($preset->id); + if (!empty($applied)) { + $presetid = $preset->id; + } + } + } + + return $presetid; + } } diff --git a/admin/tool/admin_presets/tests/helper_test.php b/admin/tool/admin_presets/tests/helper_test.php index 19dafa3f7c1..18a2ba58390 100644 --- a/admin/tool/admin_presets/tests/helper_test.php +++ b/admin/tool/admin_presets/tests/helper_test.php @@ -240,4 +240,120 @@ class helper_test extends \advanced_testcase { ], ]; } + + /** + * Test the behaviour of change_default_preset() method. + * + * @covers ::change_default_preset + * @dataProvider change_default_preset_provider + * + * @param string $preset The preset name to apply or the path to the XML to be imported and applied. + * @param array|null $settings A few settings to check (with their expected values). + * @param array|null $plugins A few module plugins to check (with their expected values for the visibility). + */ + public function test_change_default_preset(string $preset, ?array $settings = null, ?array $plugins = null): void { + $this->resetAfterTest(); + $this->setAdminUser(); + + // We need to change some of the default values; otherwise, the full preset won't be applied, because all the settings + // and plugins are the same. + set_config('enableanalytics', '0'); + + $generator = $this->getDataGenerator()->get_plugin_generator('tool_admin_presets'); + $generator->create_preset(['name' => 'Preset 1']); + + $presetid = helper::change_default_preset($preset); + + if (empty($settings) && empty($plugins)) { + // The preset hasn't been applied. + $this->assertNull($presetid); + } else { + // The preset has been applied. Check the settings and plugins are the expected. + $this->assertNotEmpty($presetid); + + // Check the setting values have changed accordingly with the ones defined in the preset. + foreach ($settings as $settingname => $settingvalue) { + $this->assertEquals($settingvalue, get_config('core', $settingname)); + } + + // Check the plugins visibility have changed accordingly with the ones defined in the preset. + $enabledplugins = \core\plugininfo\mod::get_enabled_plugins(); + foreach ($plugins as $pluginname => $pluginvalue) { + if ($pluginvalue) { + $this->assertArrayHasKey($pluginname, $enabledplugins); + } else { + $this->assertArrayNotHasKey($pluginname, $enabledplugins); + } + } + } + } + + /** + * Data provider for test_change_default_preset(). + * + * @return array + */ + public function change_default_preset_provider(): array { + return [ + 'Starter preset' => [ + 'preset' => 'starter', + 'settings' => [ + 'enablebadges' => 0, + 'enableportfolios' => 0, + ], + 'plugins' => [ + 'assign' => 1, + 'chat' => 0, + 'data' => 0, + 'lesson' => 0, + ], + ], + 'Full preset' => [ + 'preset' => 'full', + 'settings' => [ + 'enablebadges' => 1, + 'enableportfolios' => 0, + ], + 'plugins' => [ + 'assign' => 1, + 'chat' => 1, + 'data' => 1, + 'lesson' => 1, + ], + ], + 'Preset 1, created manually' => [ + 'preset' => 'Preset 1', + 'settings' => [ + 'enablebadges' => 0, + 'allowemojipicker' => 1, + ], + 'plugins' => [ + 'assign' => 1, + 'glossary' => 0, + ], + ], + 'Unexisting preset name' => [ + 'preset' => 'unexisting', + ], + 'Valid XML file' => [ + 'preset' => __DIR__ . '/fixtures/import_settings_plugins.xml', + 'settings' => [ + 'allowemojipicker' => 1, + 'enableportfolios' => 1, + ], + 'plugins' => [ + 'assign' => 1, + 'chat' => 0, + 'data' => 0, + 'lesson' => 1, + ], + ], + 'Invalid XML file' => [ + 'preset' => __DIR__ . '/fixtures/invalid_xml_file.xml', + ], + 'Unexisting XML file' => [ + 'preset' => __DIR__ . '/fixtures/unexisting.xml', + ], + ]; + } } diff --git a/config-dist.php b/config-dist.php index bcbd9d93e95..edd341d19ce 100644 --- a/config-dist.php +++ b/config-dist.php @@ -1152,6 +1152,22 @@ $CFG->admin = 'admin'; // When the full classname is used, this rule always takes priority over any wildcard rules. // //========================================================================= +// 18. SITE ADMIN PRESETS +//========================================================================= +// +// The site admin presets plugin has been integrated in Moodle LMS. You can use a setting in case you +// want to apply a preset during the installation: +// +// $CFG->setsitepresetduringinstall = 'starter'; +// +// This setting accepts the following values: +// - One of the core preset names (i.e "starter" or "full"). +// - The path of a valid XML preset file, that will be imported and applied. Absolute paths are recommended, to +// guarantee the file is found: i.e."MOODLEPATH/admin/tool/admin_presets/tests/fixtures/import_settings_plugins.xml". +// +// This setting is only used during the installation process. So once the Moodle site is installed, it is ignored. +// +//========================================================================= // ALL DONE! To continue installation, visit your main page with a browser //========================================================================= diff --git a/lib/installlib.php b/lib/installlib.php index 5144936a42c..e54b6a06b9f 100644 --- a/lib/installlib.php +++ b/lib/installlib.php @@ -263,6 +263,11 @@ function install_generate_configphp($database, $cfg) { $configphp .= '$CFG->upgradekey = ' . var_export($cfg->upgradekey, true) . ';' . PHP_EOL . PHP_EOL; } + if (isset($cfg->setsitepresetduringinstall) and $cfg->setsitepresetduringinstall !== '') { + $configphp .= '$CFG->setsitepresetduringinstall = ' . var_export($cfg->setsitepresetduringinstall, true) . + ';' . PHP_EOL . PHP_EOL; + } + $configphp .= 'require_once(__DIR__ . \'/lib/setup.php\');' . PHP_EOL . PHP_EOL; $configphp .= '// There is no php closing tag in this file,' . PHP_EOL; $configphp .= '// it is intentional because it prevents trailing whitespace problems!' . PHP_EOL; @@ -525,4 +530,9 @@ function install_cli_database(array $options, $interactive) { // Redirect to site registration on first login. set_config('registrationpending', 1); + + // Apply default preset, if it is defined in $CFG and has a valid value. + if (!empty($CFG->setsitepresetduringinstall)) { + \tool_admin_presets\helper::change_default_preset($CFG->setsitepresetduringinstall); + } }