995c5489b7
Presets are stored in the DB and may contain config for plugins which have since been deprecated. This just makes sure these are skipped when trying to apply the preset.
1195 lines
55 KiB
PHP
1195 lines
55 KiB
PHP
<?php
|
|
// This file is part of Moodle - http://moodle.org/
|
|
//
|
|
// Moodle is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// Moodle is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
namespace core_adminpresets;
|
|
|
|
use memory_xml_output;
|
|
use moodle_exception;
|
|
use stdClass;
|
|
use xml_writer;
|
|
|
|
defined('MOODLE_INTERNAL') || die();
|
|
|
|
global $CFG;
|
|
require_once($CFG->libdir . '/adminlib.php');
|
|
|
|
/**
|
|
* Admin tool presets manager class.
|
|
*
|
|
* @package core_adminpresets
|
|
* @copyright 2021 Pimenko <support@pimenko.com><pimenko.com>
|
|
* @author Jordan Kesraoui | Sylvain Revenu | Pimenko based on David Monllaó <david.monllao@urv.cat> code
|
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
|
*/
|
|
class manager {
|
|
|
|
/** @var \admin_root The admin root tree with the settings. **/
|
|
private $adminroot;
|
|
|
|
/** @var array Setting classes mapping, to associated the local/setting class that should be used when there is
|
|
* no specific class. */
|
|
protected static $settingclassesmap = [
|
|
'adminpresets_admin_setting_agedigitalconsentmap' => 'adminpresets_admin_setting_configtext',
|
|
'adminpresets_admin_setting_configcolourpicker' => 'adminpresets_admin_setting_configtext',
|
|
'adminpresets_admin_setting_configdirectory' => 'adminpresets_admin_setting_configtext',
|
|
'adminpresets_admin_setting_configduration_with_advanced' => 'adminpresets_admin_setting_configtext_with_advanced',
|
|
'adminpresets_admin_setting_configduration' => 'adminpresets_admin_setting_configtext',
|
|
'adminpresets_admin_setting_configempty' => 'adminpresets_admin_setting_configtext',
|
|
'adminpresets_admin_setting_configexecutable' => 'adminpresets_admin_setting_configtext',
|
|
'adminpresets_admin_setting_configfile' => 'adminpresets_admin_setting_configtext',
|
|
'adminpresets_admin_setting_confightmleditor' => 'adminpresets_admin_setting_configtext',
|
|
'adminpresets_admin_setting_configmixedhostiplist' => 'adminpresets_admin_setting_configtext',
|
|
'adminpresets_admin_setting_configmultiselect_modules' => 'adminpresets_admin_setting_configmultiselect_with_loader',
|
|
'adminpresets_admin_setting_configpasswordunmask' => 'adminpresets_admin_setting_configtext',
|
|
'adminpresets_admin_setting_configportlist' => 'adminpresets_admin_setting_configtext',
|
|
'adminpresets_admin_setting_configselect_with_lock' => 'adminpresets_admin_setting_configselect',
|
|
'adminpresets_admin_setting_configtext_trim_lower' => 'adminpresets_admin_setting_configtext',
|
|
'adminpresets_admin_setting_configtext_with_maxlength' => 'adminpresets_admin_setting_configtext',
|
|
'adminpresets_admin_setting_configtextarea' => 'adminpresets_admin_setting_configtext',
|
|
'adminpresets_admin_setting_configthemepreset' => 'adminpresets_admin_setting_configselect',
|
|
'adminpresets_admin_setting_countrycodes' => 'adminpresets_admin_setting_configtext',
|
|
'adminpresets_admin_setting_courselist_frontpage' => 'adminpresets_admin_setting_configmultiselect_with_loader',
|
|
'adminpresets_admin_setting_description' => 'adminpresets_admin_setting_configtext',
|
|
'adminpresets_admin_setting_enablemobileservice' => 'adminpresets_admin_setting_configcheckbox',
|
|
'adminpresets_admin_setting_filetypes' => 'adminpresets_admin_setting_configtext',
|
|
'adminpresets_admin_setting_forcetimezone' => 'adminpresets_admin_setting_configselect',
|
|
'adminpresets_admin_setting_grade_profilereport' => 'adminpresets_admin_setting_configmultiselect_with_loader',
|
|
'adminpresets_admin_setting_langlist' => 'adminpresets_admin_setting_configtext',
|
|
'adminpresets_admin_setting_my_grades_report' => 'adminpresets_admin_setting_configselect',
|
|
'adminpresets_admin_setting_pickroles' => 'adminpresets_admin_setting_configmulticheckbox',
|
|
'adminpresets_admin_setting_question_behaviour' => 'adminpresets_admin_setting_configmultiselect_with_loader',
|
|
'adminpresets_admin_setting_regradingcheckbox' => 'adminpresets_admin_setting_configcheckbox',
|
|
'adminpresets_admin_setting_scsscode' => 'adminpresets_admin_setting_configtext',
|
|
'adminpresets_admin_setting_servertimezone' => 'adminpresets_admin_setting_configselect',
|
|
'adminpresets_admin_setting_sitesetcheckbox' => 'adminpresets_admin_setting_configcheckbox',
|
|
'adminpresets_admin_setting_sitesetselect' => 'adminpresets_admin_setting_configselect',
|
|
'adminpresets_admin_setting_special_adminseesall' => 'adminpresets_admin_setting_configcheckbox',
|
|
'adminpresets_admin_setting_special_backup_auto_destination' => 'adminpresets_admin_setting_configtext',
|
|
'adminpresets_admin_setting_special_coursecontact' => 'adminpresets_admin_setting_configmulticheckbox',
|
|
'adminpresets_admin_setting_special_coursemanager' => 'adminpresets_admin_setting_configmulticheckbox',
|
|
'adminpresets_admin_setting_special_debug' => 'adminpresets_admin_setting_configmultiselect_with_loader',
|
|
'adminpresets_admin_setting_special_frontpagedesc' => 'adminpresets_admin_setting_sitesettext',
|
|
'adminpresets_admin_setting_special_gradebookroles' => 'adminpresets_admin_setting_configmulticheckbox',
|
|
'adminpresets_admin_setting_special_gradeexport' => 'adminpresets_admin_setting_configmulticheckbox',
|
|
'adminpresets_admin_setting_special_gradelimiting' => 'adminpresets_admin_setting_configcheckbox',
|
|
'adminpresets_admin_setting_special_grademinmaxtouse' => 'adminpresets_admin_setting_configselect',
|
|
'adminpresets_admin_setting_special_gradepointdefault' => 'adminpresets_admin_setting_configtext',
|
|
'adminpresets_admin_setting_special_gradepointmax' => 'adminpresets_admin_setting_configtext',
|
|
'adminpresets_admin_setting_special_registerauth' => 'adminpresets_admin_setting_configmultiselect_with_loader',
|
|
'adminpresets_admin_setting_special_selectsetup' => 'adminpresets_admin_setting_configselect',
|
|
'adminpresets_admin_settings_country_select' => 'adminpresets_admin_setting_configmultiselect_with_loader',
|
|
'adminpresets_admin_settings_coursecat_select' => 'adminpresets_admin_setting_configmultiselect_with_loader',
|
|
'adminpresets_admin_settings_h5plib_handler_select' => 'adminpresets_admin_setting_configselect',
|
|
'adminpresets_admin_settings_num_course_sections' => 'adminpresets_admin_setting_configmultiselect_with_loader',
|
|
'adminpresets_admin_settings_sitepolicy_handler_select' => 'adminpresets_admin_setting_configselect',
|
|
'adminpresets_antivirus_clamav_pathtounixsocket_setting' => 'adminpresets_admin_setting_configtext',
|
|
'adminpresets_antivirus_clamav_runningmethod_setting' => 'adminpresets_admin_setting_configselect',
|
|
'adminpresets_antivirus_clamav_tcpsockethost_setting' => 'adminpresets_admin_setting_configtext',
|
|
'adminpresets_auth_db_admin_setting_special_auth_configtext' => 'adminpresets_admin_setting_configtext',
|
|
'adminpresets_auth_ldap_admin_setting_special_lowercase_configtext' => 'adminpresets_admin_setting_configtext',
|
|
'adminpresets_auth_ldap_admin_setting_special_ntlm_configtext' => 'adminpresets_admin_setting_configtext',
|
|
'adminpresets_auth_shibboleth_admin_setting_convert_data' => 'adminpresets_admin_setting_configtext',
|
|
'adminpresets_auth_shibboleth_admin_setting_special_idp_configtextarea' => 'adminpresets_admin_setting_configtext',
|
|
'adminpresets_auth_shibboleth_admin_setting_special_wayf_select' => 'adminpresets_admin_setting_configselect',
|
|
'adminpresets_editor_atto_toolbar_setting' => 'adminpresets_admin_setting_configtext',
|
|
'adminpresets_enrol_database_admin_setting_category' => 'adminpresets_admin_setting_configselect',
|
|
'adminpresets_enrol_flatfile_role_setting' => 'adminpresets_admin_setting_configtext',
|
|
'adminpresets_enrol_ldap_admin_setting_category' => 'adminpresets_admin_setting_configselect',
|
|
'adminpresets_format_singleactivity_admin_setting_activitytype' => 'adminpresets_admin_setting_configselect',
|
|
'adminpresets_qtype_multichoice_admin_setting_answernumbering' => 'adminpresets_admin_setting_configselect',
|
|
];
|
|
|
|
/** @var array Relation between database fields and XML files. **/
|
|
protected static $dbxmlrelations = [
|
|
'name' => 'NAME',
|
|
'comments' => 'COMMENTS',
|
|
'timecreated' => 'PRESET_DATE',
|
|
'site' => 'SITE_URL',
|
|
'author' => 'AUTHOR',
|
|
'moodleversion' => 'MOODLE_VERSION',
|
|
'moodlerelease' => 'MOODLE_RELEASE'
|
|
];
|
|
|
|
/** @var int Non-core preset */
|
|
public const NONCORE_PRESET = 0;
|
|
|
|
/** @var int Starter preset */
|
|
public const STARTER_PRESET = 1;
|
|
|
|
/** @var int Full preset */
|
|
public const FULL_PRESET = 2;
|
|
|
|
/**
|
|
* Gets the system settings
|
|
*
|
|
* Loads the DB $CFG->prefix.'config' values and the
|
|
* $CFG->prefix.'config_plugins' values and redirects
|
|
* the flow through $this->get_settings()
|
|
*
|
|
* @return array $settings Array format $array['plugin']['settingname'] = settings_types child class
|
|
*/
|
|
public function get_site_settings(): array {
|
|
global $DB;
|
|
|
|
// Db configs (to avoid multiple queries).
|
|
$dbconfig = $DB->get_records_select('config', '', [], '', 'name, value');
|
|
|
|
// Adding site settings in course table.
|
|
$frontpagevalues = $DB->get_record_select('course', 'id = 1',
|
|
[], 'fullname, shortname, summary');
|
|
foreach ($frontpagevalues as $field => $value) {
|
|
$dbconfig[$field] = new stdClass();
|
|
$dbconfig[$field]->name = $field;
|
|
$dbconfig[$field]->value = $value;
|
|
}
|
|
$sitedbsettings['none'] = $dbconfig;
|
|
|
|
// Config plugins.
|
|
$configplugins = $DB->get_records('config_plugins');
|
|
foreach ($configplugins as $configplugin) {
|
|
$sitedbsettings[$configplugin->plugin][$configplugin->name] = new stdClass();
|
|
$sitedbsettings[$configplugin->plugin][$configplugin->name]->name = $configplugin->name;
|
|
$sitedbsettings[$configplugin->plugin][$configplugin->name]->value = $configplugin->value;
|
|
}
|
|
// Get an array with the common format.
|
|
return $this->get_settings($sitedbsettings, true, []);
|
|
}
|
|
|
|
/**
|
|
* Constructs an array with all the system settings
|
|
*
|
|
* If a setting value can't be found on the DB it considers
|
|
* the default value as the setting value
|
|
*
|
|
* Settings without plugin are marked as 'none' in the plugin field
|
|
*
|
|
* Returns an standarized settings array format.
|
|
*
|
|
* @param array $dbsettings Standarized array,
|
|
* format $array['plugin']['name'] = obj('name'=>'settingname', 'value'=>'settingvalue')
|
|
* @param boolean $sitedbvalues Indicates if $dbsettings comes from the site db or not
|
|
* @param array $settings Array format $array['plugin']['settingname'] = settings_types child class
|
|
* @param array|false $children Array of admin_category children or false
|
|
* @return \core_adminpresets\local\setting\adminpresets_setting[][] Array format
|
|
* $array['plugin']['settingname'] = adminpresets_setting child class
|
|
*/
|
|
public function get_settings(array $dbsettings, bool $sitedbvalues = false, array $settings = [], $children = false): array {
|
|
global $DB;
|
|
|
|
// If there are no children, load admin tree and iterate through.
|
|
if (!$children) {
|
|
$this->adminroot = admin_get_root(false, true);
|
|
$children = $this->adminroot->children;
|
|
}
|
|
|
|
// Iteates through children.
|
|
foreach ($children as $key => $child) {
|
|
|
|
// We must search category children.
|
|
if (is_a($child, 'admin_category')) {
|
|
|
|
if ($child->children) {
|
|
$settings = $this->get_settings($dbsettings, $sitedbvalues, $settings, $child->children);
|
|
}
|
|
|
|
// Settings page.
|
|
} else if (is_a($child, 'admin_settingpage')) {
|
|
|
|
if (property_exists($child, 'settings')) {
|
|
|
|
foreach ($child->settings as $values) {
|
|
$settingname = $values->name;
|
|
|
|
unset($settingvalue);
|
|
|
|
// Look for his config value.
|
|
if ($values->plugin == '') {
|
|
$values->plugin = 'none';
|
|
}
|
|
|
|
if (!empty($dbsettings[$values->plugin][$settingname])) {
|
|
$settingvalue = $dbsettings[$values->plugin][$settingname]->value;
|
|
}
|
|
|
|
// If no db value found default value.
|
|
if ($sitedbvalues && !isset($settingvalue)) {
|
|
// For settings with multiple values.
|
|
if (is_array($values->defaultsetting)) {
|
|
|
|
if (isset($values->defaultsetting['value'])) {
|
|
$settingvalue = $values->defaultsetting['value'];
|
|
// Configtime case, does not have a 'value' default setting.
|
|
} else {
|
|
$settingvalue = 0;
|
|
}
|
|
} else {
|
|
$settingvalue = $values->defaultsetting;
|
|
}
|
|
}
|
|
|
|
// If there aren't any value loaded, skip that setting.
|
|
if (!isset($settingvalue)) {
|
|
continue;
|
|
}
|
|
// If there is no setting class defined continue.
|
|
if (!$setting = $this->get_setting($values, $settingvalue)) {
|
|
continue;
|
|
}
|
|
|
|
// Settings_types childs with.
|
|
// attributes provides an attributes array.
|
|
if ($attributes = $setting->get_attributes()) {
|
|
|
|
// Look for settings attributes if it is a presets.
|
|
if (!$sitedbvalues) {
|
|
$itemid = $dbsettings[$values->plugin][$settingname]->itemid;
|
|
$attrs = $DB->get_records('adminpresets_it_a',
|
|
['itemid' => $itemid], '', 'name, value');
|
|
}
|
|
foreach ($attributes as $defaultvarname => $varname) {
|
|
|
|
unset($attributevalue);
|
|
|
|
// Settings from site.
|
|
if ($sitedbvalues) {
|
|
if (!empty($dbsettings[$values->plugin][$varname])) {
|
|
$attributevalue = $dbsettings[$values->plugin][$varname]->value;
|
|
}
|
|
|
|
// Settings from a preset.
|
|
} else if (!$sitedbvalues && isset($attrs[$varname])) {
|
|
$attributevalue = $attrs[$varname]->value;
|
|
}
|
|
|
|
// If no value found, default value,
|
|
// But we may not have a default value for the attribute.
|
|
if (!isset($attributevalue) && !empty($values->defaultsetting[$defaultvarname])) {
|
|
$attributevalue = $values->defaultsetting[$defaultvarname];
|
|
}
|
|
|
|
// If there is no even a default for this setting will be empty.
|
|
// So we do nothing in this case.
|
|
if (isset($attributevalue)) {
|
|
$setting->set_attribute_value($varname, $attributevalue);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Adding to general settings array.
|
|
$settings[$values->plugin][$settingname] = $setting;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return $settings;
|
|
}
|
|
|
|
/**
|
|
* Returns the class type object
|
|
*
|
|
* @param object $settingdata Setting data
|
|
* @param mixed $currentvalue
|
|
* @return mixed
|
|
*/
|
|
public function get_setting($settingdata, $currentvalue) {
|
|
|
|
$classname = null;
|
|
|
|
// Getting the appropriate class to get the correct setting value.
|
|
$settingtype = get_class($settingdata);
|
|
// Check if it is a setting from a plugin.
|
|
$namespacedata = explode('\\', $settingtype);
|
|
if (count($namespacedata) > 1) {
|
|
$plugindata = explode('_', $namespacedata[0]);
|
|
$settingtype = end($namespacedata);
|
|
} else {
|
|
$plugindata = explode('_', $settingtype, 2);
|
|
}
|
|
|
|
$types = \core_component::get_plugin_types();
|
|
if (array_key_exists($plugindata[0], $types)) {
|
|
$plugins = \core_component::get_plugin_list($plugindata[0]);
|
|
if (array_key_exists($plugindata[1], $plugins)) {
|
|
// Check if there is a specific class for this plugin admin setting.
|
|
$settingname = 'adminpresets_' . $settingtype;
|
|
$classname = "\\$plugindata[0]_$plugindata[1]\\adminpresets\\$settingname";
|
|
if (!class_exists($classname)) {
|
|
$classname = null;
|
|
}
|
|
}
|
|
} else {
|
|
$settingname = 'adminpresets_' . $settingtype;
|
|
$classname = '\\core_adminpresets\\local\\setting\\' . $settingname;
|
|
if (!class_exists($classname)) {
|
|
// Check if there is some mapped class that should be used for this setting.
|
|
$classname = self::get_settings_class($settingname);
|
|
}
|
|
}
|
|
|
|
if (is_null($classname)) {
|
|
// Return the default setting class if there is no specific class for this setting.
|
|
$classname = '\\core_adminpresets\\local\\setting\\adminpresets_setting';
|
|
}
|
|
|
|
return new $classname($settingdata, $currentvalue);
|
|
}
|
|
|
|
/**
|
|
* Returns the settings class mapped to the defined $classname or null if it doesn't exist any associated class.
|
|
*
|
|
* @param string $classname The classname to get the mapped class.
|
|
* @return string|null
|
|
*/
|
|
public static function get_settings_class(string $classname): ?string {
|
|
if (array_key_exists($classname, self::$settingclassesmap)) {
|
|
return '\\core_adminpresets\\local\\setting\\' . self::$settingclassesmap[$classname];
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Gets the standarized settings array from DB records
|
|
*
|
|
* @param array $dbsettings Array of objects
|
|
* @return array Standarized array,
|
|
* format $array['plugin']['name'] = obj('name'=>'settingname', 'value'=>'settingvalue')
|
|
*/
|
|
public function get_settings_from_db(array $dbsettings): array {
|
|
$settings = [];
|
|
|
|
if (!$dbsettings) {
|
|
return $settings;
|
|
}
|
|
|
|
foreach ($dbsettings as $dbsetting) {
|
|
$settings[$dbsetting->plugin][$dbsetting->name] = new stdClass();
|
|
$settings[$dbsetting->plugin][$dbsetting->name]->itemid = $dbsetting->id;
|
|
$settings[$dbsetting->plugin][$dbsetting->name]->name = $dbsetting->name;
|
|
$settings[$dbsetting->plugin][$dbsetting->name]->value = $dbsetting->value;
|
|
}
|
|
|
|
return $settings;
|
|
}
|
|
|
|
|
|
/**
|
|
* Apply a given preset.
|
|
*
|
|
* @param int $presetid The preset identifier to apply.
|
|
* @param bool $simulate Whether this is a simulation or not.
|
|
* @return array List with an array with the applied settings and another with the skipped ones.
|
|
*/
|
|
public function apply_preset(int $presetid, bool $simulate = false): array {
|
|
global $DB;
|
|
|
|
if (!$DB->get_record('adminpresets', ['id' => $presetid])) {
|
|
throw new moodle_exception('errornopreset', 'core_adminpresets');
|
|
}
|
|
|
|
// Apply preset settings.
|
|
[$settingsapplied, $settingsskipped, $appid] = $this->apply_settings($presetid, $simulate);
|
|
|
|
// Set plugins visibility.
|
|
[$pluginsapplied, $pluginsskipped] = $this->apply_plugins($presetid, $simulate, $appid);
|
|
|
|
$applied = array_merge($settingsapplied, $pluginsapplied);
|
|
$skipped = array_merge($settingsskipped, $pluginsskipped);
|
|
|
|
if (!$simulate) {
|
|
// Store it in a config setting as the last preset applied.
|
|
set_config('lastpresetapplied', $presetid, 'adminpresets');
|
|
}
|
|
|
|
return [$applied, $skipped];
|
|
}
|
|
|
|
/**
|
|
* Create a preset with the current settings and plugins information.
|
|
*
|
|
* @param \stdClass $data Preset info, such as name or description, to be used when creating the preset with the current
|
|
* settings and plugins.
|
|
* @return array List with an the presetid created (int), a boolean to define if any setting has been found and
|
|
* another boolean to specify if any plugin has been found.
|
|
*/
|
|
public function export_preset(stdClass $data): array {
|
|
global $DB;
|
|
|
|
// Admin_preset record.
|
|
$presetdata = [
|
|
'name' => $data->name ?? '',
|
|
'comments' => !empty($data->comments) ? $data->comments['text'] : '',
|
|
'author' => $data->author ?? '',
|
|
];
|
|
if (!$presetid = helper::create_preset($presetdata)) {
|
|
throw new moodle_exception('errorinserting', 'core_adminpresets');
|
|
}
|
|
|
|
// Store settings.
|
|
$settingsfound = false;
|
|
|
|
// Site settings.
|
|
$sitesettings = $this->get_site_settings();
|
|
|
|
// Sensible settings.
|
|
$sensiblesettings = explode(',', str_replace(' ', '', get_config('adminpresets', 'sensiblesettings')));
|
|
$sensiblesettings = array_combine($sensiblesettings, $sensiblesettings);
|
|
foreach ($sitesettings as $plugin => $pluginsettings) {
|
|
foreach ($pluginsettings as $settingname => $sitesetting) {
|
|
// Avoid sensible data.
|
|
if (empty($data->includesensiblesettings) && !empty($sensiblesettings["$settingname@@$plugin"])) {
|
|
continue;
|
|
}
|
|
|
|
$setting = new stdClass();
|
|
$setting->adminpresetid = $presetid;
|
|
$setting->plugin = $plugin;
|
|
$setting->name = $settingname;
|
|
$setting->value = $sitesetting->get_value();
|
|
if (!$setting->id = $DB->insert_record('adminpresets_it', $setting)) {
|
|
throw new moodle_exception('errorinserting', 'core_adminpresets');
|
|
}
|
|
|
|
// Setting attributes must also be exported.
|
|
if ($attributes = $sitesetting->get_attributes_values()) {
|
|
foreach ($attributes as $attname => $attvalue) {
|
|
$attr = new stdClass();
|
|
$attr->itemid = $setting->id;
|
|
$attr->name = $attname;
|
|
$attr->value = $attvalue;
|
|
|
|
$DB->insert_record('adminpresets_it_a', $attr);
|
|
}
|
|
}
|
|
$settingsfound = true;
|
|
}
|
|
}
|
|
|
|
// Store plugins visibility (enabled/disabled).
|
|
$pluginsfound = false;
|
|
$pluginmanager = \core_plugin_manager::instance();
|
|
$types = $pluginmanager->get_plugin_types();
|
|
foreach ($types as $plugintype => $notused) {
|
|
$plugins = $pluginmanager->get_present_plugins($plugintype);
|
|
$pluginclass = \core_plugin_manager::resolve_plugininfo_class($plugintype);
|
|
if (!empty($plugins)) {
|
|
foreach ($plugins as $pluginname => $plugin) {
|
|
$entry = new stdClass();
|
|
$entry->adminpresetid = $presetid;
|
|
$entry->plugin = $plugintype;
|
|
$entry->name = $pluginname;
|
|
$entry->enabled = $pluginclass::get_enabled_plugin($pluginname);
|
|
|
|
$DB->insert_record('adminpresets_plug', $entry);
|
|
$pluginsfound = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
// If there are no settings nor plugins, the admin preset record should be removed.
|
|
if (!$settingsfound && !$pluginsfound) {
|
|
$DB->delete_records('adminpresets', ['id' => $presetid]);
|
|
$presetid = null;
|
|
}
|
|
|
|
return [$presetid, $settingsfound, $pluginsfound];
|
|
}
|
|
|
|
/**
|
|
* Create the XML content for a given preset.
|
|
*
|
|
* @param int $presetid The preset to download.
|
|
* @return array List with the XML content (string) and a filename proposal based on the preset name (string).
|
|
*/
|
|
public function download_preset(int $presetid): array {
|
|
global $DB;
|
|
|
|
if (!$preset = $DB->get_record('adminpresets', ['id' => $presetid])) {
|
|
throw new moodle_exception('errornopreset', 'core_adminpresets');
|
|
}
|
|
|
|
// Start.
|
|
$xmloutput = new memory_xml_output();
|
|
$xmlwriter = new xml_writer($xmloutput);
|
|
$xmlwriter->start();
|
|
|
|
// Preset data.
|
|
$xmlwriter->begin_tag('PRESET');
|
|
foreach (static::$dbxmlrelations as $dbname => $xmlname) {
|
|
$xmlwriter->full_tag($xmlname, $preset->$dbname);
|
|
}
|
|
|
|
// We ride through the settings array.
|
|
$items = $DB->get_records('adminpresets_it', ['adminpresetid' => $preset->id]);
|
|
$allsettings = $this->get_settings_from_db($items);
|
|
if ($allsettings) {
|
|
$xmlwriter->begin_tag('ADMIN_SETTINGS');
|
|
|
|
foreach ($allsettings as $plugin => $settings) {
|
|
$tagname = strtoupper($plugin);
|
|
|
|
// To aviod xml slash problems.
|
|
if (strstr($tagname, '/') != false) {
|
|
$tagname = str_replace('/', '__', $tagname);
|
|
}
|
|
|
|
$xmlwriter->begin_tag($tagname);
|
|
|
|
// One tag for each plugin setting.
|
|
if (!empty($settings)) {
|
|
$xmlwriter->begin_tag('SETTINGS');
|
|
foreach ($settings as $setting) {
|
|
// Unset the tag attributes string.
|
|
$attributes = [];
|
|
|
|
// Getting setting attributes, if present.
|
|
$attrs = $DB->get_records('adminpresets_it_a', ['itemid' => $setting->itemid]);
|
|
if ($attrs) {
|
|
foreach ($attrs as $attr) {
|
|
$attributes[$attr->name] = $attr->value;
|
|
}
|
|
}
|
|
|
|
$xmlwriter->full_tag(strtoupper($setting->name), $setting->value, $attributes);
|
|
}
|
|
|
|
$xmlwriter->end_tag('SETTINGS');
|
|
}
|
|
|
|
$xmlwriter->end_tag(strtoupper($tagname));
|
|
}
|
|
|
|
$xmlwriter->end_tag('ADMIN_SETTINGS');
|
|
}
|
|
|
|
// We ride through the plugins array.
|
|
$data = $DB->get_records('adminpresets_plug', ['adminpresetid' => $preset->id]);
|
|
if ($data) {
|
|
$plugins = [];
|
|
foreach ($data as $plugin) {
|
|
$plugins[$plugin->plugin][] = $plugin;
|
|
}
|
|
|
|
$xmlwriter->begin_tag('PLUGINS');
|
|
|
|
foreach ($plugins as $plugintype => $plugintypes) {
|
|
$tagname = strtoupper($plugintype);
|
|
$xmlwriter->begin_tag($tagname);
|
|
|
|
foreach ($plugintypes as $plugin) {
|
|
$xmlwriter->full_tag(strtoupper($plugin->name), $plugin->enabled);
|
|
}
|
|
|
|
$xmlwriter->end_tag(strtoupper($tagname));
|
|
}
|
|
|
|
$xmlwriter->end_tag('PLUGINS');
|
|
}
|
|
|
|
// End.
|
|
$xmlwriter->end_tag('PRESET');
|
|
$xmlwriter->stop();
|
|
$xmlstr = $xmloutput->get_allcontents();
|
|
|
|
$filename = addcslashes($preset->name, '"') . '.xml';
|
|
|
|
return [$xmlstr, $filename];
|
|
}
|
|
|
|
/**
|
|
* Import a given XML preset.
|
|
*
|
|
* @param string $xmlcontent The XML context with the preset to be imported.
|
|
* @param string|null $presetname The preset name that will overwrite the one given in the XML file.
|
|
* @return array List with an the XML element (SimpleXMLElement|null), the imported preset (stdClass|null), a boolean
|
|
* to define if any setting has been found and another boolean to specify if any plugin has been found.
|
|
*/
|
|
public function import_preset(string $xmlcontent, ?string $presetname = null): array {
|
|
global $DB, $USER;
|
|
|
|
$settingsfound = false;
|
|
$pluginsfound = false;
|
|
|
|
try {
|
|
$xml = simplexml_load_string($xmlcontent);
|
|
} catch (\Exception $exception) {
|
|
$xml = false;
|
|
}
|
|
if (!$xml) {
|
|
return [null, null, $settingsfound, $pluginsfound];
|
|
}
|
|
|
|
// Prepare the preset info.
|
|
$preset = new stdClass();
|
|
foreach (static::$dbxmlrelations as $dbname => $xmlname) {
|
|
$preset->$dbname = (String) $xml->$xmlname;
|
|
}
|
|
$preset->userid = $USER->id;
|
|
$preset->timeimported = time();
|
|
|
|
// Overwrite preset name.
|
|
if (!empty($presetname)) {
|
|
$preset->name = $presetname;
|
|
}
|
|
|
|
// Create the preset.
|
|
if (!$preset->id = $DB->insert_record('adminpresets', $preset)) {
|
|
throw new moodle_exception('errorinserting', 'core_adminpresets');
|
|
}
|
|
|
|
// Process settings.
|
|
$sitesettings = $this->get_site_settings();
|
|
$xmladminsettings = $xml->ADMIN_SETTINGS[0];
|
|
foreach ($xmladminsettings as $plugin => $settings) {
|
|
$plugin = strtolower($plugin);
|
|
if (strstr($plugin, '__') != false) {
|
|
$plugin = str_replace('__', '/', $plugin);
|
|
}
|
|
|
|
$pluginsettings = $settings->SETTINGS[0];
|
|
if ($pluginsettings) {
|
|
foreach ($pluginsettings->children() as $name => $setting) {
|
|
$name = strtolower($name);
|
|
|
|
// Default to ''.
|
|
if ($setting->__toString() === false) {
|
|
$value = '';
|
|
} else {
|
|
$value = $setting->__toString();
|
|
}
|
|
|
|
if (empty($sitesettings[$plugin][$name])) {
|
|
debugging('Setting ' . $plugin . '/' . $name . ' not supported by this Moodle version', DEBUG_DEVELOPER);
|
|
continue;
|
|
}
|
|
|
|
// Cleaning the setting value.
|
|
if (!$presetsetting = $this->get_setting($sitesettings[$plugin][$name]->get_settingdata(), $value)) {
|
|
debugging('Setting ' . $plugin . '/' . $name . ' not implemented', DEBUG_DEVELOPER);
|
|
continue;
|
|
}
|
|
|
|
$settingsfound = true;
|
|
|
|
// New item.
|
|
$item = new stdClass();
|
|
$item->adminpresetid = $preset->id;
|
|
$item->plugin = $plugin;
|
|
$item->name = $name;
|
|
$item->value = $presetsetting->get_value();
|
|
|
|
// Insert preset item.
|
|
if (!$item->id = $DB->insert_record('adminpresets_it', $item)) {
|
|
throw new moodle_exception('errorinserting', 'core_adminpresets');
|
|
}
|
|
|
|
// Add setting attributes.
|
|
if ($setting->attributes() && ($itemattributes = $presetsetting->get_attributes())) {
|
|
foreach ($setting->attributes() as $attrname => $attrvalue) {
|
|
$itemattributenames = array_flip($itemattributes);
|
|
|
|
// Check the attribute existence.
|
|
if (!isset($itemattributenames[$attrname])) {
|
|
debugging('The ' . $plugin . '/' . $name . ' attribute ' . $attrname .
|
|
' is not supported by this Moodle version', DEBUG_DEVELOPER);
|
|
continue;
|
|
}
|
|
|
|
$attr = new stdClass();
|
|
$attr->itemid = $item->id;
|
|
$attr->name = $attrname;
|
|
$attr->value = $attrvalue->__toString();
|
|
$DB->insert_record('adminpresets_it_a', $attr);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Process plugins.
|
|
if ($xml->PLUGINS) {
|
|
$xmlplugins = $xml->PLUGINS[0];
|
|
foreach ($xmlplugins as $plugin => $plugins) {
|
|
$pluginname = strtolower($plugin);
|
|
foreach ($plugins->children() as $name => $plugin) {
|
|
$pluginsfound = true;
|
|
|
|
// New plugin.
|
|
$entry = new stdClass();
|
|
$entry->adminpresetid = $preset->id;
|
|
$entry->plugin = $pluginname;
|
|
$entry->name = strtolower($name);
|
|
$entry->enabled = $plugin->__toString();
|
|
|
|
// Insert plugin.
|
|
if (!$entry->id = $DB->insert_record('adminpresets_plug', $entry)) {
|
|
throw new moodle_exception('errorinserting', 'core_adminpresets');
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// If there are no valid or selected settings we should delete the admin preset record.
|
|
if (!$settingsfound && !$pluginsfound) {
|
|
$DB->delete_records('adminpresets', ['id' => $preset->id]);
|
|
$preset = null;
|
|
}
|
|
|
|
return [$xml, $preset, $settingsfound, $pluginsfound];
|
|
}
|
|
|
|
/**
|
|
* Delete given preset.
|
|
*
|
|
* @param int $presetid Preset identifier to delete.
|
|
* @return void
|
|
*/
|
|
public function delete_preset(int $presetid): void {
|
|
global $DB;
|
|
|
|
// Check the preset exists (cannot delete the pre-installed core "Starter" and "Full" presets).
|
|
$preset = $DB->get_record('adminpresets', ['id' => $presetid, 'iscore' => self::NONCORE_PRESET]);
|
|
if (!$preset) {
|
|
throw new moodle_exception('errordeleting', 'core_adminpresets');
|
|
}
|
|
|
|
// Deleting the preset applications.
|
|
if ($previouslyapplied = $DB->get_records('adminpresets_app', ['adminpresetid' => $presetid], 'id')) {
|
|
$appids = array_keys($previouslyapplied);
|
|
list($insql, $inparams) = $DB->get_in_or_equal($appids);
|
|
$DB->delete_records_select('adminpresets_app_it', "adminpresetapplyid $insql", $inparams);
|
|
$DB->delete_records_select('adminpresets_app_it_a', "adminpresetapplyid $insql", $inparams);
|
|
$DB->delete_records_select('adminpresets_app_plug', "adminpresetapplyid $insql", $inparams);
|
|
|
|
if (!$DB->delete_records('adminpresets_app', ['adminpresetid' => $presetid])) {
|
|
throw new moodle_exception('errordeleting', 'core_adminpresets');
|
|
}
|
|
}
|
|
|
|
// Getting items ids and remove advanced items associated to them.
|
|
$items = $DB->get_records('adminpresets_it', ['adminpresetid' => $presetid], 'id');
|
|
if (!empty($items)) {
|
|
$itemsid = array_keys($items);
|
|
list($insql, $inparams) = $DB->get_in_or_equal($itemsid);
|
|
$DB->delete_records_select('adminpresets_it_a', "itemid $insql", $inparams);
|
|
}
|
|
|
|
if (!$DB->delete_records('adminpresets_it', ['adminpresetid' => $presetid])) {
|
|
throw new moodle_exception('errordeleting', 'core_adminpresets');
|
|
}
|
|
|
|
// Delete plugins.
|
|
if (!$DB->delete_records('adminpresets_plug', ['adminpresetid' => $presetid])) {
|
|
throw new moodle_exception('errordeleting', 'core_adminpresets');
|
|
}
|
|
|
|
// Delete preset.
|
|
if (!$DB->delete_records('adminpresets', ['id' => $presetid])) {
|
|
throw new moodle_exception('errordeleting', 'core_adminpresets');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Revert a given preset applied previously.
|
|
* It backs settings and plugins to their original state before applying the presset and removes
|
|
* the applied preset information from DB.
|
|
*
|
|
* @param int $presetappid The appplied preset identifier to be reverted.
|
|
* @return array List with the presetapp removed (or null if there was some error), an array with the rollback settings/plugins
|
|
* changed and an array with the failures.
|
|
*/
|
|
public function revert_preset(int $presetappid): array {
|
|
global $DB;
|
|
|
|
// To store rollback results.
|
|
$presetapp = null;
|
|
$rollback = [];
|
|
$failures = [];
|
|
|
|
// Actual settings.
|
|
$sitesettings = $this->get_site_settings();
|
|
|
|
if (!$DB->get_record('adminpresets_app', ['id' => $presetappid])) {
|
|
throw new moodle_exception('wrongid', 'core_adminpresets');
|
|
}
|
|
|
|
// Items.
|
|
$itemsql = "SELECT cl.id, cl.plugin, cl.name, cl.value, cl.oldvalue, ap.adminpresetapplyid
|
|
FROM {adminpresets_app_it} ap
|
|
JOIN {config_log} cl ON cl.id = ap.configlogid
|
|
WHERE ap.adminpresetapplyid = :presetid";
|
|
$itemchanges = $DB->get_records_sql($itemsql, ['presetid' => $presetappid]);
|
|
if ($itemchanges) {
|
|
foreach ($itemchanges as $change) {
|
|
if ($change->plugin == '') {
|
|
$change->plugin = 'none';
|
|
}
|
|
|
|
// Admin setting.
|
|
if (!empty($sitesettings[$change->plugin][$change->name])) {
|
|
$actualsetting = $sitesettings[$change->plugin][$change->name];
|
|
$oldsetting = $this->get_setting($actualsetting->get_settingdata(), $change->oldvalue);
|
|
|
|
$visiblepluginname = $oldsetting->get_settingdata()->plugin;
|
|
if ($visiblepluginname == 'none') {
|
|
$visiblepluginname = 'core';
|
|
}
|
|
$contextdata = [
|
|
'plugin' => $visiblepluginname,
|
|
'visiblename' => $oldsetting->get_settingdata()->visiblename,
|
|
'oldvisiblevalue' => $actualsetting->get_visiblevalue(),
|
|
'visiblevalue' => $oldsetting->get_visiblevalue()
|
|
];
|
|
|
|
// Check if the actual value is the same set by the preset.
|
|
if ($change->value == $actualsetting->get_value()) {
|
|
$oldsetting->save_value();
|
|
|
|
// Output table.
|
|
$rollback[] = $contextdata;
|
|
|
|
// Deleting the adminpreset applied item instance.
|
|
$deletewhere = [
|
|
'adminpresetapplyid' => $change->adminpresetapplyid,
|
|
'configlogid' => $change->id,
|
|
];
|
|
$DB->delete_records('adminpresets_app_it', $deletewhere);
|
|
|
|
} else {
|
|
$failures[] = $contextdata;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Attributes.
|
|
$attrsql = "SELECT cl.id, cl.plugin, cl.name, cl.value, cl.oldvalue, ap.itemname, ap.adminpresetapplyid
|
|
FROM {adminpresets_app_it_a} ap
|
|
JOIN {config_log} cl ON cl.id = ap.configlogid
|
|
WHERE ap.adminpresetapplyid = :presetid";
|
|
$attrchanges = $DB->get_records_sql($attrsql, ['presetid' => $presetappid]);
|
|
if ($attrchanges) {
|
|
foreach ($attrchanges as $change) {
|
|
if ($change->plugin == '') {
|
|
$change->plugin = 'none';
|
|
}
|
|
|
|
// Admin setting of the attribute item.
|
|
if (!empty($sitesettings[$change->plugin][$change->itemname])) {
|
|
// Getting the attribute item.
|
|
$actualsetting = $sitesettings[$change->plugin][$change->itemname];
|
|
|
|
$oldsetting = $this->get_setting($actualsetting->get_settingdata(), $actualsetting->get_value());
|
|
$oldsetting->set_attribute_value($change->name, $change->oldvalue);
|
|
|
|
$varname = $change->plugin . '_' . $change->name;
|
|
|
|
// Check if the actual value is the same set by the preset.
|
|
$actualattributes = $actualsetting->get_attributes_values();
|
|
if ($change->value == $actualattributes[$change->name]) {
|
|
$oldsetting->save_attributes_values();
|
|
|
|
// Output table.
|
|
$visiblepluginname = $oldsetting->get_settingdata()->plugin;
|
|
if ($visiblepluginname == 'none') {
|
|
$visiblepluginname = 'core';
|
|
}
|
|
$rollback[] = [
|
|
'plugin' => $visiblepluginname,
|
|
'visiblename' => $oldsetting->get_settingdata()->visiblename,
|
|
'oldvisiblevalue' => $actualsetting->get_visiblevalue(),
|
|
'visiblevalue' => $oldsetting->get_visiblevalue()
|
|
];
|
|
|
|
// Deleting the adminpreset applied item attribute instance.
|
|
$deletewhere = [
|
|
'adminpresetapplyid' => $change->adminpresetapplyid,
|
|
'configlogid' => $change->id,
|
|
];
|
|
$DB->delete_records('adminpresets_app_it_a', $deletewhere);
|
|
|
|
} else {
|
|
$visiblepluginname = $oldsetting->get_settingdata()->plugin;
|
|
if ($visiblepluginname == 'none') {
|
|
$visiblepluginname = 'core';
|
|
}
|
|
$failures[] = [
|
|
'plugin' => $visiblepluginname,
|
|
'visiblename' => $oldsetting->get_settingdata()->visiblename,
|
|
'oldvisiblevalue' => $actualsetting->get_visiblevalue(),
|
|
'visiblevalue' => $oldsetting->get_visiblevalue()
|
|
];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Plugins.
|
|
$plugins = $DB->get_records('adminpresets_app_plug', ['adminpresetapplyid' => $presetappid]);
|
|
if ($plugins) {
|
|
$pluginmanager = \core_plugin_manager::instance();
|
|
foreach ($plugins as $plugin) {
|
|
$pluginclass = \core_plugin_manager::resolve_plugininfo_class($plugin->plugin);
|
|
$pluginclass::enable_plugin($plugin->name, (int) $plugin->oldvalue);
|
|
|
|
// Get the plugininfo object for this plugin, to get its proper visible name.
|
|
$plugininfo = $pluginmanager->get_plugin_info($plugin->plugin . '_' . $plugin->name);
|
|
if ($plugininfo != null) {
|
|
$visiblename = $plugininfo->displayname;
|
|
} else {
|
|
$visiblename = $plugin->plugin . '_' . $plugin->name;
|
|
}
|
|
|
|
// Output table.
|
|
$rollback[] = [
|
|
'plugin' => $plugin->plugin,
|
|
'visiblename' => $visiblename,
|
|
'oldvisiblevalue' => $plugin->value,
|
|
'visiblevalue' => $plugin->oldvalue,
|
|
];
|
|
}
|
|
$DB->delete_records('adminpresets_app_plug', ['adminpresetapplyid' => $presetappid]);
|
|
}
|
|
|
|
// Delete application if no items nor attributes nor plugins of the application remains.
|
|
if (!$DB->get_records('adminpresets_app_it', ['adminpresetapplyid' => $presetappid]) &&
|
|
!$DB->get_records('adminpresets_app_it_a', ['adminpresetapplyid' => $presetappid]) &&
|
|
!$DB->get_records('adminpresets_app_plug', ['adminpresetapplyid' => $presetappid])) {
|
|
|
|
$presetapp = $DB->get_record('adminpresets_app', ['id' => $presetappid]);
|
|
$DB->delete_records('adminpresets_app', ['id' => $presetappid]);
|
|
}
|
|
|
|
return [$presetapp, $rollback, $failures];
|
|
}
|
|
|
|
/**
|
|
* Apply settings from a preset.
|
|
*
|
|
* @param int $presetid The preset identifier to apply.
|
|
* @param bool $simulate Whether this is a simulation or not.
|
|
* @param int|null $adminpresetapplyid The identifier of the adminpresetapply or null if it hasn't been created previously.
|
|
* @return array List with an array with the applied settings, another with the skipped ones and the adminpresetapplyid.
|
|
*/
|
|
protected function apply_settings(int $presetid, bool $simulate = false, ?int $adminpresetapplyid = null): array {
|
|
global $DB, $USER;
|
|
|
|
$applied = [];
|
|
$skipped = [];
|
|
if (!$items = $DB->get_records('adminpresets_it', ['adminpresetid' => $presetid])) {
|
|
return [$applied, $skipped, $adminpresetapplyid];
|
|
}
|
|
|
|
$presetdbsettings = $this->get_settings_from_db($items);
|
|
// Standarized format: $array['plugin']['settingname'] = child class.
|
|
$presetsettings = $this->get_settings($presetdbsettings, false, []);
|
|
|
|
// Standarized format: $array['plugin']['settingname'] = child class.
|
|
$siteavailablesettings = $this->get_site_settings();
|
|
|
|
// Set settings values.
|
|
foreach ($presetsettings as $plugin => $pluginsettings) {
|
|
foreach ($pluginsettings as $settingname => $presetsetting) {
|
|
$updatesetting = false;
|
|
|
|
// Current value (which will become old value if the setting is legit to be applied).
|
|
$sitesetting = $siteavailablesettings[$plugin][$settingname];
|
|
|
|
// Wrong setting, set_value() method has previously cleaned the value.
|
|
if ($sitesetting->get_value() === false) {
|
|
debugging($presetsetting->get_settingdata()->plugin . '/' . $presetsetting->get_settingdata()->name .
|
|
' setting has a wrong value!', DEBUG_DEVELOPER);
|
|
continue;
|
|
}
|
|
|
|
// If the new value is different the setting must be updated.
|
|
if ($presetsetting->get_value() != $sitesetting->get_value()) {
|
|
$updatesetting = true;
|
|
}
|
|
|
|
// If one of the setting attributes values is different, setting must also be updated.
|
|
if ($presetsetting->get_attributes_values()) {
|
|
|
|
$siteattributesvalues = $presetsetting->get_attributes_values();
|
|
foreach ($presetsetting->get_attributes_values() as $attributename => $attributevalue) {
|
|
|
|
if ($attributevalue !== $siteattributesvalues[$attributename]) {
|
|
$updatesetting = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
$visiblepluginname = $presetsetting->get_settingdata()->plugin;
|
|
if ($visiblepluginname == 'none') {
|
|
$visiblepluginname = 'core';
|
|
}
|
|
$data = [
|
|
'plugin' => $visiblepluginname,
|
|
'visiblename' => $presetsetting->get_settingdata()->visiblename,
|
|
'visiblevalue' => $presetsetting->get_visiblevalue(),
|
|
];
|
|
|
|
// Saving data.
|
|
if ($updatesetting) {
|
|
// The preset application it's only saved when differences (in their values) are found.
|
|
if (empty($applieditem)) {
|
|
// Save the preset application and store the preset applied id.
|
|
$presetapplied = new stdClass();
|
|
$presetapplied->adminpresetid = $presetid;
|
|
$presetapplied->userid = $USER->id;
|
|
$presetapplied->time = time();
|
|
if (!$simulate && !$adminpresetapplyid = $DB->insert_record('adminpresets_app', $presetapplied)) {
|
|
throw new moodle_exception('errorinserting', 'core_adminpresets');
|
|
}
|
|
}
|
|
|
|
// Implemented this way because the config_write method of admin_setting class does not return the
|
|
// config_log inserted id.
|
|
$applieditem = new stdClass();
|
|
$applieditem->adminpresetapplyid = $adminpresetapplyid;
|
|
if (!$simulate && $applieditem->configlogid = $presetsetting->save_value()) {
|
|
$DB->insert_record('adminpresets_app_it', $applieditem);
|
|
}
|
|
|
|
// For settings with multiple values.
|
|
if (!$simulate && $attributeslogids = $presetsetting->save_attributes_values()) {
|
|
foreach ($attributeslogids as $attributelogid) {
|
|
$applieditemattr = new stdClass();
|
|
$applieditemattr->adminpresetapplyid = $applieditem->adminpresetapplyid;
|
|
$applieditemattr->configlogid = $attributelogid;
|
|
$applieditemattr->itemname = $presetsetting->get_settingdata()->name;
|
|
$DB->insert_record('adminpresets_app_it_a', $applieditemattr);
|
|
}
|
|
}
|
|
|
|
// Added to changed values.
|
|
$data['oldvisiblevalue'] = $sitesetting->get_visiblevalue();
|
|
$applied[] = $data;
|
|
} else {
|
|
// Unnecessary changes (actual setting value).
|
|
$skipped[] = $data;
|
|
}
|
|
}
|
|
}
|
|
return [$applied, $skipped, $adminpresetapplyid];
|
|
}
|
|
|
|
/**
|
|
* Apply plugins from a preset.
|
|
*
|
|
* @param int $presetid The preset identifier to apply.
|
|
* @param bool $simulate Whether this is a simulation or not.
|
|
* @param int|null $adminpresetapplyid The identifier of the adminpresetapply or null if it hasn't been created previously.
|
|
* @return array List with an array with the applied settings, another with the skipped ones and the adminpresetapplyid.
|
|
*/
|
|
protected function apply_plugins(int $presetid, bool $simulate = false, ?int $adminpresetapplyid = null): array {
|
|
global $DB, $USER;
|
|
|
|
$applied = [];
|
|
$skipped = [];
|
|
|
|
$strenabled = get_string('enabled', 'core_adminpresets');
|
|
$strdisabled = get_string('disabled', 'core_adminpresets');
|
|
|
|
$plugins = $DB->get_records('adminpresets_plug', ['adminpresetid' => $presetid]);
|
|
$pluginmanager = \core_plugin_manager::instance();
|
|
foreach ($plugins as $plugin) {
|
|
$pluginclass = \core_plugin_manager::resolve_plugininfo_class($plugin->plugin);
|
|
$oldvalue = $pluginclass::get_enabled_plugin($plugin->name);
|
|
|
|
// Get the plugininfo object for this plugin, to get its proper visible name.
|
|
$plugininfo = $pluginmanager->get_plugin_info($plugin->plugin . '_' . $plugin->name);
|
|
if ($plugininfo != null) {
|
|
$visiblename = $plugininfo->displayname;
|
|
} else {
|
|
$visiblename = $plugin->plugin . '_' . $plugin->name;
|
|
}
|
|
|
|
if ($plugin->enabled > 0) {
|
|
$visiblevalue = $strenabled;
|
|
} else if ($plugin->enabled == 0) {
|
|
$visiblevalue = $strdisabled;
|
|
} else {
|
|
$visiblevalue = get_string('disabledwithvalue', 'core_adminpresets', $plugin->enabled);
|
|
}
|
|
|
|
$data = [
|
|
'plugin' => $plugin->plugin,
|
|
'visiblename' => $visiblename,
|
|
'visiblevalue' => $visiblevalue,
|
|
];
|
|
|
|
if ($plugininfo && $plugininfo->is_deprecated()) {
|
|
$skipped[] = $data;
|
|
continue;
|
|
}
|
|
|
|
if ($pluginclass == '\core\plugininfo\orphaned') {
|
|
$skipped[] = $data;
|
|
continue;
|
|
}
|
|
|
|
// Only change the plugin visibility if it's different to current value.
|
|
if (($plugin->enabled != $oldvalue) && (($plugin->enabled > 0 && !$oldvalue) || ($plugin->enabled < 1 && $oldvalue))) {
|
|
try {
|
|
if (!$simulate) {
|
|
$pluginclass::enable_plugin($plugin->name, $plugin->enabled);
|
|
|
|
// The preset application it's only saved when values differences are found.
|
|
if (empty($adminpresetapplyid)) {
|
|
// Save the preset application and store the preset applied id.
|
|
$presetapplied = new stdClass();
|
|
$presetapplied->adminpresetid = $presetid;
|
|
$presetapplied->userid = $USER->id;
|
|
$presetapplied->time = time();
|
|
if (!$adminpresetapplyid = $DB->insert_record('adminpresets_app', $presetapplied)) {
|
|
throw new moodle_exception('errorinserting', 'core_adminpresets');
|
|
}
|
|
}
|
|
|
|
// Add plugin to aplied plugins table (for being able to restore in the future if required).
|
|
$appliedplug = new stdClass();
|
|
$appliedplug->adminpresetapplyid = $adminpresetapplyid;
|
|
$appliedplug->plugin = $plugin->plugin;
|
|
$appliedplug->name = $plugin->name;
|
|
$appliedplug->value = $plugin->enabled;
|
|
$appliedplug->oldvalue = $oldvalue;
|
|
$DB->insert_record('adminpresets_app_plug', $appliedplug);
|
|
}
|
|
|
|
if ($oldvalue > 0) {
|
|
$oldvisiblevalue = $strenabled;
|
|
} else if ($oldvalue == 0) {
|
|
$oldvisiblevalue = $strdisabled;
|
|
} else {
|
|
$oldvisiblevalue = get_string('disabledwithvalue', 'core_adminpresets', $oldvalue);
|
|
}
|
|
$data['oldvisiblevalue'] = $oldvisiblevalue;
|
|
$applied[] = $data;
|
|
} catch (\exception $e) {
|
|
$skipped[] = $data;
|
|
}
|
|
} else {
|
|
$skipped[] = $data;
|
|
}
|
|
}
|
|
|
|
return [$applied, $skipped, $adminpresetapplyid];
|
|
}
|
|
|
|
}
|