├── .gitignore ├── README ├── lib ├── dd_configuration_IResourceLoader.php ├── dd_configuration_CompositeConfiguration.php ├── dd_configuration_ClasspathResourceLoader.php ├── dd_configuration_PdoConfiguration.php ├── dd_configuration_IConfiguration.php ├── dd_configuration_MapConfiguration.php ├── dd_configuration_Util.php ├── dd_configuration_AbstractConfiguration.php ├── dd_configuration_PropertiesConfiguration.php ├── dd_configuration_Resolver.php └── dd_configuration_PathResourceLoader.php └── LICENSE /.gitignore: -------------------------------------------------------------------------------- 1 | .buildpath 2 | .project 3 | .settings 4 | ._* 5 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | Dragonfly Development PHP Configuration Library 2 | http://dflydev.com/d2code/php/dd-configuration-php/ 3 | 4 | 5 | dd-configuration provides a generic configuration interface enabling PHP 6 | developers to enjoy some of the benefits provided Java users by way of the 7 | Apache Commons Configuration library. 8 | 9 | 10 | Inspired by Apache Commons Configuration 11 | http://commons.apache.org/configuration/ 12 | -------------------------------------------------------------------------------- /lib/dd_configuration_IResourceLoader.php: -------------------------------------------------------------------------------- 1 | 23 | -------------------------------------------------------------------------------- /lib/dd_configuration_CompositeConfiguration.php: -------------------------------------------------------------------------------- 1 | import($configurations); 26 | } 27 | 28 | } 29 | 30 | ?> 31 | -------------------------------------------------------------------------------- /lib/dd_configuration_ClasspathResourceLoader.php: -------------------------------------------------------------------------------- 1 | 38 | -------------------------------------------------------------------------------- /lib/dd_configuration_PdoConfiguration.php: -------------------------------------------------------------------------------- 1 | prepare($sql); 29 | $sth->execute(); 30 | foreach ( $sth->fetchAll(PDO::FETCH_ASSOC) as $row ) { 31 | $this->map[$row['configurationKey']] = $row['configurationValue']; 32 | } 33 | } 34 | 35 | } 36 | 37 | ?> 38 | -------------------------------------------------------------------------------- /lib/dd_configuration_IConfiguration.php: -------------------------------------------------------------------------------- 1 | 68 | -------------------------------------------------------------------------------- /lib/dd_configuration_MapConfiguration.php: -------------------------------------------------------------------------------- 1 | map = $map; 23 | } 24 | 25 | /** 26 | * All keys 27 | * @return array 28 | */ 29 | public function keys() { 30 | return array_keys($this->map); 31 | } 32 | 33 | /** 34 | * Get raw value for key 35 | * 36 | * Value will be returned raw and will not contain any resolved 37 | * results. 38 | * 39 | * @param string $key Key 40 | * @return mixed 41 | */ 42 | public function getRaw($key) { 43 | return array_key_exists($key, $this->map) ? $this->map[$key] : null; 44 | } 45 | 46 | /** 47 | * Set value for a key 48 | * @input string $key Key 49 | * @input mixed $value Value 50 | */ 51 | public function set($key, $value = null) { 52 | $this->map[$key] = $value; 53 | } 54 | 55 | /** 56 | * Does a key exist? 57 | * @input string $key Key 58 | * @return bool 59 | */ 60 | public function exists($key) { 61 | return array_key_exists($key, $this->map); 62 | } 63 | 64 | } 65 | 66 | ?> 67 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2010, Dragonfly Development Inc 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, 8 | this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above copyright 10 | notice, this list of conditions and the following disclaimer in the 11 | documentation and/or other materials provided with the distribution. 12 | * Neither the name of Dragonfly Development Inc nor the names of its 13 | contributors may be used to endorse or promote products derived from 14 | this software without specific prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 20 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 | POSSIBILITY OF SUCH DAMAGE. 27 | -------------------------------------------------------------------------------- /lib/dd_configuration_Util.php: -------------------------------------------------------------------------------- 1 | keys() as $key ) { 22 | $importer->set($key, $importee->getRaw($key)); 23 | } 24 | return true; 25 | } 26 | 27 | /** 28 | * Resolve a key 29 | * @param dd_configuration_IConfiguration $configuration Configuration 30 | * @param string $key Key 31 | * @return string Resolved key 32 | */ 33 | static public function RESOLVE_KEY(dd_configuration_IConfiguration $configuration, $key) { 34 | return $configuration->resolver()->resolveKey($configuration, $key); 35 | } 36 | 37 | /** 38 | * Resolve a value 39 | * @param dd_configuration_IConfiguration $configuration Configuration 40 | * @param string $value value 41 | * @return string Resolved key 42 | */ 43 | static public function RESOLVE_VALUE(dd_configuration_IConfiguration $configuration, $value) { 44 | return $configuration->resolver()->resolveValue($configuration, $value); 45 | } 46 | 47 | } 48 | 49 | ?> 50 | -------------------------------------------------------------------------------- /lib/dd_configuration_AbstractConfiguration.php: -------------------------------------------------------------------------------- 1 | resolver === null ) { 43 | $this->resolver = new dd_configuration_Resolver($this); 44 | } 45 | return $this->resolver; 46 | } 47 | 48 | /** 49 | * Import another configuration 50 | * @param mixed $input dd_configuration_IConfiguration or array 51 | */ 52 | public function import($configuration) { 53 | if ( ! is_array($configuration) ) { 54 | $configuration = array($configuration); 55 | } 56 | foreach ( $configuration as $item ) { 57 | if ( ! dd_configuration_Util::IMPORT($this, $item) ) { 58 | return false; 59 | } 60 | } 61 | return true; 62 | } 63 | 64 | } 65 | 66 | ?> 67 | -------------------------------------------------------------------------------- /lib/dd_configuration_PropertiesConfiguration.php: -------------------------------------------------------------------------------- 1 | resourceLoader = new dd_configuration_ClasspathResourceLoader( 37 | isset($trace[0]['file']) ? $trace[0]['file'] : null 38 | ); 39 | } 40 | else $this->resourceLoader = $resourceLoader; 41 | 42 | if ( $locations !== null ) $this->addLocations($locations); 43 | 44 | } 45 | 46 | /** 47 | * Add properties file locations 48 | * 49 | * May accept a string specifying location or an array containing 50 | * multiple location strings. This is the most flexible way to 51 | * add locations. 52 | * 53 | * @param mixed $locations Locations 54 | */ 55 | public function addLocations($locations = null) { 56 | 57 | if ( $locations !== null ) { 58 | if ( ! is_array($locations) ) $locations = array($locations); 59 | foreach ( $locations as $location ) { 60 | $this->addLocation($location); 61 | } 62 | } 63 | 64 | } 65 | 66 | /** 67 | * Add a properties file location 68 | * 69 | * Requires passed value to be a location string. 70 | * 71 | * @param string $location Location 72 | */ 73 | public function addLocation($location) { 74 | 75 | if ( is_array($location) ) throw new Exception('Cannot specify location as an array'); 76 | 77 | $path = $this->resourceLoader->find($location); 78 | 79 | if ( $path !== null ) { 80 | 81 | $this->locations[] = $path; 82 | 83 | $content = file_get_contents($path); 84 | 85 | foreach ( explode("\n", $content) as $line ) { 86 | 87 | preg_match('/^\s*([^=]+?)\s*=\s*(.+?)\s*$/', $line, $matches); 88 | 89 | if ( count($matches) > 1 && strlen($matches[1]) > 0 && strpos($matches[1], '#') !== 0) { 90 | $this->map[$matches[1]] = $matches[2]; 91 | } 92 | 93 | } 94 | 95 | } 96 | 97 | } 98 | 99 | } 100 | 101 | ?> 102 | -------------------------------------------------------------------------------- /lib/dd_configuration_Resolver.php: -------------------------------------------------------------------------------- 1 | resolved) ) { 29 | $this->resolved[$key] = $this->resolveValue($configuration, $configuration->getRaw($key)); 30 | } 31 | return $this->resolved[$key]; 32 | } 33 | 34 | /** 35 | * Resolve a value 36 | * @param dd_configuration_IConfiguration $configuration Configuration 37 | * @param string $key Key 38 | * @return string 39 | */ 40 | public function resolveValue(dd_configuration_IConfiguration $configuration, $value) { 41 | 42 | $counter = 0; 43 | $resolverCallback = new dd_configuration_ResolverCallback( 44 | $configuration 45 | ); 46 | while ( true ) { 47 | 48 | $newValue = preg_replace_callback( 49 | '/\${([a-zA-Z0-9\.\(\)_\:]+?)}/', 50 | array($resolverCallback, 'resolveCallback'), 51 | $value 52 | ); 53 | 54 | if ( $newValue === $value ) { 55 | break; 56 | } 57 | 58 | $value = $newValue; 59 | 60 | // Break recursion if depth goes beyond 10! 61 | // TODO Make this configurable? 62 | if ( $counter++ > 10 ) break; 63 | 64 | } 65 | 66 | return $value; 67 | 68 | } 69 | 70 | } 71 | 72 | /** 73 | * Configuration Resolver Callback. 74 | * @package dd_configuration 75 | */ 76 | class dd_configuration_ResolverCallback { 77 | 78 | /** 79 | * Configuration 80 | * @var dd_configuration_IConfiguration 81 | */ 82 | protected $configuration; 83 | 84 | /** 85 | * Constructor 86 | * @param dd_configuration_IConfiguration $configuration Configuration 87 | */ 88 | public function __construct(dd_configuration_IConfiguration $configuration) { 89 | $this->configuration = $configuration; 90 | } 91 | 92 | /** 93 | * preg_replace_callback Callback. 94 | * @param array $matches Matches 95 | */ 96 | public function resolveCallback($matches) { 97 | $key = $matches[1]; 98 | if ( preg_match('/^(ENV|SERVER|CONSTANT):(\w+)$/', $key, $special) ) { 99 | list($whole, $which, $key) = $special; 100 | if ( $which == 'ENV' ) { 101 | if ( array_key_exists($key, $_ENV) ) { 102 | return $_ENV[$key]; 103 | } 104 | } elseif ( $which == 'SERVER' ) { 105 | if ( array_key_exists($key, $_SERVER) ) { 106 | return $_SERVER[$key]; 107 | } 108 | } elseif ( $which == 'CONSTANT' ) { 109 | if ( defined($key) ) { 110 | return constant($key); 111 | } 112 | } 113 | } 114 | if ( $this->configuration->exists($key) ) { 115 | return $this->configuration->get($key); 116 | } 117 | return $matches[0]; 118 | } 119 | 120 | } 121 | 122 | ?> 123 | -------------------------------------------------------------------------------- /lib/dd_configuration_PathResourceLoader.php: -------------------------------------------------------------------------------- 1 | callingFile = $callingFile; 51 | } 52 | if ( $paths !== null ) { 53 | if ( ! is_array($paths) ) { 54 | $paths = array($paths); 55 | } 56 | foreach ( $paths as $path ) { 57 | $this->paths[] = $path; 58 | } 59 | } 60 | if ( $prependedPaths !== null ) { 61 | if ( ! is_array($prependedPaths) ) { 62 | $prependedPaths = array($prependedPaths); 63 | } 64 | foreach ( $prependedPaths as $path ) { 65 | $this->prependedPaths[] = $path; 66 | } 67 | } 68 | if ( $appendedPaths !== null ) { 69 | if ( ! is_array($appendedPaths) ) { 70 | $appendedPaths = array($appendedPaths); 71 | } 72 | foreach ( $appendedPaths as $path ) { 73 | $this->appendedPaths[] = $path; 74 | } 75 | } 76 | } 77 | 78 | /** 79 | * Find the path for a location 80 | * @param string $location Location 81 | * @return string 82 | */ 83 | public function find($location) { 84 | 85 | if ( strpos($location, '/') === 0 ) { 86 | if ( file_exists($location) ) return $location; 87 | return null; 88 | } 89 | 90 | foreach ( $this->allPaths() as $path ) { 91 | $testLocation = $path . '/' . $location; 92 | // TODO This could possibly be cached eventually. 93 | if ( file_exists($testLocation) ) return $testLocation; 94 | } 95 | 96 | // Could not be found. 97 | return null; 98 | 99 | } 100 | 101 | /** 102 | * Paths to search 103 | * @return array 104 | */ 105 | public function allPaths() { 106 | 107 | $callingFiles = array(); 108 | if ( $this->callingFile ) $callingFiles[] = dirname($this->callingFile); 109 | 110 | return array_merge( 111 | $callingFiles, 112 | $this->prependedPaths(), 113 | $this->paths(), 114 | $this->appendedPaths() 115 | ); 116 | 117 | } 118 | 119 | /** 120 | * Paths 121 | * @return array 122 | */ 123 | public function paths() { 124 | return $this->paths; 125 | } 126 | 127 | /** 128 | * Prepend a path to the classpath 129 | * @param string $path Path 130 | */ 131 | public function prependPath($path) { 132 | array_unshift($this->prependedPaths, $path); 133 | } 134 | 135 | /** 136 | * Append a path to the classpath 137 | * @param string $path Path 138 | */ 139 | public function appendPath($path) { 140 | push($this->appendedPaths, $path); 141 | } 142 | 143 | /** 144 | * Prepended paths 145 | * @return array 146 | */ 147 | public function prependedPaths() { 148 | return $this->prependedPaths; 149 | } 150 | 151 | /** 152 | * Appended paths 153 | * @return array 154 | */ 155 | public function appendedPaths() { 156 | return $this->appendedPaths; 157 | } 158 | 159 | 160 | } 161 | 162 | ?> 163 | --------------------------------------------------------------------------------