mirror of
https://github.com/moodle/moodle.git
synced 2025-02-25 04:23:22 +01:00
1190 lines
54 KiB
PHP
1190 lines
54 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 ($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];
|
|
}
|
|
|
|
}
|