support global and per-host configuration files
This commit is contained in:
parent
846e3a38cf
commit
82ee59779e
3 changed files with 329 additions and 3 deletions
109
src/SemanticScuttle/Config.php
Normal file
109
src/SemanticScuttle/Config.php
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* SemanticScuttle - your social bookmark manager.
|
||||||
|
*
|
||||||
|
* PHP version 5.
|
||||||
|
*
|
||||||
|
* @category Bookmarking
|
||||||
|
* @package SemanticScuttle
|
||||||
|
* @author Christian Weiske <cweiske@cweiske.de>
|
||||||
|
* @license AGPL http://www.gnu.org/licenses/agpl.html
|
||||||
|
* @link http://sourceforge.net/projects/semanticscuttle
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configuration handling
|
||||||
|
*
|
||||||
|
* @category Bookmarking
|
||||||
|
* @package SemanticScuttle
|
||||||
|
* @author Christian Weiske <cweiske@cweiske.de>
|
||||||
|
* @license AGPL http://www.gnu.org/licenses/agpl.html
|
||||||
|
* @link http://sourceforge.net/projects/semanticscuttle
|
||||||
|
*/
|
||||||
|
class SemanticScuttle_Config
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Prefix for configuration files.
|
||||||
|
* Used to inject stream wrapper protocol for unit testing
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $filePrefix = '';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds the correct data directory
|
||||||
|
*
|
||||||
|
* @return string Full path to the data directory with a trailing slash
|
||||||
|
*/
|
||||||
|
protected function getDataDir()
|
||||||
|
{
|
||||||
|
if ('@data_dir@' == '@' . 'data_dir@') {
|
||||||
|
//non pear-install
|
||||||
|
$datadir = dirname(__FILE__) . '/../../data/';
|
||||||
|
} else {
|
||||||
|
//pear installation; files are in include path
|
||||||
|
$datadir = '@data_dir@/SemanticScuttle/';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $datadir;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tries to find a configuration file by looking in different
|
||||||
|
* places:
|
||||||
|
* - pear data_dir/SemanticScuttle/config-$hostname.php
|
||||||
|
* - pear data_dir/SemanticScuttle/config.php
|
||||||
|
* - /etc/semanticscuttle/config-$hostname.php
|
||||||
|
* - /etc/semanticscuttle/config.php
|
||||||
|
*
|
||||||
|
* Paths with host name have priority.
|
||||||
|
*
|
||||||
|
* @return array Array with config file path as first value
|
||||||
|
* and default config file path as second value.
|
||||||
|
* Any may be NULL if not found
|
||||||
|
*/
|
||||||
|
public function findFiles()
|
||||||
|
{
|
||||||
|
//use basename to prevent path injection
|
||||||
|
$host = basename($_SERVER['HTTP_HOST']);
|
||||||
|
$datadir = $this->getDataDir();
|
||||||
|
|
||||||
|
$arFiles = array(
|
||||||
|
$datadir . 'config.' . $host . '.php',
|
||||||
|
'/etc/semanticscuttle/config.' . $host . '.php',
|
||||||
|
$datadir . 'config.php',
|
||||||
|
'/etc/semanticscuttle/config.php',
|
||||||
|
);
|
||||||
|
|
||||||
|
$configfile = null;
|
||||||
|
foreach ($arFiles as $file) {
|
||||||
|
if (file_exists($this->filePrefix . $file)) {
|
||||||
|
$configfile = $file;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//find default file
|
||||||
|
$arDefaultFiles = array_unique(
|
||||||
|
array(
|
||||||
|
substr($configfile, 0, -3) . 'default.php',
|
||||||
|
$datadir . 'config.default.php',
|
||||||
|
'/etc/semanticscuttle/config.default.php',
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$defaultfile = null;
|
||||||
|
foreach ($arDefaultFiles as $file) {
|
||||||
|
if (file_exists($this->filePrefix . $file)) {
|
||||||
|
$defaultfile = $file;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return array($configfile, $defaultfile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
|
@ -25,8 +25,19 @@ if ('@data_dir@' == '@' . 'data_dir@') {
|
||||||
//FIXME: when you have multiple installations, the www_dir will be wrong
|
//FIXME: when you have multiple installations, the www_dir will be wrong
|
||||||
$wwwdir = '@www_dir@/SemanticScuttle/';
|
$wwwdir = '@www_dir@/SemanticScuttle/';
|
||||||
}
|
}
|
||||||
|
require_once dirname(__FILE__) . '/Config.php';
|
||||||
|
|
||||||
if (!file_exists($datadir . '/config.php')) {
|
$cfg = new SemanticScuttle_Config();
|
||||||
|
list($configfile, $defaultfile) = $cfg->findFiles();
|
||||||
|
if ($defaultfile === null) {
|
||||||
|
header('HTTP/1.0 500 Internal Server Error');
|
||||||
|
die(
|
||||||
|
'No default configuration file config.default.php found.'
|
||||||
|
. ' This is really, really strange'
|
||||||
|
. "\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if ($configfile === null) {
|
||||||
header('HTTP/1.0 500 Internal Server Error');
|
header('HTTP/1.0 500 Internal Server Error');
|
||||||
die(
|
die(
|
||||||
'Please copy "config.php.dist" to "config.php" in data/ folder.'
|
'Please copy "config.php.dist" to "config.php" in data/ folder.'
|
||||||
|
@ -39,8 +50,8 @@ set_include_path(
|
||||||
);
|
);
|
||||||
|
|
||||||
// 1 // First requirements part (before debug management)
|
// 1 // First requirements part (before debug management)
|
||||||
require_once $datadir . '/config.default.php';
|
require_once $defaultfile;
|
||||||
require_once $datadir . '/config.php';
|
require_once $configfile;
|
||||||
|
|
||||||
if (isset($_GET['unittestMode']) && $_GET['unittestMode'] == 1
|
if (isset($_GET['unittestMode']) && $_GET['unittestMode'] == 1
|
||||||
) {
|
) {
|
||||||
|
|
206
tests/SemanticScuttle/ConfigTest.php
Normal file
206
tests/SemanticScuttle/ConfigTest.php
Normal file
|
@ -0,0 +1,206 @@
|
||||||
|
<?php
|
||||||
|
//that's PEAR's Stream_Var package
|
||||||
|
require_once 'Stream/Var.php';
|
||||||
|
|
||||||
|
class SemanticScuttle_ConfigTest_StreamVar extends Stream_Var {
|
||||||
|
public function url_stat($path, $flags)
|
||||||
|
{
|
||||||
|
$url = parse_url($path);
|
||||||
|
|
||||||
|
$scope = $url['host'];
|
||||||
|
if (isset($url['path'])) {
|
||||||
|
$varpath = substr($url['path'], 1);
|
||||||
|
} else {
|
||||||
|
$varpath = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$this->_setPointer($scope, $varpath)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent::url_stat($path, $flags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SemanticScuttle_ConfigTest extends PHPUnit_Framework_TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Configuration object to test
|
||||||
|
*/
|
||||||
|
protected $cfg;
|
||||||
|
|
||||||
|
|
||||||
|
public function setUpWrapper()
|
||||||
|
{
|
||||||
|
if (!in_array('unittest', stream_get_wrappers())) {
|
||||||
|
stream_wrapper_register(
|
||||||
|
'unittest', 'SemanticScuttle_ConfigTest_StreamVar'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->cfg = $this->getMock(
|
||||||
|
'SemanticScuttle_Config',
|
||||||
|
array('getDataDir')
|
||||||
|
);
|
||||||
|
$this->cfg->expects($this->once())
|
||||||
|
->method('getDataDir')
|
||||||
|
->will($this->returnValue('/data-dir/'));
|
||||||
|
|
||||||
|
$this->cfg->filePrefix = 'unittest://GLOBALS/unittest-dir';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public function testFindLocalData()
|
||||||
|
{
|
||||||
|
$this->setUpWrapper();
|
||||||
|
$GLOBALS['unittest-dir']['data-dir'] = array(
|
||||||
|
'config.php' => 'content',
|
||||||
|
'config.default.php' => 'content'
|
||||||
|
);
|
||||||
|
$this->assertEquals(
|
||||||
|
array(
|
||||||
|
'/data-dir/config.php',
|
||||||
|
'/data-dir/config.default.php'
|
||||||
|
),
|
||||||
|
$this->cfg->findFiles()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testFindHostPreferredOverNonHostConfig()
|
||||||
|
{
|
||||||
|
$this->setUpWrapper();
|
||||||
|
$_SERVER['HTTP_HOST'] = 'foo.example.org';
|
||||||
|
|
||||||
|
$GLOBALS['unittest-dir']['data-dir'] = array(
|
||||||
|
'config.php' => 'content',
|
||||||
|
'config.foo.example.org.php' => 'content',
|
||||||
|
'config.default.php' => 'content'
|
||||||
|
);
|
||||||
|
$this->assertEquals(
|
||||||
|
array(
|
||||||
|
'/data-dir/config.foo.example.org.php',
|
||||||
|
'/data-dir/config.default.php'
|
||||||
|
),
|
||||||
|
$this->cfg->findFiles()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testFindEtcHostPreferredOverLocalConfigPhp()
|
||||||
|
{
|
||||||
|
$this->setUpWrapper();
|
||||||
|
$_SERVER['HTTP_HOST'] = 'foo.example.org';
|
||||||
|
|
||||||
|
$GLOBALS['unittest-dir'] = array(
|
||||||
|
'etc' => array(
|
||||||
|
'semanticscuttle' => array(
|
||||||
|
'config.foo.example.org.php' => 'content',
|
||||||
|
)
|
||||||
|
),
|
||||||
|
'data-dir' => array(
|
||||||
|
'config.php' => 'content',
|
||||||
|
'config.default.php' => 'content'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertEquals(
|
||||||
|
array(
|
||||||
|
'/etc/semanticscuttle/config.foo.example.org.php',
|
||||||
|
'/data-dir/config.default.php'
|
||||||
|
),
|
||||||
|
$this->cfg->findFiles()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testFindEtcConfig()
|
||||||
|
{
|
||||||
|
$this->setUpWrapper();
|
||||||
|
$GLOBALS['unittest-dir'] = array(
|
||||||
|
'etc' => array(
|
||||||
|
'semanticscuttle' => array(
|
||||||
|
'config.php' => 'content'
|
||||||
|
)
|
||||||
|
),
|
||||||
|
'data-dir' => array(
|
||||||
|
'config.default.php' => 'content'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$this->assertEquals(
|
||||||
|
array(
|
||||||
|
'/etc/semanticscuttle/config.php',
|
||||||
|
'/data-dir/config.default.php'
|
||||||
|
),
|
||||||
|
$this->cfg->findFiles()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testFindEtcDefaultConfig()
|
||||||
|
{
|
||||||
|
$this->setUpWrapper();
|
||||||
|
$GLOBALS['unittest-dir'] = array(
|
||||||
|
'etc' => array(
|
||||||
|
'semanticscuttle' => array(
|
||||||
|
'config.php' => 'content',
|
||||||
|
'config.default.php' => 'content'
|
||||||
|
)
|
||||||
|
),
|
||||||
|
);
|
||||||
|
$this->assertEquals(
|
||||||
|
array(
|
||||||
|
'/etc/semanticscuttle/config.php',
|
||||||
|
'/etc/semanticscuttle/config.default.php'
|
||||||
|
),
|
||||||
|
$this->cfg->findFiles()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testFindLocalDefaultPreferredOverEtcDefault()
|
||||||
|
{
|
||||||
|
$this->setUpWrapper();
|
||||||
|
$GLOBALS['unittest-dir'] = array(
|
||||||
|
'etc' => array(
|
||||||
|
'semanticscuttle' => array(
|
||||||
|
'config.php' => 'content',
|
||||||
|
'config.default.php' => 'content'
|
||||||
|
)
|
||||||
|
),
|
||||||
|
'data-dir' => array(
|
||||||
|
'config.php' => 'content',
|
||||||
|
'config.default.php' => 'content'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$this->assertEquals(
|
||||||
|
array(
|
||||||
|
'/data-dir/config.php',
|
||||||
|
'/data-dir/config.default.php'
|
||||||
|
),
|
||||||
|
$this->cfg->findFiles()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testFindSameDirDefaultPreferred()
|
||||||
|
{
|
||||||
|
$this->setUpWrapper();
|
||||||
|
$GLOBALS['unittest-dir'] = array(
|
||||||
|
'etc' => array(
|
||||||
|
'semanticscuttle' => array(
|
||||||
|
'config.php' => 'content',
|
||||||
|
'config.default.php' => 'content'
|
||||||
|
)
|
||||||
|
),
|
||||||
|
'data-dir' => array(
|
||||||
|
'config.default.php' => 'content'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$this->assertEquals(
|
||||||
|
array(
|
||||||
|
'/etc/semanticscuttle/config.php',
|
||||||
|
'/etc/semanticscuttle/config.default.php'
|
||||||
|
),
|
||||||
|
$this->cfg->findFiles()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
Loading…
Reference in a new issue