Skip to content

Instantly share code, notes, and snippets.

@petrabarus
Created June 26, 2013 01:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save petrabarus/5863901 to your computer and use it in GitHub Desktop.
Save petrabarus/5863901 to your computer and use it in GitHub Desktop.
<?php
/**
* ConfigLoader class file.
*
* @author Petra Barus <petra.barus@gmail.com>
* @package application.components
* @since 2013.02.15
*/
/**
* ConfigLoader handles hierarchical configuration file from configuration
* directory.
*
* A configuration directory will look like this.
*
* protected/config/environments
* +- default
* | +- application
* | | +- components.php //contains default components
* | | +- params.php //contains default params
* | +- application.php //contains default config, e.g. application name, timezone, language.
* +- web
* | +- application
* | | +- urlManager.php //contains default url manager or rules for web
* | +- application.php
* +- console
* | +- application.php
* +- test
* | +- application
* | | +- components
* | | | +- db.php //contains default database for testing
* | +- application.php
* +- development
* | +- application
* | | +- components
* | | +- clientScript
* | | +- packages.php //contains javascript packages for local development
* | +- application.php
* +- production
* | +- application
* | | +- components
* | | +- clientScript
* | | +- packages.php //contains javascript packages for production
* | | +- db.php //contains default database for production
* | | +- mailer.php //contains default mailer components
* | +- application.php
* +- console-production //contains configuration for console production
* +- application
* +- components
* +- request.php //contains request component configuration.
*
* To load configuration use the loadConfiguration() method.
* e.g. in index.php
*
* $dir = dirname(__FILE__) . '/protected/config/environments';
* $config = ConfigLoader::loadConfiguration($dir, array('default', 'web', 'test'));
* Yii::createWebApplication($config)->run();
*
* The ConfigLoader::loadConfiguration() also receive file path and array.
* e.g.
*
* $dir = dirname(__FILE__) . '/protected/config/environments';
* $config = ConfigLoader::loadConfiguration($dir, array('default', 'web', 'test', '/usr/local/share/production.php', array('language' => 'en')));
* Yii::createWebApplication($config)->run();
*
* Since this will load a lot of files, the config can be merged for production
* using the config command
*
* $yiic config build --directory=protected/config/environments
* --config=default --config=web --config=production
* --config=/user/local/share/production.php > protected/config/production.php
*
* @author Petra Barus <petra.barus@gmail.com>
* @package application.components
* @since 2013.02.15
*/
class ConfigLoader
{
/**
* Load configuration from a directory.
*
* This load configuration hierarchical. The second parameters can contain
* two types: array and string. If it's array then load the configuration
* from the array. If it's string then load the configuration from the
* directory named by the string. The config will be loaded from the first
* loaded element, and the last will override the first.
*
* @param string $configdir the configuration directory.
* @param array $configs array of configurations.
* @return array array of configuration.
* @since 2013.02.15
*/
public static function loadConfiguration($configdir, $configs = array())
{
//$configs = array_merge(array('default'), $configs);
$configuration = new CMap();
foreach ($configs as $config) {
if (is_array($config)) {//additional configuration
$configuration->mergeWith($config);
} else if (is_file($config)) {//if the configuration is already a file.
$configuration->mergeWith(require_once($config));
} else if (is_string($config)) {//this is a path name
$configuration->mergeWith(self::loadConfigurationFiles($configdir, $config));
}
}
return $configuration->toArray();
}
/**
* Load configuration from files.
*
* This will load hierarchical configuration files. Since the files are
* sorted by alphabet, never use a conflicted config in one directory.
*
* @param string $basedir the base directory containing environments of the
* configurations.
* @param string $name the sub name of the configurations.
* @return \CMap
*/
private static function loadConfigurationFiles($basedir, $name)
{
$configuration = new CMap();
if (file_exists($basedir)) {
$dir = $basedir . DIRECTORY_SEPARATOR . $name;
if (is_file($application = $dir . DIRECTORY_SEPARATOR . 'application.php')) {
$configuration->mergeWith(require_once($application));
}
$dir .= DIRECTORY_SEPARATOR . 'application';
if (is_dir($dir)) {
$files = CFileHelper::findFiles($dir, array('fileTypes' => array('php')));
foreach ($files as $file) {
$path = str_replace($dir, '', $file);
$pathArray = explode(DIRECTORY_SEPARATOR, $path);
$subconfig = array();
$curconfig = &$subconfig; //pointing while iterating
for ($i = 0; $i < count($pathArray); $i++) {
$segment = trim($pathArray[$i]);
if (!empty($segment)) {
if ($i == count($pathArray) - 1) { //the end of segment, which is the filename
$segment = str_replace('.php', '', $segment);
$curconfig[$segment] = require_once($file);
} else {
$curconfig[$segment] = array();
//descent to sub config
$curconfig = &$curconfig[$segment];
}
}
}
if (is_array($subconfig)) {
$configuration->mergeWith($subconfig);
}
}
}
}
return $configuration;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment