X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=application%2Fconfig%2FConfigManager.php;h=f5f753f8fb55853688824327cb19ea5669dcead8;hb=7af9a41881ed0b9d44d18a0ce03a123a8441adf5;hp=dfe9eeb964872047bd54525f78c170245c7ecdc9;hpb=59404d7909b21682ec0782778452a8a70e38b25e;p=github%2Fshaarli%2FShaarli.git diff --git a/application/config/ConfigManager.php b/application/config/ConfigManager.php index dfe9eeb9..f5f753f8 100644 --- a/application/config/ConfigManager.php +++ b/application/config/ConfigManager.php @@ -2,30 +2,28 @@ // FIXME! Namespaces... require_once 'ConfigIO.php'; +require_once 'ConfigJson.php'; require_once 'ConfigPhp.php'; -#require_once 'ConfigJson.php'; /** * Class ConfigManager * - * Singleton, manages all Shaarli's settings. + * Manages all Shaarli's settings. + * See the documentation for more information on settings: + * - doc/Shaarli-configuration.html + * - https://github.com/shaarli/Shaarli/wiki/Shaarli-configuration */ class ConfigManager { /** - * @var ConfigManager instance. + * @var string Flag telling a setting is not found. */ - protected static $instance = null; + protected static $NOT_FOUND = 'NOT_FOUND'; /** * @var string Config folder. */ - public static $CONFIG_FILE = 'data/config'; - - /** - * @var string Flag telling a setting is not found. - */ - protected static $NOT_FOUND = 'NOT_FOUND'; + protected $configFile; /** * @var array Loaded config array. @@ -38,28 +36,22 @@ class ConfigManager protected $configIO; /** - * Private constructor: new instances not allowed. - */ - private function __construct() {} - - /** - * Cloning isn't allowed either. + * Constructor. + * + * @param string $configFile Configuration file path without extension. */ - private function __clone() {} + public function __construct($configFile = 'data/config') + { + $this->configFile = $configFile; + $this->initialize(); + } /** - * Return existing instance of PluginManager, or create it. - * - * @return ConfigManager instance. + * Reset the ConfigManager instance. */ - public static function getInstance() + public function reset() { - if (!(self::$instance instanceof self)) { - self::$instance = new self(); - self::$instance->initialize(); - } - - return self::$instance; + $this->initialize(); } /** @@ -67,21 +59,28 @@ class ConfigManager */ public function reload() { - $this->initialize(); + $this->load(); } /** - * Initialize loaded conf in ConfigManager. + * Initialize the ConfigIO and loaded the conf. */ protected function initialize() { - /*if (! file_exists(self::$CONFIG_FILE .'.php')) { - $this->configIO = new ConfigJson(); - } else { + if (file_exists($this->configFile . '.php')) { $this->configIO = new ConfigPhp(); - }*/ - $this->configIO = new ConfigPhp(); - $this->loadedConfig = $this->configIO->read(self::$CONFIG_FILE); + } else { + $this->configIO = new ConfigJson(); + } + $this->load(); + } + + /** + * Load configuration in the ConfigurationManager. + */ + protected function load() + { + $this->loadedConfig = $this->configIO->read($this->getConfigFileExt()); $this->setDefaultValues(); } @@ -100,6 +99,11 @@ class ConfigManager */ public function get($setting, $default = '') { + // During the ConfigIO transition, map legacy settings to the new ones. + if ($this->configIO instanceof ConfigPhp && isset(ConfigPhp::$LEGACY_KEYS_MAPPING[$setting])) { + $setting = ConfigPhp::$LEGACY_KEYS_MAPPING[$setting]; + } + $settings = explode('.', $setting); $value = self::getConfig($settings, $this->loadedConfig); if ($value === self::$NOT_FOUND) { @@ -117,9 +121,20 @@ class ConfigManager * @param string $value Value to set. * @param bool $write Write the new setting in the config file, default false. * @param bool $isLoggedIn User login state, default false. + * + * @throws Exception Invalid */ public function set($setting, $value, $write = false, $isLoggedIn = false) { + if (empty($setting) || ! is_string($setting)) { + throw new Exception('Invalid setting key parameter. String expected, got: '. gettype($setting)); + } + + // During the ConfigIO transition, map legacy settings to the new ones. + if ($this->configIO instanceof ConfigPhp && isset(ConfigPhp::$LEGACY_KEYS_MAPPING[$setting])) { + $setting = ConfigPhp::$LEGACY_KEYS_MAPPING[$setting]; + } + $settings = explode('.', $setting); self::setConfig($settings, $value, $this->loadedConfig); if ($write) { @@ -138,6 +153,11 @@ class ConfigManager */ public function exists($setting) { + // During the ConfigIO transition, map legacy settings to the new ones. + if ($this->configIO instanceof ConfigPhp && isset(ConfigPhp::$LEGACY_KEYS_MAPPING[$setting])) { + $setting = ConfigPhp::$LEGACY_KEYS_MAPPING[$setting]; + } + $settings = explode('.', $setting); $value = self::getConfig($settings, $this->loadedConfig); if ($value === self::$NOT_FOUND) { @@ -151,6 +171,8 @@ class ConfigManager * * @param bool $isLoggedIn User login state. * + * @return bool True if the configuration has been successfully written, false otherwise. + * * @throws MissingFieldConfigException: a mandatory field has not been provided in $conf. * @throws UnauthorizedConfigException: user is not authorize to change configuration. * @throws IOException: an error occurred while writing the new config file. @@ -159,12 +181,19 @@ class ConfigManager { // These fields are required in configuration. $mandatoryFields = array( - 'login', 'hash', 'salt', 'timezone', 'title', 'titleLink', - 'redirector', 'disablesessionprotection', 'privateLinkByDefault' + 'credentials.login', + 'credentials.hash', + 'credentials.salt', + 'security.session_protection_disabled', + 'general.timezone', + 'general.title', + 'general.header_link', + 'privacy.default_private_links', + 'redirector.url', ); // Only logged in user can alter config. - if (is_file(self::$CONFIG_FILE) && !$isLoggedIn) { + if (is_file($this->getConfigFileExt()) && !$isLoggedIn) { throw new UnauthorizedConfigException(); } @@ -175,17 +204,37 @@ class ConfigManager } } - $this->configIO->write(self::$CONFIG_FILE, $this->loadedConfig); + return $this->configIO->write($this->getConfigFileExt(), $this->loadedConfig); } /** - * Get the configuration file path. + * Set the config file path (without extension). * - * @return string Config file path. + * @param string $configFile File path. + */ + public function setConfigFile($configFile) + { + $this->configFile = $configFile; + } + + /** + * Return the configuration file path (without extension). + * + * @return string Config path. */ public function getConfigFile() { - return self::$CONFIG_FILE . $this->configIO->getExtension(); + return $this->configFile; + } + + /** + * Get the configuration file path with its extension. + * + * @return string Config file path. + */ + public function getConfigFileExt() + { + return $this->configFile . $this->configIO->getExtension(); } /** @@ -240,78 +289,44 @@ class ConfigManager */ protected function setDefaultValues() { - // Data subdirectory - $this->setEmpty('config.DATADIR', 'data'); - - // Main configuration file - $this->setEmpty('config.CONFIG_FILE', 'data/config.php'); - - // Link datastore - $this->setEmpty('config.DATASTORE', 'data/datastore.php'); - - // Banned IPs - $this->setEmpty('config.IPBANS_FILENAME', 'data/ipbans.php'); - - // Processed updates file. - $this->setEmpty('config.UPDATES_FILE', 'data/updates.txt'); - - // Access log - $this->setEmpty('config.LOG_FILE', 'data/log.txt'); - - // For updates check of Shaarli - $this->setEmpty('config.UPDATECHECK_FILENAME', 'data/lastupdatecheck.txt'); - - // Set ENABLE_UPDATECHECK to disabled by default. - $this->setEmpty('config.ENABLE_UPDATECHECK', false); - - // RainTPL cache directory (keep the trailing slash!) - $this->setEmpty('config.RAINTPL_TMP', 'tmp/'); - // Raintpl template directory (keep the trailing slash!) - $this->setEmpty('config.RAINTPL_TPL', 'tpl/'); + $this->setEmpty('resource.data_dir', 'data'); + $this->setEmpty('resource.config', 'data/config.php'); + $this->setEmpty('resource.datastore', 'data/datastore.php'); + $this->setEmpty('resource.ban_file', 'data/ipbans.php'); + $this->setEmpty('resource.updates', 'data/updates.txt'); + $this->setEmpty('resource.log', 'data/log.txt'); + $this->setEmpty('resource.update_check', 'data/lastupdatecheck.txt'); + $this->setEmpty('resource.raintpl_tpl', 'tpl/'); + $this->setEmpty('resource.raintpl_tmp', 'tmp/'); + $this->setEmpty('resource.thumbnails_cache', 'cache'); + $this->setEmpty('resource.page_cache', 'pagecache'); + + $this->setEmpty('security.ban_after', 4); + $this->setEmpty('security.ban_duration', 1800); + $this->setEmpty('security.session_protection_disabled', false); + $this->setEmpty('security.open_shaarli', false); + + $this->setEmpty('general.header_link', '?'); + $this->setEmpty('general.links_per_page', 20); + $this->setEmpty('general.enabled_plugins', array('qrcode')); + + $this->setEmpty('updates.check_updates', false); + $this->setEmpty('updates.check_updates_branch', 'stable'); + $this->setEmpty('updates.check_updates_interval', 86400); + + $this->setEmpty('feed.rss_permalinks', true); + $this->setEmpty('feed.show_atom', false); + + $this->setEmpty('privacy.default_private_links', false); + $this->setEmpty('privacy.hide_public_links', false); + $this->setEmpty('privacy.hide_timestamps', false); + + $this->setEmpty('thumbnail.enable_thumbnails', true); + $this->setEmpty('thumbnail.enable_localcache', true); + + $this->setEmpty('redirector.url', ''); + $this->setEmpty('redirector.encode_url', true); - // Thumbnail cache directory - $this->setEmpty('config.CACHEDIR', 'cache'); - - // Atom & RSS feed cache directory - $this->setEmpty('config.PAGECACHE', 'pagecache'); - - // Ban IP after this many failures - $this->setEmpty('config.BAN_AFTER', 4); - // Ban duration for IP address after login failures (in seconds) - $this->setEmpty('config.BAN_DURATION', 1800); - - // Feed options - // Enable RSS permalinks by default. - // This corresponds to the default behavior of shaarli before this was added as an option. - $this->setEmpty('config.ENABLE_RSS_PERMALINKS', true); - // If true, an extra "ATOM feed" button will be displayed in the toolbar - $this->setEmpty('config.SHOW_ATOM', false); - - // Link display options - $this->setEmpty('config.HIDE_PUBLIC_LINKS', false); - $this->setEmpty('config.HIDE_TIMESTAMPS', false); - $this->setEmpty('config.LINKS_PER_PAGE', 20); - - // Open Shaarli (true): anyone can add/edit/delete links without having to login - $this->setEmpty('config.OPEN_SHAARLI', false); - - // Thumbnails - // Display thumbnails in links - $this->setEmpty('config.ENABLE_THUMBNAILS', true); - // Store thumbnails in a local cache - $this->setEmpty('config.ENABLE_LOCALCACHE', true); - - // Update check frequency for Shaarli. 86400 seconds=24 hours - $this->setEmpty('config.UPDATECHECK_BRANCH', 'stable'); - $this->setEmpty('config.UPDATECHECK_INTERVAL', 86400); - - $this->setEmpty('redirector', ''); - $this->setEmpty('config.REDIRECTOR_URLENCODE', true); - - // Enabled plugins. - $this->setEmpty('config.ENABLED_PLUGINS', array('qrcode')); - - // Initialize plugin parameters array. $this->setEmpty('plugins', array()); } @@ -321,12 +336,28 @@ class ConfigManager * @param string $key Setting key. * @param mixed $value Setting value. */ - protected function setEmpty($key, $value) + public function setEmpty($key, $value) { if (! $this->exists($key)) { $this->set($key, $value); } } + + /** + * @return ConfigIO + */ + public function getConfigIO() + { + return $this->configIO; + } + + /** + * @param ConfigIO $configIO + */ + public function setConfigIO($configIO) + { + $this->configIO = $configIO; + } } /**