diff --git a/config-dist.php b/config-dist.php index d03ab4c0320..bbb90587715 100644 --- a/config-dist.php +++ b/config-dist.php @@ -399,6 +399,21 @@ $CFG->admin = 'admin'; // Since 2.0 sql queries are not shown during upgrade by default. // Please note that this setting may produce very long upgrade page on large sites. // $CFG->upgradeshowsql = true; // NOT FOR PRODUCTION SERVERS! +// +//========================================================================= +// 9. FORCED SETTINGS +//========================================================================= +// It is possible to specify normal admin settings here, the point is that +// they can not be changed through the standard admin settings pages any more. +// +// Core settings are specified directly via assignment to $CFG variable. +// Example: +// $CFG->somecoresetting = 'value'; +// +// Plugin settings have to be put into a special array. +// Example: +// $CFG->forced_plugin_settings = array('pluginname' => array('settingname' => 'value', 'secondsetting' => 'othervalue'), +// 'otherplugin' => array('mysetting' => 'myvalue', 'thesetting' => 'thevalue')); //========================================================================= diff --git a/lib/adminlib.php b/lib/adminlib.php index 0e9a21beadf..25785d30c7c 100644 --- a/lib/adminlib.php +++ b/lib/adminlib.php @@ -5718,10 +5718,15 @@ function format_admin_setting($setting, $title='', $form='', $description='', $l $labelfor = ''; } - if (empty($setting->plugin) and array_key_exists($setting->name, $CFG->config_php_settings)) { - $override = '
'.get_string('configoverride', 'admin').'
'; + $override = ''; + if (empty($setting->plugin)) { + if (array_key_exists($setting->name, $CFG->config_php_settings)) { + $override = '
'.get_string('configoverride', 'admin').'
'; + } } else { - $override = ''; + if (array_key_exists($setting->plugin, $CFG->forced_plugin_settings) and array_key_exists($setting->name, $CFG->forced_plugin_settings[$setting->plugin])) { + $override = '
'.get_string('configoverride', 'admin').'
'; + } } if ($warning !== '') { diff --git a/lib/moodlelib.php b/lib/moodlelib.php index 02c6dd6da81..dad6b677f18 100644 --- a/lib/moodlelib.php +++ b/lib/moodlelib.php @@ -935,58 +935,71 @@ function set_config($name, $value, $plugin=NULL) { * Get configuration values from the global config table * or the config_plugins table. * - * If called with no parameters it will do the right thing - * generating $CFG safely from the database without overwriting - * existing values. - * * If called with one parameter, it will load all the config - * variables for one pugin, and return them as an object. + * variables for one plugin, and return them as an object. * - * If called with 2 parameters it will return a $string single - * value or false of the value is not found. + * If called with 2 parameters it will return a string single + * value or false if the value is not found. * - * @global object - * @param string $plugin default NULL + * @param string $plugin full component name * @param string $name default NULL * @return mixed hash-like object or single value, return false no config found */ -function get_config($plugin=NULL, $name=NULL) { +function get_config($plugin, $name = NULL) { global $CFG, $DB; + // normalise component name + if ($plugin === 'moodle' or $plugin === 'core') { + $plugin = NULL; + } + if (!empty($name)) { // the user is asking for a specific value if (!empty($plugin)) { - return $DB->get_field('config_plugins', 'value', array('plugin'=>$plugin, 'name'=>$name)); + if (isset($CFG->forced_plugin_settings[$plugin]) and array_key_exists($name, $CFG->forced_plugin_settings[$plugin])) { + // setting forced in config file + return $CFG->forced_plugin_settings[$plugin][$name]; + } else { + return $DB->get_field('config_plugins', 'value', array('plugin'=>$plugin, 'name'=>$name)); + } } else { - return $DB->get_field('config', 'value', array('name'=>$name)); + if (array_key_exists($name, $CFG->config_php_settings)) { + // setting force in config file + return $CFG->config_php_settings[$name]; + } else { + return $DB->get_field('config', 'value', array('name'=>$name)); + } } } // the user is after a recordset - if (!empty($plugin)) { + if ($plugin) { $localcfg = $DB->get_records_menu('config_plugins', array('plugin'=>$plugin), '', 'name,value'); - if (!empty($localcfg)) { - return (object)$localcfg; - } else { - return false; - } - } else { - // this was originally in setup.php - if ($configs = $DB->get_records('config')) { - $localcfg = (array)$CFG; - foreach ($configs as $config) { - if (!isset($localcfg[$config->name])) { - $localcfg[$config->name] = $config->value; + if (isset($CFG->forced_plugin_settings[$plugin])) { + foreach($CFG->forced_plugin_settings[$plugin] as $n=>$v) { + if (is_null($v) or is_array($v) or is_object($v)) { + // we do not want any extra mess here, just real settings that could be saved in db + unset($localcfg[$n]); + } else { + //convert to string as if it went through the DB + $localcfg[$n] = (string)$v; } - // do not complain anymore if config.php overrides settings from db } - - $localcfg = (object)$localcfg; - return $localcfg; - } else { - // preserve $CFG if DB returns nothing or error - return $CFG; } + return (object)$localcfg; + } else { + // this part is not really used any more, but anyway... + $localcfg = $DB->get_records_menu('config', array(), '', 'name,value'); + foreach($CFG->config_php_settings as $n=>$v) { + if (is_null($v) or is_array($v) or is_object($v)) { + // we do not want any extra mess here, just real settings that could be saved in db + unset($localcfg[$n]); + } else { + //convert to string as if it went through the DB + $localcfg[$n] = (string)$v; + } + } + return (object)$localcfg; } } diff --git a/lib/setup.php b/lib/setup.php index b6571ddbeb2..fd8e38e5ec5 100644 --- a/lib/setup.php +++ b/lib/setup.php @@ -224,7 +224,11 @@ if (!isset($_SERVER['REMOTE_ADDR']) && isset($_SERVER['argv'][0])) { // Store settings from config.php in array in $CFG - we can use it later to detect problems and overrides $CFG->config_php_settings = (array)$CFG; - +// Forced plugin settings override values from config_plugins table +unset($CFG->config_php_settings['forced_plugin_settings']); +if (!isset($CFG->forced_plugin_settings)) { + $CFG->forced_plugin_settings = array(); +} // Set httpswwwroot default value (this variable will replace $CFG->wwwroot // inside some URLs used in HTTPSPAGEREQUIRED pages. $CFG->httpswwwroot = $CFG->wwwroot; @@ -315,11 +319,7 @@ if (isset($CFG->debug)) { } // Load up any configuration from the config table -try { - $CFG = get_config(); -} catch (dml_read_exception $e) { - // most probably empty db, going to install soon -} +initialise_cfg(); // Verify upgrade is not running unless we are in a script that needs to execute in any case if (!defined('NO_UPGRADE_CHECK') and isset($CFG->upgraderunning)) { @@ -392,7 +392,7 @@ unset($originalconfigdebug); unset($originaldatabasedebug); error_reporting($CFG->debug); -// find out if PHP cofigured to display warnings, +// find out if PHP configured to display warnings, // this is a security problem because some moodle scripts may // disclose sensitive information if (ini_get_bool('display_errors')) { diff --git a/lib/setuplib.php b/lib/setuplib.php index 8aba8d23459..acb97520dd7 100644 --- a/lib/setuplib.php +++ b/lib/setuplib.php @@ -454,6 +454,29 @@ function setup_validate_php_configuration() { } } +/** + * Initialise global $CFG variable + * @return void + */ +function initialise_cfg() { + global $CFG, $DB; + + try { + if ($DB) { + $localcfg = $DB->get_records_menu('config', array(), '', 'name,value'); + foreach ($localcfg as $name=>$value) { + if (property_exists($CFG, $name)) { + // config.php settings always take precedence + continue; + } + $CFG->{$name} = $value; + } + } + } catch (dml_read_exception $e) { + // most probably empty db, going to install soon + } +} + /** * Initialises $FULLME and friends. Private function. Should only be called from * setup.php.