From 684e662a58b02bde225e44d3677987b6fc3adf0b Mon Sep 17 00:00:00 2001 From: ArthurHoaro Date: Wed, 18 May 2016 21:48:24 +0200 Subject: [PATCH] Replace $GLOBALS configuration with the configuration manager in the whole code base --- application/ApplicationUtils.php | 26 +- application/Config.php | 221 -------------- application/FileUtils.php | 8 +- application/PageBuilder.php | 28 +- application/Updater.php | 30 +- application/Utils.php | 2 +- application/config/ConfigIO.php | 2 + application/config/ConfigManager.php | 49 ++- application/config/ConfigPhp.php | 3 - application/config/ConfigPlugin.php | 4 +- index.php | 441 ++++++++++++--------------- tests/ApplicationUtilsTest.php | 54 ++-- tests/ConfigTest.php | 244 --------------- tests/FeedBuilderTest.php | 6 +- tests/LinkDBTest.php | 2 +- tests/Updater/DummyUpdater.php | 5 +- tests/Updater/UpdaterTest.php | 80 +++-- tests/config/ConfigPhpTest.php | 16 +- tests/config/php/configOK.php | 14 - tests/utils/config/configPhp.php | 14 + tests/utils/config/configUpdater.php | 15 + tpl/configure.html | 8 +- tpl/page.header.html | 4 +- 23 files changed, 421 insertions(+), 855 deletions(-) delete mode 100644 application/Config.php delete mode 100644 tests/ConfigTest.php delete mode 100644 tests/config/php/configOK.php create mode 100644 tests/utils/config/configPhp.php create mode 100644 tests/utils/config/configUpdater.php diff --git a/application/ApplicationUtils.php b/application/ApplicationUtils.php index 978fc9d..ed9abc3 100644 --- a/application/ApplicationUtils.php +++ b/application/ApplicationUtils.php @@ -132,32 +132,32 @@ class ApplicationUtils /** * Checks Shaarli has the proper access permissions to its resources * - * @param array $globalConfig The $GLOBALS['config'] array - * * @return array A list of the detected configuration issues */ - public static function checkResourcePermissions($globalConfig) + public static function checkResourcePermissions() { $errors = array(); + $conf = ConfigManager::getInstance(); // Check script and template directories are readable foreach (array( 'application', 'inc', 'plugins', - $globalConfig['RAINTPL_TPL'] + $conf->get('config.RAINTPL_TPL'), ) as $path) { if (! is_readable(realpath($path))) { $errors[] = '"'.$path.'" directory is not readable'; } } + $datadir = $conf->get('config.DATADIR'); // Check cache and data directories are readable and writeable foreach (array( - $globalConfig['CACHEDIR'], - $globalConfig['DATADIR'], - $globalConfig['PAGECACHE'], - $globalConfig['RAINTPL_TMP'] + $conf->get('config.CACHEDIR'), + $datadir, + $conf->get('config.PAGECACHE'), + $conf->get('config.RAINTPL_TMP'), ) as $path) { if (! is_readable(realpath($path))) { $errors[] = '"'.$path.'" directory is not readable'; @@ -169,11 +169,11 @@ class ApplicationUtils // Check configuration files are readable and writeable foreach (array( - $globalConfig['CONFIG_FILE'], - $globalConfig['DATASTORE'], - $globalConfig['IPBANS_FILENAME'], - $globalConfig['LOG_FILE'], - $globalConfig['UPDATECHECK_FILENAME'] + $conf->getConfigFile(), + $conf->get('config.DATASTORE'), + $conf->get('config.IPBANS_FILENAME'), + $conf->get('config.LOG_FILE'), + $conf->get('config.UPDATECHECK_FILENAME'), ) as $path) { if (! is_file(realpath($path))) { # the file may not exist yet diff --git a/application/Config.php b/application/Config.php deleted file mode 100644 index 05a5945..0000000 --- a/application/Config.php +++ /dev/null @@ -1,221 +0,0 @@ - $value) { - $configStr .= '$GLOBALS[\'config\'][\''. $key .'\'] = '.var_export($config['config'][$key], true).';'. PHP_EOL; - } - - if (isset($config['plugins'])) { - foreach ($config['plugins'] as $key => $value) { - $configStr .= '$GLOBALS[\'plugins\'][\''. $key .'\'] = '.var_export($config['plugins'][$key], true).';'. PHP_EOL; - } - } - - if (!file_put_contents($config['config']['CONFIG_FILE'], $configStr) - || strcmp(file_get_contents($config['config']['CONFIG_FILE']), $configStr) != 0 - ) { - throw new Exception( - 'Shaarli could not create the config file. - Please make sure Shaarli has the right to write in the folder is it installed in.' - ); - } -} - -/** - * Process plugin administration form data and save it in an array. - * - * @param array $formData Data sent by the plugin admin form. - * - * @return array New list of enabled plugin, ordered. - * - * @throws PluginConfigOrderException Plugins can't be sorted because their order is invalid. - */ -function save_plugin_config($formData) -{ - // Make sure there are no duplicates in orders. - if (!validate_plugin_order($formData)) { - throw new PluginConfigOrderException(); - } - - $plugins = array(); - $newEnabledPlugins = array(); - foreach ($formData as $key => $data) { - if (startsWith($key, 'order')) { - continue; - } - - // If there is no order, it means a disabled plugin has been enabled. - if (isset($formData['order_' . $key])) { - $plugins[(int) $formData['order_' . $key]] = $key; - } - else { - $newEnabledPlugins[] = $key; - } - } - - // New enabled plugins will be added at the end of order. - $plugins = array_merge($plugins, $newEnabledPlugins); - - // Sort plugins by order. - if (!ksort($plugins)) { - throw new PluginConfigOrderException(); - } - - $finalPlugins = array(); - // Make plugins order continuous. - foreach ($plugins as $plugin) { - $finalPlugins[] = $plugin; - } - - return $finalPlugins; -} - -/** - * Validate plugin array submitted. - * Will fail if there is duplicate orders value. - * - * @param array $formData Data from submitted form. - * - * @return bool true if ok, false otherwise. - */ -function validate_plugin_order($formData) -{ - $orders = array(); - foreach ($formData as $key => $value) { - // No duplicate order allowed. - if (in_array($value, $orders)) { - return false; - } - - if (startsWith($key, 'order')) { - $orders[] = $value; - } - } - - return true; -} - -/** - * Affect plugin parameters values into plugins array. - * - * @param mixed $plugins Plugins array ($plugins[]['parameters']['param_name'] = . - * @param mixed $config Plugins configuration. - * - * @return mixed Updated $plugins array. - */ -function load_plugin_parameter_values($plugins, $config) -{ - $out = $plugins; - foreach ($plugins as $name => $plugin) { - if (empty($plugin['parameters'])) { - continue; - } - - foreach ($plugin['parameters'] as $key => $param) { - if (!empty($config[$key])) { - $out[$name]['parameters'][$key] = $config[$key]; - } - } - } - - return $out; -} - -/** - * Exception used if a mandatory field is missing in given configuration. - */ -class MissingFieldConfigException extends Exception -{ - public $field; - - /** - * Construct exception. - * - * @param string $field field name missing. - */ - public function __construct($field) - { - $this->field = $field; - $this->message = 'Configuration value is required for '. $this->field; - } -} - -/** - * Exception used if an unauthorized attempt to edit configuration has been made. - */ -class UnauthorizedConfigException extends Exception -{ - /** - * Construct exception. - */ - public function __construct() - { - $this->message = 'You are not authorized to alter config.'; - } -} - -/** - * Exception used if an error occur while saving plugin configuration. - */ -class PluginConfigOrderException extends Exception -{ - /** - * Construct exception. - */ - public function __construct() - { - $this->message = 'An error occurred while trying to save plugins loading order.'; - } -} diff --git a/application/FileUtils.php b/application/FileUtils.php index 6a12ef0..6cac982 100644 --- a/application/FileUtils.php +++ b/application/FileUtils.php @@ -9,11 +9,13 @@ class IOException extends Exception /** * Construct a new IOException * - * @param string $path path to the ressource that cannot be accessed + * @param string $path path to the resource that cannot be accessed + * @param string $message Custom exception message. */ - public function __construct($path) + public function __construct($path, $message = '') { $this->path = $path; - $this->message = 'Error accessing '.$this->path; + $this->message = empty($message) ? 'Error accessing' : $message; + $this->message .= PHP_EOL . $this->path; } } diff --git a/application/PageBuilder.php b/application/PageBuilder.php index 8258078..cf13c71 100644 --- a/application/PageBuilder.php +++ b/application/PageBuilder.php @@ -29,21 +29,22 @@ class PageBuilder private function initialize() { $this->tpl = new RainTPL(); + $conf = ConfigManager::getInstance(); try { $version = ApplicationUtils::checkUpdate( shaarli_version, - $GLOBALS['config']['UPDATECHECK_FILENAME'], - $GLOBALS['config']['UPDATECHECK_INTERVAL'], - $GLOBALS['config']['ENABLE_UPDATECHECK'], + $conf->get('config.UPDATECHECK_FILENAME'), + $conf->get('config.UPDATECHECK_INTERVAL'), + $conf->get('config.ENABLE_UPDATECHECK'), isLoggedIn(), - $GLOBALS['config']['UPDATECHECK_BRANCH'] + $conf->get('config.UPDATECHECK_BRANCH') ); $this->tpl->assign('newVersion', escape($version)); $this->tpl->assign('versionError', ''); } catch (Exception $exc) { - logm($GLOBALS['config']['LOG_FILE'], $_SERVER['REMOTE_ADDR'], $exc->getMessage()); + logm($conf->get('config.LOG_FILE'), $_SERVER['REMOTE_ADDR'], $exc->getMessage()); $this->tpl->assign('newVersion', ''); $this->tpl->assign('versionError', escape($exc->getMessage())); } @@ -62,16 +63,19 @@ class PageBuilder $this->tpl->assign('scripturl', index_url($_SERVER)); $this->tpl->assign('pagetitle', 'Shaarli'); $this->tpl->assign('privateonly', !empty($_SESSION['privateonly'])); // Show only private links? - if (!empty($GLOBALS['title'])) { - $this->tpl->assign('pagetitle', $GLOBALS['title']); + if ($conf->exists('title')) { + $this->tpl->assign('pagetitle', $conf->get('title')); } - if (!empty($GLOBALS['titleLink'])) { - $this->tpl->assign('titleLink', $GLOBALS['titleLink']); + if ($conf->exists('titleLink')) { + $this->tpl->assign('titleLink', $conf->get('titleLink')); } - if (!empty($GLOBALS['pagetitle'])) { - $this->tpl->assign('pagetitle', $GLOBALS['pagetitle']); + if ($conf->exists('pagetitle')) { + $this->tpl->assign('pagetitle', $conf->get('pagetitle')); } - $this->tpl->assign('shaarlititle', empty($GLOBALS['title']) ? 'Shaarli': $GLOBALS['title']); + $this->tpl->assign('shaarlititle', $conf->get('title', 'Shaarli')); + $this->tpl->assign('openshaarli', $conf->get('config.OPEN_SHAARLI', false)); + $this->tpl->assign('showatom', $conf->get('config.SHOW_ATOM', false)); + // FIXME! Globals if (!empty($GLOBALS['plugin_errors'])) { $this->tpl->assign('plugin_errors', $GLOBALS['plugin_errors']); } diff --git a/application/Updater.php b/application/Updater.php index 58c13c0..6b92af3 100644 --- a/application/Updater.php +++ b/application/Updater.php @@ -12,11 +12,6 @@ class Updater */ protected $doneUpdates; - /** - * @var array Shaarli's configuration array. - */ - protected $config; - /** * @var LinkDB instance. */ @@ -36,14 +31,12 @@ class Updater * Object constructor. * * @param array $doneUpdates Updates which are already done. - * @param array $config Shaarli's configuration array. * @param LinkDB $linkDB LinkDB instance. * @param boolean $isLoggedIn True if the user is logged in. */ - public function __construct($doneUpdates, $config, $linkDB, $isLoggedIn) + public function __construct($doneUpdates, $linkDB, $isLoggedIn) { $this->doneUpdates = $doneUpdates; - $this->config = $config; $this->linkDB = $linkDB; $this->isLoggedIn = $isLoggedIn; @@ -114,19 +107,21 @@ class Updater */ public function updateMethodMergeDeprecatedConfigFile() { - $config_file = $this->config['config']['CONFIG_FILE']; + $conf = ConfigManager::getInstance(); - if (is_file($this->config['config']['DATADIR'].'/options.php')) { - include $this->config['config']['DATADIR'].'/options.php'; + if (is_file($conf->get('config.DATADIR') . '/options.php')) { + include $conf->get('config.DATADIR') . '/options.php'; // Load GLOBALS into config + $allowedKeys = array_merge(ConfigPhp::$ROOT_KEYS); + $allowedKeys[] = 'config'; foreach ($GLOBALS as $key => $value) { - $this->config[$key] = $value; + if (in_array($key, $allowedKeys)) { + $conf->set($key, $value); + } } - $this->config['config']['CONFIG_FILE'] = $config_file; - writeConfig($this->config, $this->isLoggedIn); - - unlink($this->config['config']['DATADIR'].'/options.php'); + $conf->write($this->isLoggedIn); + unlink($conf->get('config.DATADIR').'/options.php'); } return true; @@ -137,13 +132,14 @@ class Updater */ public function updateMethodRenameDashTags() { + $conf = ConfigManager::getInstance(); $linklist = $this->linkDB->filterSearch(); foreach ($linklist as $link) { $link['tags'] = preg_replace('/(^| )\-/', '$1', $link['tags']); $link['tags'] = implode(' ', array_unique(LinkFilter::tagsStrToArray($link['tags'], true))); $this->linkDB[$link['linkdate']] = $link; } - $this->linkDB->savedb($this->config['config']['PAGECACHE']); + $this->linkDB->savedb($conf->get('config.PAGECACHE')); return true; } } diff --git a/application/Utils.php b/application/Utils.php index da521cc..9a8ca6d 100644 --- a/application/Utils.php +++ b/application/Utils.php @@ -273,4 +273,4 @@ function autoLocale($headerLocale) } } setlocale(LC_ALL, $attempts); -} \ No newline at end of file +} diff --git a/application/config/ConfigIO.php b/application/config/ConfigIO.php index 2b68fe6..4b1c990 100644 --- a/application/config/ConfigIO.php +++ b/application/config/ConfigIO.php @@ -21,6 +21,8 @@ interface ConfigIO * * @param string $filepath Config file absolute path. * @param array $conf All configuration in an array. + * + * @return bool True if the configuration has been successfully written, false otherwise. */ function write($filepath, $conf); diff --git a/application/config/ConfigManager.php b/application/config/ConfigManager.php index dfe9eeb..212aac0 100644 --- a/application/config/ConfigManager.php +++ b/application/config/ConfigManager.php @@ -62,16 +62,25 @@ class ConfigManager return self::$instance; } + /** + * Reset the ConfigManager instance. + */ + public static function reset() + { + self::$instance = null; + return self::getInstance(); + } + /** * Rebuild the loaded config array from config files. */ public function reload() { - $this->initialize(); + $this->load(); } /** - * Initialize loaded conf in ConfigManager. + * Initialize the ConfigIO and loaded the conf. */ protected function initialize() { @@ -81,7 +90,15 @@ class ConfigManager $this->configIO = new ConfigPhp(); }*/ $this->configIO = new ConfigPhp(); - $this->loadedConfig = $this->configIO->read(self::$CONFIG_FILE); + $this->load(); + } + + /** + * Load configuration in the ConfigurationManager. + */ + protected function load() + { + $this->loadedConfig = $this->configIO->read($this->getConfigFile()); $this->setDefaultValues(); } @@ -117,9 +134,15 @@ 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)); + } + $settings = explode('.', $setting); self::setConfig($settings, $value, $this->loadedConfig); if ($write) { @@ -151,6 +174,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. @@ -175,7 +200,7 @@ class ConfigManager } } - $this->configIO->write(self::$CONFIG_FILE, $this->loadedConfig); + return $this->configIO->write($this->getConfigFile(), $this->loadedConfig); } /** @@ -327,6 +352,22 @@ class ConfigManager $this->set($key, $value); } } + + /** + * @return ConfigIO + */ + public function getConfigIO() + { + return $this->configIO; + } + + /** + * @param ConfigIO $configIO + */ + public function setConfigIO($configIO) + { + $this->configIO = $configIO; + } } /** diff --git a/application/config/ConfigPhp.php b/application/config/ConfigPhp.php index 311aeb8..19fecf2 100644 --- a/application/config/ConfigPhp.php +++ b/application/config/ConfigPhp.php @@ -28,7 +28,6 @@ class ConfigPhp implements ConfigIO */ function read($filepath) { - $filepath .= $this->getExtension(); if (! file_exists($filepath) || ! is_readable($filepath)) { return array(); } @@ -49,8 +48,6 @@ class ConfigPhp implements ConfigIO */ function write($filepath, $conf) { - $filepath .= $this->getExtension(); - $configStr = ' /shaarli/ -define('WEB_PATH', substr($_SERVER["REQUEST_URI"], 0, 1+strrpos($_SERVER["REQUEST_URI"], '/', 0))); +define('WEB_PATH', substr($_SERVER['REQUEST_URI'], 0, 1+strrpos($_SERVER['REQUEST_URI'], '/', 0))); // High execution time in case of problematic imports/exports. ini_set('max_input_time','60'); @@ -144,12 +43,6 @@ error_reporting(E_ALL^E_WARNING); // See all errors (for debugging only) //error_reporting(-1); -/* - * User configuration - */ -if (is_file($GLOBALS['config']['CONFIG_FILE'])) { - require_once $GLOBALS['config']['CONFIG_FILE']; -} // Shaarli library require_once 'application/ApplicationUtils.php'; @@ -166,10 +59,12 @@ require_once 'application/PageBuilder.php'; require_once 'application/TimeZone.php'; require_once 'application/Url.php'; require_once 'application/Utils.php'; -require_once 'application/Config.php'; +require_once 'application/config/ConfigManager.php'; +require_once 'application/config/ConfigPlugin.php'; require_once 'application/PluginManager.php'; require_once 'application/Router.php'; require_once 'application/Updater.php'; +require_once 'inc/rain.tpl.class.php'; // Ensure the PHP version is supported try { @@ -210,16 +105,16 @@ if (isset($_COOKIE['shaarli']) && !is_session_id_valid($_COOKIE['shaarli'])) { $_COOKIE['shaarli'] = session_id(); } -include "inc/rain.tpl.class.php"; //include Rain TPL -raintpl::$tpl_dir = $GLOBALS['config']['RAINTPL_TPL']; // template directory -raintpl::$cache_dir = $GLOBALS['config']['RAINTPL_TMP']; // cache directory +$conf = ConfigManager::getInstance(); + +RainTPL::$tpl_dir = $conf->get('config.RAINTPL_TPL'); // template directory +RainTPL::$cache_dir = $conf->get('config.RAINTPL_TMP'); // cache directory $pluginManager = PluginManager::getInstance(); -$pluginManager->load($GLOBALS['config']['ENABLED_PLUGINS']); +$pluginManager->load($conf->get('config.ENABLED_PLUGINS')); ob_start(); // Output buffering for the page cache. - // In case stupid admin has left magic_quotes enabled in php.ini: if (get_magic_quotes_gpc()) { @@ -236,17 +131,25 @@ header("Cache-Control: post-check=0, pre-check=0", false); header("Pragma: no-cache"); // Handling of old config file which do not have the new parameters. -if (empty($GLOBALS['title'])) $GLOBALS['title']='Shared links on '.escape(index_url($_SERVER)); -if (empty($GLOBALS['timezone'])) $GLOBALS['timezone']=date_default_timezone_get(); -if (empty($GLOBALS['redirector'])) $GLOBALS['redirector']=''; -if (empty($GLOBALS['disablesessionprotection'])) $GLOBALS['disablesessionprotection']=false; -if (empty($GLOBALS['privateLinkByDefault'])) $GLOBALS['privateLinkByDefault']=false; -if (empty($GLOBALS['titleLink'])) $GLOBALS['titleLink']='?'; -// I really need to rewrite Shaarli with a proper configuation manager. +if (! $conf->exists('title')) { + $conf->set('title', 'Shared links on '. escape(index_url($_SERVER))); +} +if (! $conf->exists('timezone')) { + $conf->set('timezone', date_default_timezone_get()); +} +if (! $conf->exists('disablesessionprotection')) { + $conf->set('disablesessionprotection', false); +} +if (! $conf->exists('privateLinkByDefault')) { + $conf->set('privateLinkByDefault', false); +} +if (! $conf->exists('titleLink')) { + $conf->set('titleLink', '?'); +} -if (! is_file($GLOBALS['config']['CONFIG_FILE'])) { +if (! is_file($conf->getConfigFile())) { // Ensure Shaarli has proper access to its resources - $errors = ApplicationUtils::checkResourcePermissions($GLOBALS['config']); + $errors = ApplicationUtils::checkResourcePermissions(); if ($errors != array()) { $message = '

Insufficient permissions:

    '; @@ -265,12 +168,13 @@ if (! is_file($GLOBALS['config']['CONFIG_FILE'])) { install(); } -$GLOBALS['title'] = !empty($GLOBALS['title']) ? escape($GLOBALS['title']) : ''; -$GLOBALS['titleLink'] = !empty($GLOBALS['titleLink']) ? escape($GLOBALS['titleLink']) : ''; -$GLOBALS['redirector'] = !empty($GLOBALS['redirector']) ? escape($GLOBALS['redirector']) : ''; +// FIXME! Update these value with Updater and escpae it during the install/config save. +$conf->set('title', escape($conf->get('title'))); +$conf->set('titleLink', escape($conf->get('titleLink'))); +$conf->set('redirector', escape($conf->get('redirector'))); // a token depending of deployment salt, user password, and the current ip -define('STAY_SIGNED_IN_TOKEN', sha1($GLOBALS['hash'].$_SERVER["REMOTE_ADDR"].$GLOBALS['salt'])); +define('STAY_SIGNED_IN_TOKEN', sha1($conf->get('hash') . $_SERVER['REMOTE_ADDR'] . $conf->get('salt'))); // Sniff browser language and set date format accordingly. if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { @@ -283,12 +187,14 @@ header('Content-Type: text/html; charset=utf-8'); // We use UTF-8 for proper int //================================================================================================== function setup_login_state() { - if ($GLOBALS['config']['OPEN_SHAARLI']) { + $conf = ConfigManager::getInstance(); + + if ($conf->get('config.OPEN_SHAARLI')) { return true; } $userIsLoggedIn = false; // By default, we do not consider the user as logged in; $loginFailure = false; // If set to true, every attempt to authenticate the user will fail. This indicates that an important condition isn't met. - if (!isset($GLOBALS['login'])) { + if (! $conf->exists('login')) { $userIsLoggedIn = false; // Shaarli is not configured yet. $loginFailure = true; } @@ -300,9 +206,9 @@ function setup_login_state() { $userIsLoggedIn = true; } // If session does not exist on server side, or IP address has changed, or session has expired, logout. - if (empty($_SESSION['uid']) || - ($GLOBALS['disablesessionprotection']==false && $_SESSION['ip']!=allIPs()) || - time() >= $_SESSION['expires_on']) + if (empty($_SESSION['uid']) + || ($conf->get('disablesessionprotection') == false && $_SESSION['ip'] != allIPs()) + || time() >= $_SESSION['expires_on']) { logout(); $userIsLoggedIn = false; @@ -325,17 +231,19 @@ $userIsLoggedIn = setup_login_state(); // ------------------------------------------------------------------------------------------ // PubSubHubbub protocol support (if enabled) [UNTESTED] // (Source: http://aldarone.fr/les-flux-rss-shaarli-et-pubsubhubbub/ ) -if (!empty($GLOBALS['config']['PUBSUBHUB_URL'])) include './publisher.php'; function pubsubhub() { - if (!empty($GLOBALS['config']['PUBSUBHUB_URL'])) + $conf = ConfigManager::getInstance(); + $pshUrl = $conf->get('config.PUBSUBHUB_URL'); + if (!empty($pshUrl)) { - $p = new Publisher($GLOBALS['config']['PUBSUBHUB_URL']); - $topic_url = array ( - index_url($_SERVER).'?do=atom', - index_url($_SERVER).'?do=rss' - ); - $p->publish_update($topic_url); + include_once './publisher.php'; + $p = new Publisher($pshUrl); + $topic_url = array ( + index_url($_SERVER).'?do=atom', + index_url($_SERVER).'?do=rss' + ); + $p->publish_update($topic_url); } } @@ -345,7 +253,7 @@ function pubsubhub() // Returns the IP address of the client (Used to prevent session cookie hijacking.) function allIPs() { - $ip = $_SERVER["REMOTE_ADDR"]; + $ip = $_SERVER['REMOTE_ADDR']; // Then we use more HTTP headers to prevent session hijacking from users behind the same proxy. if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { $ip=$ip.'_'.$_SERVER['HTTP_X_FORWARDED_FOR']; } if (isset($_SERVER['HTTP_CLIENT_IP'])) { $ip=$ip.'_'.$_SERVER['HTTP_CLIENT_IP']; } @@ -353,23 +261,25 @@ function allIPs() } function fillSessionInfo() { + $conf = ConfigManager::getInstance(); $_SESSION['uid'] = sha1(uniqid('',true).'_'.mt_rand()); // Generate unique random number (different than phpsessionid) $_SESSION['ip']=allIPs(); // We store IP address(es) of the client to make sure session is not hijacked. - $_SESSION['username']=$GLOBALS['login']; + $_SESSION['username']= $conf->get('login'); $_SESSION['expires_on']=time()+INACTIVITY_TIMEOUT; // Set session expiration. } // Check that user/password is correct. function check_auth($login,$password) { - $hash = sha1($password.$login.$GLOBALS['salt']); - if ($login==$GLOBALS['login'] && $hash==$GLOBALS['hash']) + $conf = ConfigManager::getInstance(); + $hash = sha1($password . $login . $conf->get('salt')); + if ($login == $conf->get('login') && $hash == $conf->get('hash')) { // Login/password is correct. fillSessionInfo(); - logm($GLOBALS['config']['LOG_FILE'], $_SERVER['REMOTE_ADDR'], 'Login successful'); + logm($conf->get('config.LOG_FILE'), $_SERVER['REMOTE_ADDR'], 'Login successful'); return True; } - logm($GLOBALS['config']['LOG_FILE'], $_SERVER['REMOTE_ADDR'], 'Login failed for user '.$login); + logm($conf->get('config.LOG_FILE'), $_SERVER['REMOTE_ADDR'], 'Login failed for user '.$login); return False; } @@ -395,44 +305,64 @@ function logout() { // ------------------------------------------------------------------------------------------ // Brute force protection system // Several consecutive failed logins will ban the IP address for 30 minutes. -if (!is_file($GLOBALS['config']['IPBANS_FILENAME'])) file_put_contents($GLOBALS['config']['IPBANS_FILENAME'], "array(),'BANS'=>array()),true).";\n?>"); -include $GLOBALS['config']['IPBANS_FILENAME']; +if (!is_file($conf->get('config.IPBANS_FILENAME', 'data/ipbans.php'))) { + // FIXME! globals + file_put_contents( + $conf->get('config.IPBANS_FILENAME', 'data/ipbans.php'), + "array(),'BANS'=>array()),true).";\n?>" + ); +} +include $conf->get('config.IPBANS_FILENAME', 'data/ipbans.php'); // Signal a failed login. Will ban the IP if too many failures: function ban_loginFailed() { - $ip=$_SERVER["REMOTE_ADDR"]; $gb=$GLOBALS['IPBANS']; + $conf = ConfigManager::getInstance(); + $ip = $_SERVER['REMOTE_ADDR']; + $gb = $GLOBALS['IPBANS']; if (!isset($gb['FAILURES'][$ip])) $gb['FAILURES'][$ip]=0; $gb['FAILURES'][$ip]++; - if ($gb['FAILURES'][$ip]>($GLOBALS['config']['BAN_AFTER']-1)) + if ($gb['FAILURES'][$ip] > ($conf->get('config.BAN_AFTER') - 1)) { - $gb['BANS'][$ip]=time()+$GLOBALS['config']['BAN_DURATION']; - logm($GLOBALS['config']['LOG_FILE'], $_SERVER['REMOTE_ADDR'], 'IP address banned from login'); + $gb['BANS'][$ip] = time() + $conf->get('config.BAN_DURATION', 1800); + logm($conf->get('config.LOG_FILE'), $_SERVER['REMOTE_ADDR'], 'IP address banned from login'); } $GLOBALS['IPBANS'] = $gb; - file_put_contents($GLOBALS['config']['IPBANS_FILENAME'], ""); + file_put_contents( + $conf->get('config.IPBANS_FILENAME', 'data/ipbans.php'), + "" + ); } // Signals a successful login. Resets failed login counter. function ban_loginOk() { - $ip=$_SERVER["REMOTE_ADDR"]; $gb=$GLOBALS['IPBANS']; + $conf = ConfigManager::getInstance(); + $ip = $_SERVER['REMOTE_ADDR']; + $gb = $GLOBALS['IPBANS']; unset($gb['FAILURES'][$ip]); unset($gb['BANS'][$ip]); $GLOBALS['IPBANS'] = $gb; - file_put_contents($GLOBALS['config']['IPBANS_FILENAME'], ""); + file_put_contents( + $conf->get('config.IPBANS_FILENAME', 'data/ipbans.php'), + "" + ); } // Checks if the user CAN login. If 'true', the user can try to login. function ban_canLogin() { + $conf = ConfigManager::getInstance(); $ip=$_SERVER["REMOTE_ADDR"]; $gb=$GLOBALS['IPBANS']; if (isset($gb['BANS'][$ip])) { // User is banned. Check if the ban has expired: if ($gb['BANS'][$ip]<=time()) { // Ban expired, user can try to login again. - logm($GLOBALS['config']['LOG_FILE'], $_SERVER['REMOTE_ADDR'], 'Ban lifted.'); + logm($conf->get('config.LOG_FILE'), $_SERVER['REMOTE_ADDR'], 'Ban lifted.'); unset($gb['FAILURES'][$ip]); unset($gb['BANS'][$ip]); - file_put_contents($GLOBALS['config']['IPBANS_FILENAME'], ""); + file_put_contents( + $conf->get('config.IPBANS_FILENAME', 'data/ipbans.php'), + "" + ); return true; // Ban has expired, user can login. } return false; // User is banned. @@ -546,7 +476,8 @@ if (!isset($_SESSION['tokens'])) $_SESSION['tokens']=array(); // Token are atta // Returns a token. function getToken() { - $rnd = sha1(uniqid('',true).'_'.mt_rand().$GLOBALS['salt']); // We generate a random string. + $conf = ConfigManager::getInstance(); + $rnd = sha1(uniqid('', true) .'_'. mt_rand() . $conf->get('salt')); // We generate a random string. $_SESSION['tokens'][$rnd]=1; // Store it on the server side. return $rnd; } @@ -568,10 +499,11 @@ function tokenOk($token) // Gives the last 7 days (which have links). // This RSS feed cannot be filtered. function showDailyRSS() { + $conf = ConfigManager::getInstance(); // Cache system $query = $_SERVER['QUERY_STRING']; $cache = new CachedPage( - $GLOBALS['config']['PAGECACHE'], + $conf->get('config.PAGE_CACHE'), page_url($_SERVER), startsWith($query,'do=dailyrss') && !isLoggedIn() ); @@ -584,11 +516,11 @@ function showDailyRSS() { // If cached was not found (or not usable), then read the database and build the response: // Read links from database (and filter private links if used it not logged in). $LINKSDB = new LinkDB( - $GLOBALS['config']['DATASTORE'], + $conf->get('config.DATASTORE'), isLoggedIn(), - $GLOBALS['config']['HIDE_PUBLIC_LINKS'], - $GLOBALS['redirector'], - $GLOBALS['config']['REDIRECTOR_URLENCODE'] + $conf->get('config.HIDE_PUBLIC_LINKS'), + $conf->get('redirector'), + $conf->get('config.REDIRECTOR_URLENCODE') ); /* Some Shaarlies may have very few links, so we need to look @@ -600,7 +532,7 @@ function showDailyRSS() { } rsort($linkdates); $nb_of_days = 7; // We take 7 days. - $today = Date('Ymd'); + $today = date('Ymd'); $days = array(); foreach ($linkdates as $linkdate) { @@ -622,7 +554,7 @@ function showDailyRSS() { $pageaddr = escape(index_url($_SERVER)); echo ''; echo ''; - echo 'Daily - '. $GLOBALS['title'] . ''; + echo 'Daily - '. $conf->get('title') . ''; echo ''. $pageaddr .''; echo 'Daily shared links'; echo 'en-en'; @@ -641,7 +573,7 @@ function showDailyRSS() { // We pre-format some fields for proper output. foreach ($linkdates as $linkdate) { $l = $LINKSDB[$linkdate]; - $l['formatedDescription'] = format_description($l['description'], $GLOBALS['redirector']); + $l['formatedDescription'] = format_description($l['description'], $conf->get('redirector')); $l['thumbnail'] = thumbnail($l['url']); $l_date = DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, $l['linkdate']); $l['timestamp'] = $l_date->getTimestamp(); @@ -653,7 +585,7 @@ function showDailyRSS() { // Then build the HTML for this day: $tpl = new RainTPL; - $tpl->assign('title', $GLOBALS['title']); + $tpl->assign('title', $conf->get('title')); $tpl->assign('daydate', $dayDate->getTimestamp()); $tpl->assign('absurl', $absurl); $tpl->assign('links', $links); @@ -677,7 +609,8 @@ function showDailyRSS() { */ function showDaily($pageBuilder, $LINKSDB) { - $day=Date('Ymd',strtotime('-1 day')); // Yesterday, in format YYYYMMDD. + $conf = ConfigManager::getInstance(); + $day=date('Ymd',strtotime('-1 day')); // Yesterday, in format YYYYMMDD. if (isset($_GET['day'])) $day=$_GET['day']; $days = $LINKSDB->days(); @@ -705,7 +638,7 @@ function showDaily($pageBuilder, $LINKSDB) $taglist = explode(' ',$link['tags']); uasort($taglist, 'strcasecmp'); $linksToDisplay[$key]['taglist']=$taglist; - $linksToDisplay[$key]['formatedDescription'] = format_description($link['description'], $GLOBALS['redirector']); + $linksToDisplay[$key]['formatedDescription'] = format_description($link['description'], $conf->get('redirector')); $linksToDisplay[$key]['thumbnail'] = thumbnail($link['url']); $date = DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, $link['linkdate']); $linksToDisplay[$key]['timestamp'] = $date->getTimestamp(); @@ -763,17 +696,17 @@ function showLinkList($PAGE, $LINKSDB) { // Render HTML page (according to URL parameters and user rights) function renderPage() { + $conf = ConfigManager::getInstance(); $LINKSDB = new LinkDB( - $GLOBALS['config']['DATASTORE'], + $conf->get('config.DATASTORE'), isLoggedIn(), - $GLOBALS['config']['HIDE_PUBLIC_LINKS'], - $GLOBALS['redirector'], - $GLOBALS['config']['REDIRECTOR_URLENCODE'] + $conf->get('config.HIDE_PUBLIC_LINKS'), + $conf->get('redirector'), + $conf->get('config.REDIRECTOR_URLENCODE') ); $updater = new Updater( - read_updates_file($GLOBALS['config']['UPDATES_FILE']), - $GLOBALS, + read_updates_file($conf->get('config.UPDATES_FILE')), $LINKSDB, isLoggedIn() ); @@ -781,7 +714,7 @@ function renderPage() $newUpdates = $updater->update(); if (! empty($newUpdates)) { write_updates_file( - $GLOBALS['config']['UPDATES_FILE'], + $conf->get('config.UPDATES_FILE'), $updater->getDoneUpdates() ); } @@ -820,7 +753,7 @@ function renderPage() // -------- Display login form. if ($targetPage == Router::$PAGE_LOGIN) { - if ($GLOBALS['config']['OPEN_SHAARLI']) { header('Location: ?'); exit; } // No need to login for open Shaarli + if ($conf->get('config.OPEN_SHAARLI')) { header('Location: ?'); exit; } // No need to login for open Shaarli $token=''; if (ban_canLogin()) $token=getToken(); // Do not waste token generation if not useful. $PAGE->assign('token',$token); if (isset($_GET['username'])) { @@ -833,7 +766,7 @@ function renderPage() // -------- User wants to logout. if (isset($_SERVER['QUERY_STRING']) && startsWith($_SERVER['QUERY_STRING'], 'do=logout')) { - invalidateCaches($GLOBALS['config']['PAGECACHE']); + invalidateCaches($conf->get('config.PAGECACHE')); logout(); header('Location: ?'); exit; @@ -933,7 +866,7 @@ function renderPage() // Cache system $query = $_SERVER['QUERY_STRING']; $cache = new CachedPage( - $GLOBALS['config']['PAGECACHE'], + $conf->get('config.PAGECACHE'), page_url($_SERVER), startsWith($query,'do='. $targetPage) && !isLoggedIn() ); @@ -946,10 +879,11 @@ function renderPage() // Generate data. $feedGenerator = new FeedBuilder($LINKSDB, $feedType, $_SERVER, $_GET, isLoggedIn()); $feedGenerator->setLocale(strtolower(setlocale(LC_COLLATE, 0))); - $feedGenerator->setHideDates($GLOBALS['config']['HIDE_TIMESTAMPS'] && !isLoggedIn()); - $feedGenerator->setUsePermalinks(isset($_GET['permalinks']) || !$GLOBALS['config']['ENABLE_RSS_PERMALINKS']); - if (!empty($GLOBALS['config']['PUBSUBHUB_URL'])) { - $feedGenerator->setPubsubhubUrl($GLOBALS['config']['PUBSUBHUB_URL']); + $feedGenerator->setHideDates($conf->get('config.HIDE_TIMESTAMPS') && !isLoggedIn()); + $feedGenerator->setUsePermalinks(isset($_GET['permalinks']) || !$conf->get('config.ENABLE_RSS_PERMALINKS')); + $pshUrl = $conf->get('config.PUBSUBHUB_URL'); + if (!empty($pshUrl)) { + $feedGenerator->setPubsubhubUrl($pshUrl); } $data = $feedGenerator->buildData(); @@ -1110,19 +1044,23 @@ function renderPage() // -------- User wants to change his/her password. if ($targetPage == Router::$PAGE_CHANGEPASSWORD) { - if ($GLOBALS['config']['OPEN_SHAARLI']) die('You are not supposed to change a password on an Open Shaarli.'); + if ($conf->get('config.OPEN_SHAARLI')) { + die('You are not supposed to change a password on an Open Shaarli.'); + } + if (!empty($_POST['setpassword']) && !empty($_POST['oldpassword'])) { if (!tokenOk($_POST['token'])) die('Wrong token.'); // Go away! // Make sure old password is correct. - $oldhash = sha1($_POST['oldpassword'].$GLOBALS['login'].$GLOBALS['salt']); - if ($oldhash!=$GLOBALS['hash']) { echo ''; exit; } + $oldhash = sha1($_POST['oldpassword'].$conf->get('login').$conf->get('salt')); + if ($oldhash!= $conf->get('hash')) { echo ''; exit; } // Save new password - $GLOBALS['salt'] = sha1(uniqid('',true).'_'.mt_rand()); // Salt renders rainbow-tables attacks useless. - $GLOBALS['hash'] = sha1($_POST['setpassword'].$GLOBALS['login'].$GLOBALS['salt']); + // Salt renders rainbow-tables attacks useless. + $conf->set('salt', sha1(uniqid('', true) .'_'. mt_rand())); + $conf->set('hash', sha1($_POST['setpassword'] . $conf->get('login') . $conf->get('salt'))); try { - writeConfig($GLOBALS, isLoggedIn()); + $conf->write(isLoggedIn()); } catch(Exception $e) { error_log( @@ -1159,17 +1097,17 @@ function renderPage() ) { $tz = $_POST['continent'] . '/' . $_POST['city']; } - $GLOBALS['timezone'] = $tz; - $GLOBALS['title']=$_POST['title']; - $GLOBALS['titleLink']=$_POST['titleLink']; - $GLOBALS['redirector']=$_POST['redirector']; - $GLOBALS['disablesessionprotection']=!empty($_POST['disablesessionprotection']); - $GLOBALS['privateLinkByDefault']=!empty($_POST['privateLinkByDefault']); - $GLOBALS['config']['ENABLE_RSS_PERMALINKS']= !empty($_POST['enableRssPermalinks']); - $GLOBALS['config']['ENABLE_UPDATECHECK'] = !empty($_POST['updateCheck']); - $GLOBALS['config']['HIDE_PUBLIC_LINKS'] = !empty($_POST['hidePublicLinks']); + $conf->set('timezone', $tz); + $conf->set('title', $_POST['title']); + $conf->set('titleLink', $_POST['titleLink']); + $conf->set('redirector', $_POST['redirector']); + $conf->set('disablesessionprotection', !empty($_POST['disablesessionprotection'])); + $conf->set('privateLinkByDefault', !empty($_POST['privateLinkByDefault'])); + $conf->set('config.ENABLE_RSS_PERMALINKS', !empty($_POST['enableRssPermalinks'])); + $conf->set('config.ENABLE_UPDATECHECK', !empty($_POST['updateCheck'])); + $conf->set('config.HIDE_PUBLIC_LINKS', !empty($_POST['hidePublicLinks'])); try { - writeConfig($GLOBALS, isLoggedIn()); + $conf->write(isLoggedIn()); } catch(Exception $e) { error_log( @@ -1178,20 +1116,24 @@ function renderPage() ); // TODO: do not handle exceptions/errors in JS. - echo ''; + echo ''; exit; } - echo ''; + echo ''; exit; } else // Show the configuration form. { $PAGE->assign('token',getToken()); - $PAGE->assign('title', empty($GLOBALS['title']) ? '' : $GLOBALS['title'] ); - $PAGE->assign('redirector', empty($GLOBALS['redirector']) ? '' : $GLOBALS['redirector'] ); - list($timezone_form, $timezone_js) = generateTimeZoneForm($GLOBALS['timezone']); + $PAGE->assign('title', $conf->get('title')); + $PAGE->assign('redirector', $conf->get('redirector')); + list($timezone_form, $timezone_js) = generateTimeZoneForm($conf->get('timezone')); $PAGE->assign('timezone_form', $timezone_form); $PAGE->assign('timezone_js',$timezone_js); + $PAGE->assign('private_links_default', $conf->get('privateLinkByDefault')); + $PAGE->assign('enable_rss_permalinks', $conf->get('config.ENABLE_RSS_PERMALINKS')); + $PAGE->assign('enable_update_check', $conf->get('config.ENABLE_UPDATECHECK')); + $PAGE->assign('hide_public_links', $conf->get('config.HIDE_PUBLIC_LINKS')); $PAGE->renderPage('configure'); exit; } @@ -1223,7 +1165,7 @@ function renderPage() $value['tags']=trim(implode(' ',$tags)); $LINKSDB[$key]=$value; } - $LINKSDB->savedb($GLOBALS['config']['PAGECACHE']); + $LINKSDB->savedb($conf->get('config.PAGECACHE')); echo ''; exit; } @@ -1240,7 +1182,7 @@ function renderPage() $value['tags']=trim(implode(' ',$tags)); $LINKSDB[$key]=$value; } - $LINKSDB->savedb($GLOBALS['config']['PAGECACHE']); // Save to disk. + $LINKSDB->savedb($conf->get('config.PAGECACHE')); // Save to disk. echo ''; exit; } @@ -1291,7 +1233,7 @@ function renderPage() $pluginManager->executeHooks('save_link', $link); $LINKSDB[$linkdate] = $link; - $LINKSDB->savedb($GLOBALS['config']['PAGECACHE']); + $LINKSDB->savedb($conf->get('config.PAGECACHE')); pubsubhub(); // If we are called from the bookmarklet, we must close the popup: @@ -1333,7 +1275,7 @@ function renderPage() $pluginManager->executeHooks('delete_link', $LINKSDB[$linkdate]); unset($LINKSDB[$linkdate]); - $LINKSDB->savedb($GLOBALS['config']['PAGECACHE']); // save to disk + $LINKSDB->savedb('config.PAGECACHE'); // save to disk // If we are called from the bookmarklet, we must close the popup: if (isset($_GET['source']) && ($_GET['source']=='bookmarklet' || $_GET['source']=='firefoxsocialapi')) { echo ''; exit; } @@ -1533,7 +1475,7 @@ function renderPage() // Split plugins into 2 arrays: ordered enabled plugins and disabled. $enabledPlugins = array_filter($pluginMeta, function($v) { return $v['order'] !== false; }); // Load parameters. - $enabledPlugins = load_plugin_parameter_values($enabledPlugins, $GLOBALS['plugins']); + $enabledPlugins = load_plugin_parameter_values($enabledPlugins, $conf->get('plugins', array())); uasort( $enabledPlugins, function($a, $b) { return $a['order'] - $b['order']; } @@ -1552,13 +1494,13 @@ function renderPage() if (isset($_POST['parameters_form'])) { unset($_POST['parameters_form']); foreach ($_POST as $param => $value) { - $GLOBALS['plugins'][$param] = escape($value); + $conf->set('plugins.'. $param, escape($value)); } } else { - $GLOBALS['config']['ENABLED_PLUGINS'] = save_plugin_config($_POST); + $conf->set('config.ENABLED_PLUGINS', save_plugin_config($_POST)); } - writeConfig($GLOBALS, isLoggedIn()); + $conf->write(isLoggedIn()); } catch (Exception $e) { error_log( @@ -1584,6 +1526,7 @@ function renderPage() function importFile($LINKSDB) { if (!isLoggedIn()) { die('Not allowed.'); } + $conf = ConfigManager::getInstance(); $filename=$_FILES['filetoupload']['name']; $filesize=$_FILES['filetoupload']['size']; @@ -1654,7 +1597,7 @@ function importFile($LINKSDB) } } } - $LINKSDB->savedb($GLOBALS['config']['PAGECACHE']); + $LINKSDB->savedb($conf->get('config.PAGECACHE')); echo ''; } @@ -1673,6 +1616,7 @@ function importFile($LINKSDB) */ function buildLinkList($PAGE,$LINKSDB) { + $conf = ConfigManager::getInstance(); // Used in templates $searchtags = !empty($_GET['searchtags']) ? escape($_GET['searchtags']) : ''; $searchterm = !empty($_GET['searchterm']) ? escape($_GET['searchterm']) : ''; @@ -1700,7 +1644,7 @@ function buildLinkList($PAGE,$LINKSDB) // If there is only a single link, we change on-the-fly the title of the page. if (count($linksToDisplay) == 1) { - $GLOBALS['pagetitle'] = $linksToDisplay[$keys[0]]['title'].' - '.$GLOBALS['title']; + $conf->set('pagetitle', $linksToDisplay[$keys[0]]['title'] .' - '. $conf->get('title')); } // Select articles according to paging. @@ -1716,7 +1660,7 @@ function buildLinkList($PAGE,$LINKSDB) while ($i<$end && $iget('redirector')); $classLi = ($i % 2) != 0 ? '' : 'publicLinkHightLight'; $link['class'] = $link['private'] == 0 ? $classLi : 'private'; $date = DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, $link['linkdate']); @@ -1758,14 +1702,14 @@ function buildLinkList($PAGE,$LINKSDB) 'result_count' => count($linksToDisplay), 'search_term' => $searchterm, 'search_tags' => $searchtags, - 'redirector' => empty($GLOBALS['redirector']) ? '' : $GLOBALS['redirector'], // Optional redirector URL. + 'redirector' => $conf->get('redirector'), // Optional redirector URL. 'token' => $token, 'links' => $linkDisp, 'tags' => $LINKSDB->allTags(), ); // FIXME! temporary fix - see #399. - if (!empty($GLOBALS['pagetitle']) && count($linkDisp) == 1) { - $data['pagetitle'] = $GLOBALS['pagetitle']; + if ($conf->exists('pagetitle') && count($linkDisp) == 1) { + $data['pagetitle'] = $conf->get('pagetitle'); } $pluginManager = PluginManager::getInstance(); @@ -1789,7 +1733,8 @@ function buildLinkList($PAGE,$LINKSDB) // Return an empty array if no thumbnail available. function computeThumbnail($url,$href=false) { - if (!$GLOBALS['config']['ENABLE_THUMBNAILS']) return array(); + $conf = ConfigManager::getInstance(); + if (!$conf->get('config.ENABLE_THUMBNAILS')) return array(); if ($href==false) $href=$url; // For most hosts, the URL of the thumbnail can be easily deduced from the URL of the link. @@ -1857,7 +1802,7 @@ function computeThumbnail($url,$href=false) // So we deport the thumbnail generation in order not to slow down page generation // (and we also cache the thumbnail) - if (!$GLOBALS['config']['ENABLE_LOCALCACHE']) return array(); // If local cache is disabled, no thumbnails for services which require the use a local cache. + if (! $conf->get('config.ENABLE_LOCALCACHE')) return array(); // If local cache is disabled, no thumbnails for services which require the use a local cache. if ($domain=='flickr.com' || endsWith($domain,'.flickr.com') || $domain=='vimeo.com' @@ -1880,7 +1825,7 @@ function computeThumbnail($url,$href=false) $path = parse_url($url,PHP_URL_PATH); if ("/talks/" !== substr($path,0,7)) return array(); // This is not a single video URL. } - $sign = hash_hmac('sha256', $url, $GLOBALS['salt']); // We use the salt to sign data (it's random, secret, and specific to each installation) + $sign = hash_hmac('sha256', $url, $conf->get('salt')); // We use the salt to sign data (it's random, secret, and specific to each installation) return array('src'=>index_url($_SERVER).'?do=genthumbnail&hmac='.$sign.'&url='.urlencode($url), 'href'=>$href,'width'=>'120','style'=>'height:auto;','alt'=>'thumbnail'); } @@ -1891,7 +1836,7 @@ function computeThumbnail($url,$href=false) $ext=strtolower(pathinfo($url,PATHINFO_EXTENSION)); if ($ext=='jpg' || $ext=='jpeg' || $ext=='png' || $ext=='gif') { - $sign = hash_hmac('sha256', $url, $GLOBALS['salt']); // We use the salt to sign data (it's random, secret, and specific to each installation) + $sign = hash_hmac('sha256', $url, $conf->get('salt')); // We use the salt to sign data (it's random, secret, and specific to each installation) return array('src'=>index_url($_SERVER).'?do=genthumbnail&hmac='.$sign.'&url='.urlencode($url), 'href'=>$href,'width'=>'120','style'=>'height:auto;','alt'=>'thumbnail'); } @@ -1988,21 +1933,28 @@ function install() if (!empty($_POST['setlogin']) && !empty($_POST['setpassword'])) { + $conf = ConfigManager::getInstance(); $tz = 'UTC'; if (!empty($_POST['continent']) && !empty($_POST['city']) && isTimeZoneValid($_POST['continent'], $_POST['city']) ) { $tz = $_POST['continent'].'/'.$_POST['city']; } - $GLOBALS['timezone'] = $tz; - // Everything is ok, let's create config file. - $GLOBALS['login'] = $_POST['setlogin']; - $GLOBALS['salt'] = sha1(uniqid('',true).'_'.mt_rand()); // Salt renders rainbow-tables attacks useless. - $GLOBALS['hash'] = sha1($_POST['setpassword'].$GLOBALS['login'].$GLOBALS['salt']); - $GLOBALS['title'] = (empty($_POST['title']) ? 'Shared links on '.escape(index_url($_SERVER)) : $_POST['title'] ); - $GLOBALS['config']['ENABLE_UPDATECHECK'] = !empty($_POST['updateCheck']); + $conf->set('timezone', $tz); + $login = $_POST['setlogin']; + $conf->set('login', $login); + $salt = sha1(uniqid('', true) .'_'. mt_rand()); + $conf->set('salt', $salt); + $conf->set('hash', sha1($_POST['setpassword'] . $login . $salt)); + if (!empty($_POST['title'])) { + $conf->set('title', $_POST['title']); + } else { + $conf->set('title', 'Shared links on '.escape(index_url($_SERVER))); + } + $conf->set('config.ENABLE_UPDATECHECK', !empty($_POST['updateCheck'])); try { - writeConfig($GLOBALS, isLoggedIn()); + // Everything is ok, let's create config file. + $conf->write(isLoggedIn()); } catch(Exception $e) { error_log( @@ -2043,24 +1995,26 @@ function install() */ function genThumbnail() { + $conf = ConfigManager::getInstance(); // Make sure the parameters in the URL were generated by us. - $sign = hash_hmac('sha256', $_GET['url'], $GLOBALS['salt']); + $sign = hash_hmac('sha256', $_GET['url'], $conf->get('salt')); if ($sign!=$_GET['hmac']) die('Naughty boy!'); + $cacheDir = $conf->get('config.CACHEDIR', 'cache'); // Let's see if we don't already have the image for this URL in the cache. $thumbname=hash('sha1',$_GET['url']).'.jpg'; - if (is_file($GLOBALS['config']['CACHEDIR'].'/'.$thumbname)) + if (is_file($cacheDir .'/'. $thumbname)) { // We have the thumbnail, just serve it: header('Content-Type: image/jpeg'); - echo file_get_contents($GLOBALS['config']['CACHEDIR'].'/'.$thumbname); + echo file_get_contents($cacheDir .'/'. $thumbname); return; } // We may also serve a blank image (if service did not respond) $blankname=hash('sha1',$_GET['url']).'.gif'; - if (is_file($GLOBALS['config']['CACHEDIR'].'/'.$blankname)) + if (is_file($cacheDir .'/'. $blankname)) { header('Content-Type: image/gif'); - echo file_get_contents($GLOBALS['config']['CACHEDIR'].'/'.$blankname); + echo file_get_contents($cacheDir .'/'. $blankname); return; } @@ -2107,7 +2061,7 @@ function genThumbnail() list($headers, $content) = get_http_response($imageurl, 10); if (strpos($headers[0], '200 OK') !== false) { // Save image to cache. - file_put_contents($GLOBALS['config']['CACHEDIR'].'/' . $thumbname, $content); + file_put_contents($cacheDir .'/'. $thumbname, $content); header('Content-Type: image/jpeg'); echo $content; return; @@ -2128,7 +2082,7 @@ function genThumbnail() list($headers, $content) = get_http_response($imageurl, 10); if (strpos($headers[0], '200 OK') !== false) { // Save image to cache. - file_put_contents($GLOBALS['config']['CACHEDIR'] . '/' . $thumbname, $content); + file_put_contents($cacheDir .'/'. $thumbname, $content); header('Content-Type: image/jpeg'); echo $content; return; @@ -2151,7 +2105,7 @@ function genThumbnail() // No control on image size, so wait long enough list($headers, $content) = get_http_response($imageurl, 20); if (strpos($headers[0], '200 OK') !== false) { - $filepath=$GLOBALS['config']['CACHEDIR'].'/'.$thumbname; + $filepath = $cacheDir .'/'. $thumbname; file_put_contents($filepath, $content); // Save image to cache. if (resizeImage($filepath)) { @@ -2179,7 +2133,7 @@ function genThumbnail() // No control on image size, so wait long enough list($headers, $content) = get_http_response($imageurl, 20); if (strpos($headers[0], '200 OK') !== false) { - $filepath=$GLOBALS['config']['CACHEDIR'].'/'.$thumbname; + $filepath = $cacheDir.'/'.$thumbname; // Save image to cache. file_put_contents($filepath, $content); if (resizeImage($filepath)) @@ -2199,7 +2153,7 @@ function genThumbnail() // We allow 30 seconds max to download (and downloads are limited to 4 Mb) list($headers, $content) = get_http_response($url, 30); if (strpos($headers[0], '200 OK') !== false) { - $filepath=$GLOBALS['config']['CACHEDIR'].'/'.$thumbname; + $filepath = $cacheDir .'/'.$thumbname; // Save image to cache. file_put_contents($filepath, $content); if (resizeImage($filepath)) @@ -2214,7 +2168,8 @@ function genThumbnail() // Otherwise, return an empty image (8x8 transparent gif) $blankgif = base64_decode('R0lGODlhCAAIAIAAAP///////yH5BAEKAAEALAAAAAAIAAgAAAIHjI+py+1dAAA7'); - file_put_contents($GLOBALS['config']['CACHEDIR'].'/'.$blankname,$blankgif); // Also put something in cache so that this URL is not requested twice. + // Also put something in cache so that this URL is not requested twice. + file_put_contents($cacheDir .'/'. $blankname, $blankgif); header('Content-Type: image/gif'); echo $blankgif; } @@ -2254,6 +2209,8 @@ function resizeImage($filepath) if (isset($_SERVER['QUERY_STRING']) && startsWith($_SERVER['QUERY_STRING'], 'do=genthumbnail')) { genThumbnail(); exit; } // Thumbnail generation/cache does not need the link database. if (isset($_SERVER['QUERY_STRING']) && startsWith($_SERVER['QUERY_STRING'], 'do=dailyrss')) { showDailyRSS(); exit; } -if (!isset($_SESSION['LINKS_PER_PAGE'])) $_SESSION['LINKS_PER_PAGE']=$GLOBALS['config']['LINKS_PER_PAGE']; +if (!isset($_SESSION['LINKS_PER_PAGE'])) { + $_SESSION['LINKS_PER_PAGE'] = $conf->get('config.LINKS_PER_PAGE', 20); +} renderPage(); ?> diff --git a/tests/ApplicationUtilsTest.php b/tests/ApplicationUtilsTest.php index 6064357..cf82b65 100644 --- a/tests/ApplicationUtilsTest.php +++ b/tests/ApplicationUtilsTest.php @@ -3,6 +3,7 @@ * ApplicationUtils' tests */ +require_once 'application/config/ConfigManager.php'; require_once 'application/ApplicationUtils.php'; /** @@ -59,7 +60,7 @@ class ApplicationUtilsTest extends PHPUnit_Framework_TestCase $testTimeout ) ); - $this->assertRegexp( + $this->assertRegExp( self::$versionPattern, ApplicationUtils::getLatestGitVersionCode( 'https://raw.githubusercontent.com/shaarli/Shaarli/' @@ -275,21 +276,21 @@ class ApplicationUtilsTest extends PHPUnit_Framework_TestCase */ public function testCheckCurrentResourcePermissions() { - $config = array( - 'CACHEDIR' => 'cache', - 'CONFIG_FILE' => 'data/config.php', - 'DATADIR' => 'data', - 'DATASTORE' => 'data/datastore.php', - 'IPBANS_FILENAME' => 'data/ipbans.php', - 'LOG_FILE' => 'data/log.txt', - 'PAGECACHE' => 'pagecache', - 'RAINTPL_TMP' => 'tmp', - 'RAINTPL_TPL' => 'tpl', - 'UPDATECHECK_FILENAME' => 'data/lastupdatecheck.txt' - ); + $conf = ConfigManager::getInstance(); + $conf->set('config.CACHEDIR', 'cache'); + $conf->set('config.CONFIG_FILE', 'data/config.php'); + $conf->set('config.DATADIR', 'data'); + $conf->set('config.DATASTORE', 'data/datastore.php'); + $conf->set('config.IPBANS_FILENAME', 'data/ipbans.php'); + $conf->set('config.LOG_FILE', 'data/log.txt'); + $conf->set('config.PAGECACHE', 'pagecache'); + $conf->set('config.RAINTPL_TMP', 'tmp'); + $conf->set('config.RAINTPL_TPL', 'tpl'); + $conf->set('config.UPDATECHECK_FILENAME', 'data/lastupdatecheck.txt'); + $this->assertEquals( array(), - ApplicationUtils::checkResourcePermissions($config) + ApplicationUtils::checkResourcePermissions() ); } @@ -298,18 +299,17 @@ class ApplicationUtilsTest extends PHPUnit_Framework_TestCase */ public function testCheckCurrentResourcePermissionsErrors() { - $config = array( - 'CACHEDIR' => 'null/cache', - 'CONFIG_FILE' => 'null/data/config.php', - 'DATADIR' => 'null/data', - 'DATASTORE' => 'null/data/store.php', - 'IPBANS_FILENAME' => 'null/data/ipbans.php', - 'LOG_FILE' => 'null/data/log.txt', - 'PAGECACHE' => 'null/pagecache', - 'RAINTPL_TMP' => 'null/tmp', - 'RAINTPL_TPL' => 'null/tpl', - 'UPDATECHECK_FILENAME' => 'null/data/lastupdatecheck.txt' - ); + $conf = ConfigManager::getInstance(); + $conf->set('config.CACHEDIR', 'null/cache'); + $conf->set('config.CONFIG_FILE', 'null/data/config.php'); + $conf->set('config.DATADIR', 'null/data'); + $conf->set('config.DATASTORE', 'null/data/store.php'); + $conf->set('config.IPBANS_FILENAME', 'null/data/ipbans.php'); + $conf->set('config.LOG_FILE', 'null/data/log.txt'); + $conf->set('config.PAGECACHE', 'null/pagecache'); + $conf->set('config.RAINTPL_TMP', 'null/tmp'); + $conf->set('config.RAINTPL_TPL', 'null/tpl'); + $conf->set('config.UPDATECHECK_FILENAME', 'null/data/lastupdatecheck.txt'); $this->assertEquals( array( '"null/tpl" directory is not readable', @@ -322,7 +322,7 @@ class ApplicationUtilsTest extends PHPUnit_Framework_TestCase '"null/tmp" directory is not readable', '"null/tmp" directory is not writable' ), - ApplicationUtils::checkResourcePermissions($config) + ApplicationUtils::checkResourcePermissions() ); } } diff --git a/tests/ConfigTest.php b/tests/ConfigTest.php deleted file mode 100644 index 7200aae..0000000 --- a/tests/ConfigTest.php +++ /dev/null @@ -1,244 +0,0 @@ - 'login', - 'hash' => 'hash', - 'salt' => 'salt', - 'timezone' => 'Europe/Paris', - 'title' => 'title', - 'titleLink' => 'titleLink', - 'redirector' => '', - 'disablesessionprotection' => false, - 'privateLinkByDefault' => false, - 'config' => array( - 'CONFIG_FILE' => 'tests/config.php', - 'DATADIR' => 'tests', - 'config1' => 'config1data', - 'config2' => 'config2data', - ) - ); - } - - /** - * Executed after each test. - * - * @return void - */ - public function tearDown() - { - if (is_file(self::$configFields['config']['CONFIG_FILE'])) { - unlink(self::$configFields['config']['CONFIG_FILE']); - } - } - - /** - * Test writeConfig function, valid use case, while being logged in. - */ - public function testWriteConfig() - { - writeConfig(self::$configFields, true); - - include self::$configFields['config']['CONFIG_FILE']; - $this->assertEquals(self::$configFields['login'], $GLOBALS['login']); - $this->assertEquals(self::$configFields['hash'], $GLOBALS['hash']); - $this->assertEquals(self::$configFields['salt'], $GLOBALS['salt']); - $this->assertEquals(self::$configFields['timezone'], $GLOBALS['timezone']); - $this->assertEquals(self::$configFields['title'], $GLOBALS['title']); - $this->assertEquals(self::$configFields['titleLink'], $GLOBALS['titleLink']); - $this->assertEquals(self::$configFields['redirector'], $GLOBALS['redirector']); - $this->assertEquals(self::$configFields['disablesessionprotection'], $GLOBALS['disablesessionprotection']); - $this->assertEquals(self::$configFields['privateLinkByDefault'], $GLOBALS['privateLinkByDefault']); - $this->assertEquals(self::$configFields['config']['config1'], $GLOBALS['config']['config1']); - $this->assertEquals(self::$configFields['config']['config2'], $GLOBALS['config']['config2']); - } - - /** - * Test writeConfig option while logged in: - * 1. init fields. - * 2. update fields, add new sub config, add new root config. - * 3. rewrite config. - * 4. check result. - */ - public function testWriteConfigFieldUpdate() - { - writeConfig(self::$configFields, true); - self::$configFields['title'] = 'ok'; - self::$configFields['config']['config1'] = 'ok'; - self::$configFields['config']['config_new'] = 'ok'; - self::$configFields['new'] = 'should not be saved'; - writeConfig(self::$configFields, true); - - include self::$configFields['config']['CONFIG_FILE']; - $this->assertEquals('ok', $GLOBALS['title']); - $this->assertEquals('ok', $GLOBALS['config']['config1']); - $this->assertEquals('ok', $GLOBALS['config']['config_new']); - $this->assertFalse(isset($GLOBALS['new'])); - } - - /** - * Test writeConfig function with an empty array. - * - * @expectedException MissingFieldConfigException - */ - public function testWriteConfigEmpty() - { - writeConfig(array(), true); - } - - /** - * Test writeConfig function with a missing mandatory field. - * - * @expectedException MissingFieldConfigException - */ - public function testWriteConfigMissingField() - { - unset(self::$configFields['login']); - writeConfig(self::$configFields, true); - } - - /** - * Test writeConfig function while being logged out, and there is no config file existing. - */ - public function testWriteConfigLoggedOutNoFile() - { - writeConfig(self::$configFields, false); - } - - /** - * Test writeConfig function while being logged out, and a config file already exists. - * - * @expectedException UnauthorizedConfigException - */ - public function testWriteConfigLoggedOutWithFile() - { - file_put_contents(self::$configFields['config']['CONFIG_FILE'], ''); - writeConfig(self::$configFields, false); - } - - /** - * Test save_plugin_config with valid data. - * - * @throws PluginConfigOrderException - */ - public function testSavePluginConfigValid() - { - $data = array( - 'order_plugin1' => 2, // no plugin related - 'plugin2' => 0, // new - at the end - 'plugin3' => 0, // 2nd - 'order_plugin3' => 8, - 'plugin4' => 0, // 1st - 'order_plugin4' => 5, - ); - - $expected = array( - 'plugin3', - 'plugin4', - 'plugin2', - ); - - $out = save_plugin_config($data); - $this->assertEquals($expected, $out); - } - - /** - * Test save_plugin_config with invalid data. - * - * @expectedException PluginConfigOrderException - */ - public function testSavePluginConfigInvalid() - { - $data = array( - 'plugin2' => 0, - 'plugin3' => 0, - 'order_plugin3' => 0, - 'plugin4' => 0, - 'order_plugin4' => 0, - ); - - save_plugin_config($data); - } - - /** - * Test save_plugin_config without data. - */ - public function testSavePluginConfigEmpty() - { - $this->assertEquals(array(), save_plugin_config(array())); - } - - /** - * Test validate_plugin_order with valid data. - */ - public function testValidatePluginOrderValid() - { - $data = array( - 'order_plugin1' => 2, - 'plugin2' => 0, - 'plugin3' => 0, - 'order_plugin3' => 1, - 'plugin4' => 0, - 'order_plugin4' => 5, - ); - - $this->assertTrue(validate_plugin_order($data)); - } - - /** - * Test validate_plugin_order with invalid data. - */ - public function testValidatePluginOrderInvalid() - { - $data = array( - 'order_plugin1' => 2, - 'order_plugin3' => 1, - 'order_plugin4' => 1, - ); - - $this->assertFalse(validate_plugin_order($data)); - } - - /** - * Test load_plugin_parameter_values. - */ - public function testLoadPluginParameterValues() - { - $plugins = array( - 'plugin_name' => array( - 'parameters' => array( - 'param1' => true, - 'param2' => false, - 'param3' => '', - ) - ) - ); - - $parameters = array( - 'param1' => 'value1', - 'param2' => 'value2', - ); - - $result = load_plugin_parameter_values($plugins, $parameters); - $this->assertEquals('value1', $result['plugin_name']['parameters']['param1']); - $this->assertEquals('value2', $result['plugin_name']['parameters']['param2']); - $this->assertEquals('', $result['plugin_name']['parameters']['param3']); - } -} diff --git a/tests/FeedBuilderTest.php b/tests/FeedBuilderTest.php index 069b158..a4d6960 100644 --- a/tests/FeedBuilderTest.php +++ b/tests/FeedBuilderTest.php @@ -76,7 +76,7 @@ class FeedBuilderTest extends PHPUnit_Framework_TestCase // Test headers (RSS) $this->assertEquals(self::$RSS_LANGUAGE, $data['language']); $this->assertEmpty($data['pubsubhub_url']); - $this->assertEquals('Tue, 10 Mar 2015 11:46:51 +0100', $data['last_update']); + $this->assertRegExp('/Tue, 10 Mar 2015 11:46:51 \+\d{4}/', $data['last_update']); $this->assertEquals(true, $data['show_dates']); $this->assertEquals('http://host.tld/index.php?do=feed', $data['self_link']); $this->assertEquals('http://host.tld/', $data['index_url']); @@ -88,7 +88,7 @@ class FeedBuilderTest extends PHPUnit_Framework_TestCase $this->assertEquals('20150310_114651', $link['linkdate']); $this->assertEquals('http://host.tld/?WDWyig', $link['guid']); $this->assertEquals('http://host.tld/?WDWyig', $link['url']); - $this->assertEquals('Tue, 10 Mar 2015 11:46:51 +0100', $link['iso_date']); + $this->assertRegExp('/Tue, 10 Mar 2015 11:46:51 \+\d{4}/', $link['iso_date']); $this->assertContains('Stallman has a beard', $link['description']); $this->assertContains('Permalink', $link['description']); $this->assertContains('http://host.tld/?WDWyig', $link['description']); @@ -113,7 +113,7 @@ class FeedBuilderTest extends PHPUnit_Framework_TestCase $data = $feedBuilder->buildData(); $this->assertEquals(ReferenceLinkDB::$NB_LINKS_TOTAL, count($data['links'])); $link = array_shift($data['links']); - $this->assertEquals('2015-03-10T11:46:51+01:00', $link['iso_date']); + $this->assertRegExp('/2015-03-10T11:46:51\+\d{2}:+\d{2}/', $link['iso_date']); } /** diff --git a/tests/LinkDBTest.php b/tests/LinkDBTest.php index b055fe9..956be3b 100644 --- a/tests/LinkDBTest.php +++ b/tests/LinkDBTest.php @@ -101,7 +101,7 @@ class LinkDBTest extends PHPUnit_Framework_TestCase * Attempt to instantiate a LinkDB whereas the datastore is not writable * * @expectedException IOException - * @expectedExceptionMessageRegExp /Error accessing null/ + * @expectedExceptionMessageRegExp /Error accessing\nnull/ */ public function testConstructDatastoreNotWriteable() { diff --git a/tests/Updater/DummyUpdater.php b/tests/Updater/DummyUpdater.php index e9ef2aa..6724b20 100644 --- a/tests/Updater/DummyUpdater.php +++ b/tests/Updater/DummyUpdater.php @@ -12,13 +12,12 @@ class DummyUpdater extends Updater * Object constructor. * * @param array $doneUpdates Updates which are already done. - * @param array $config Shaarli's configuration array. * @param LinkDB $linkDB LinkDB instance. * @param boolean $isLoggedIn True if the user is logged in. */ - public function __construct($doneUpdates, $config, $linkDB, $isLoggedIn) + public function __construct($doneUpdates, $linkDB, $isLoggedIn) { - parent::__construct($doneUpdates, $config, $linkDB, $isLoggedIn); + parent::__construct($doneUpdates, $linkDB, $isLoggedIn); // Retrieve all update methods. // For unit test, only retrieve final methods, diff --git a/tests/Updater/UpdaterTest.php b/tests/Updater/UpdaterTest.php index a29d906..8bfb4ba 100644 --- a/tests/Updater/UpdaterTest.php +++ b/tests/Updater/UpdaterTest.php @@ -1,5 +1,6 @@ false, 'privateLinkByDefault' => false, 'config' => array( - 'CONFIG_FILE' => 'tests/Updater/config.php', 'DATADIR' => 'tests/Updater', 'PAGECACHE' => 'sandbox/pagecache', 'config1' => 'config1data', 'config2' => 'config2data', ) ); + + ConfigManager::$CONFIG_FILE = 'tests/Updater/config'; + $this->conf = ConfigManager::getInstance(); + foreach (self::$configFields as $key => $value) { + $this->conf->set($key, $value); + } + $this->conf->write(true); } /** @@ -50,16 +67,16 @@ class UpdaterTest extends PHPUnit_Framework_TestCase */ public function tearDown() { - if (is_file(self::$configFields['config']['CONFIG_FILE'])) { - unlink(self::$configFields['config']['CONFIG_FILE']); + if (is_file(self::$configFile)) { + unlink(self::$configFile); } if (is_file(self::$configFields['config']['DATADIR'] . '/options.php')) { unlink(self::$configFields['config']['DATADIR'] . '/options.php'); } - if (is_file(self::$configFields['config']['DATADIR'] . '/updates.json')) { - unlink(self::$configFields['config']['DATADIR'] . '/updates.json'); + if (is_file(self::$configFields['config']['DATADIR'] . '/updates.txt')) { + unlink(self::$configFields['config']['DATADIR'] . '/updates.txt'); } } @@ -69,7 +86,7 @@ class UpdaterTest extends PHPUnit_Framework_TestCase public function testReadEmptyUpdatesFile() { $this->assertEquals(array(), read_updates_file('')); - $updatesFile = self::$configFields['config']['DATADIR'] . '/updates.json'; + $updatesFile = self::$configFields['config']['DATADIR'] . '/updates.txt'; touch($updatesFile); $this->assertEquals(array(), read_updates_file($updatesFile)); } @@ -79,7 +96,7 @@ class UpdaterTest extends PHPUnit_Framework_TestCase */ public function testReadWriteUpdatesFile() { - $updatesFile = self::$configFields['config']['DATADIR'] . '/updates.json'; + $updatesFile = self::$configFields['config']['DATADIR'] . '/updates.txt'; $updatesMethods = array('m1', 'm2', 'm3'); write_updates_file($updatesFile, $updatesMethods); @@ -112,7 +129,7 @@ class UpdaterTest extends PHPUnit_Framework_TestCase */ public function testWriteUpdatesFileNotWritable() { - $updatesFile = self::$configFields['config']['DATADIR'] . '/updates.json'; + $updatesFile = self::$configFields['config']['DATADIR'] . '/updates.txt'; touch($updatesFile); chmod($updatesFile, 0444); @write_updates_file($updatesFile, array('test')); @@ -131,10 +148,10 @@ class UpdaterTest extends PHPUnit_Framework_TestCase 'updateMethodDummy3', 'updateMethodException', ); - $updater = new DummyUpdater($updates, array(), array(), true); + $updater = new DummyUpdater($updates, array(), true); $this->assertEquals(array(), $updater->update()); - $updater = new DummyUpdater(array(), array(), array(), false); + $updater = new DummyUpdater(array(), array(), false); $this->assertEquals(array(), $updater->update()); } @@ -149,7 +166,7 @@ class UpdaterTest extends PHPUnit_Framework_TestCase 'updateMethodDummy2', 'updateMethodDummy3', ); - $updater = new DummyUpdater($updates, array(), array(), true); + $updater = new DummyUpdater($updates, array(), true); $this->assertEquals($expectedUpdates, $updater->update()); } @@ -165,7 +182,7 @@ class UpdaterTest extends PHPUnit_Framework_TestCase ); $expectedUpdate = array('updateMethodDummy2'); - $updater = new DummyUpdater($updates, array(), array(), true); + $updater = new DummyUpdater($updates, array(), true); $this->assertEquals($expectedUpdate, $updater->update()); } @@ -182,7 +199,7 @@ class UpdaterTest extends PHPUnit_Framework_TestCase 'updateMethodDummy3', ); - $updater = new DummyUpdater($updates, array(), array(), true); + $updater = new DummyUpdater($updates, array(), true); $updater->update(); } @@ -195,26 +212,25 @@ class UpdaterTest extends PHPUnit_Framework_TestCase */ public function testUpdateMergeDeprecatedConfig() { - // init - writeConfig(self::$configFields, true); - $configCopy = self::$configFields; - $invert = !$configCopy['privateLinkByDefault']; - $configCopy['privateLinkByDefault'] = $invert; - // Use writeConfig to create a options.php - $configCopy['config']['CONFIG_FILE'] = 'tests/Updater/options.php'; - writeConfig($configCopy, true); + ConfigManager::$CONFIG_FILE = 'tests/Updater/options'; + $invert = !$this->conf->get('privateLinkByDefault'); + $this->conf->set('privateLinkByDefault', $invert); + $this->conf->write(true); - $this->assertTrue(is_file($configCopy['config']['CONFIG_FILE'])); + $optionsFile = 'tests/Updater/options.php'; + $this->assertTrue(is_file($optionsFile)); + + ConfigManager::$CONFIG_FILE = 'tests/Updater/config'; // merge configs - $updater = new Updater(array(), self::$configFields, array(), true); + $updater = new Updater(array(), array(), true); $updater->updateMethodMergeDeprecatedConfigFile(); // make sure updated field is changed - include self::$configFields['config']['CONFIG_FILE']; - $this->assertEquals($invert, $GLOBALS['privateLinkByDefault']); - $this->assertFalse(is_file($configCopy['config']['CONFIG_FILE'])); + $this->conf->reload(); + $this->assertEquals($invert, $this->conf->get('privateLinkByDefault')); + $this->assertFalse(is_file($optionsFile)); } /** @@ -222,22 +238,22 @@ class UpdaterTest extends PHPUnit_Framework_TestCase */ public function testMergeDeprecatedConfigNoFile() { - writeConfig(self::$configFields, true); - - $updater = new Updater(array(), self::$configFields, array(), true); + $updater = new Updater(array(), array(), true); $updater->updateMethodMergeDeprecatedConfigFile(); - include self::$configFields['config']['CONFIG_FILE']; - $this->assertEquals(self::$configFields['login'], $GLOBALS['login']); + $this->assertEquals(self::$configFields['login'], $this->conf->get('login')); } + /** + * Test renameDashTags update method. + */ public function testRenameDashTags() { $refDB = new ReferenceLinkDB(); $refDB->write(self::$testDatastore); $linkDB = new LinkDB(self::$testDatastore, true, false); $this->assertEmpty($linkDB->filterSearch(array('searchtags' => 'exclude'))); - $updater = new Updater(array(), self::$configFields, $linkDB, true); + $updater = new Updater(array(), $linkDB, true); $updater->updateMethodRenameDashTags(); $this->assertNotEmpty($linkDB->filterSearch(array('searchtags' => 'exclude'))); } diff --git a/tests/config/ConfigPhpTest.php b/tests/config/ConfigPhpTest.php index 0f849bd..58cd8d2 100644 --- a/tests/config/ConfigPhpTest.php +++ b/tests/config/ConfigPhpTest.php @@ -22,7 +22,7 @@ class ConfigPhpTest extends PHPUnit_Framework_TestCase */ public function testRead() { - $conf = $this->configIO->read('tests/config/php/configOK'); + $conf = $this->configIO->read('tests/utils/config/configPhp.php'); $this->assertEquals('root', $conf['login']); $this->assertEquals('lala', $conf['redirector']); $this->assertEquals('data/datastore.php', $conf['config']['DATASTORE']); @@ -42,7 +42,7 @@ class ConfigPhpTest extends PHPUnit_Framework_TestCase */ public function testWriteNew() { - $dataFile = 'tests/config/php/configWrite'; + $dataFile = 'tests/utils/config/configWrite.php'; $data = array( 'login' => 'root', 'redirector' => 'lala', @@ -60,8 +60,8 @@ $GLOBALS[\'redirector\'] = \'lala\'; $GLOBALS[\'config\'][\'DATASTORE\'] = \'data/datastore.php\'; $GLOBALS[\'plugins\'][\'WALLABAG_VERSION\'] = \'1\'; '; - $this->assertEquals($expected, file_get_contents($dataFile .'.php')); - unlink($dataFile .'.php'); + $this->assertEquals($expected, file_get_contents($dataFile)); + unlink($dataFile); } /** @@ -69,14 +69,14 @@ $GLOBALS[\'plugins\'][\'WALLABAG_VERSION\'] = \'1\'; */ public function testOverwrite() { - $source = 'tests/config/php/configOK.php'; - $dest = 'tests/config/php/configOverwrite'; - copy($source, $dest . '.php'); + $source = 'tests/utils/config/configPhp.php'; + $dest = 'tests/utils/config/configOverwrite.php'; + copy($source, $dest); $conf = $this->configIO->read($dest); $conf['redirector'] = 'blabla'; $this->configIO->write($dest, $conf); $conf = $this->configIO->read($dest); $this->assertEquals('blabla', $conf['redirector']); - unlink($dest .'.php'); + unlink($dest); } } diff --git a/tests/config/php/configOK.php b/tests/config/php/configOK.php deleted file mode 100644 index b91ad29..0000000 --- a/tests/config/php/configOK.php +++ /dev/null @@ -1,14 +0,0 @@ -New link: + {if="$private_links_default"}checked{/if}/> @@ -57,7 +57,7 @@ RSS direct links + {if="$enable_rss_permalinks"}checked{/if}/>