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
|
||||
$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');
|
||||
die(
|
||||
'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)
|
||||
require_once $datadir . '/config.default.php';
|
||||
require_once $datadir . '/config.php';
|
||||
require_once $defaultfile;
|
||||
require_once $configfile;
|
||||
|
||||
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