]> gitweb.fluxo.info Git - semanticscuttle.git/commitdiff
support global and per-host configuration files
authorChristian Weiske <cweiske@cweiske.de>
Thu, 21 Jul 2011 19:32:48 +0000 (21:32 +0200)
committerChristian Weiske <cweiske@cweiske.de>
Thu, 21 Jul 2011 19:32:48 +0000 (21:32 +0200)
src/SemanticScuttle/Config.php [new file with mode: 0644]
src/SemanticScuttle/header.php
tests/SemanticScuttle/ConfigTest.php [new file with mode: 0644]

diff --git a/src/SemanticScuttle/Config.php b/src/SemanticScuttle/Config.php
new file mode 100644 (file)
index 0000000..0773310
--- /dev/null
@@ -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);
+    }
+}
+
+?>
\ No newline at end of file
index 6c0d4dff71f3c247326b06461b2ab51274ffe3e1..92523003060271d5ac33cc6bcf5fbeccad889a27 100644 (file)
@@ -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
 ) {
diff --git a/tests/SemanticScuttle/ConfigTest.php b/tests/SemanticScuttle/ConfigTest.php
new file mode 100644 (file)
index 0000000..670f82a
--- /dev/null
@@ -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()
+        );
+    }
+
+}
+
+?>
\ No newline at end of file