300 lines
7 KiB
PHP
300 lines
7 KiB
PHP
<?php
|
|
|
|
/**
|
|
* Configuration Class File for PICKLES
|
|
*
|
|
* PHP version 5
|
|
*
|
|
* Licensed under The MIT License
|
|
* Redistribution of these files must retain the above copyright notice.
|
|
*
|
|
* @author Joshua Sherman <pickles@joshtronic.com>
|
|
* @copyright Copyright 2007-2013, Joshua Sherman
|
|
* @license http://www.opensource.org/licenses/mit-license.html
|
|
* @package PICKLES
|
|
* @link https://github.com/joshtronic/pickles
|
|
*/
|
|
|
|
/**
|
|
* Config Class
|
|
*
|
|
* Handles loading the site's configuration file (if available). At the moment
|
|
* this class is a very skewed Singleton. The plan is to eventually extend this
|
|
* out to support multiple configuration files, and the ability to load in
|
|
* custom config files on the fly as well. The core of PICKLES uses the class
|
|
* as a Singleton so we're not loading the configuration multiple times per
|
|
* page load.
|
|
*
|
|
* @usage <code>$config = new Config($filename);</code>
|
|
*/
|
|
class Config extends Object
|
|
{
|
|
/**
|
|
* Config data
|
|
*
|
|
* @access private
|
|
* @var array
|
|
*/
|
|
private $data = array();
|
|
|
|
/**
|
|
* Constructor
|
|
*
|
|
* Calls the parent constructor and loads the passed file.
|
|
*
|
|
* @param string $filename optional Filename of the config
|
|
*/
|
|
public function __construct($filename = null)
|
|
{
|
|
parent::__construct();
|
|
|
|
// Try to fine the configuration
|
|
if ($filename == null)
|
|
{
|
|
$filename = 'config.php';
|
|
$loaded = false;
|
|
$cwd = getcwd();
|
|
|
|
while ($loaded == false)
|
|
{
|
|
chdir(dirname($filename));
|
|
|
|
if (getcwd() == '/')
|
|
{
|
|
throw new Exception('Unable to load configuration.');
|
|
}
|
|
|
|
chdir($cwd);
|
|
|
|
$filename = '../' . $filename;
|
|
$loaded = $this->load($filename);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
$this->load($filename);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Loads a configuration file
|
|
*
|
|
* @param string $filename filename of the config file
|
|
* @return boolean success of the load process
|
|
*/
|
|
public function load($filename)
|
|
{
|
|
$environments = false;
|
|
$environment = false;
|
|
|
|
// Sanity checks the config file
|
|
if (file_exists($filename) && is_file($filename) && is_readable($filename))
|
|
{
|
|
require_once $filename;
|
|
|
|
// Determines the environment
|
|
if (isset($config['environment']))
|
|
{
|
|
$environment = $config['environment'];
|
|
}
|
|
else
|
|
{
|
|
if (isset($config['environments']) && is_array($config['environments']))
|
|
{
|
|
$environments = $config['environments'];
|
|
|
|
// If we're on the CLI, check an environment was even passed in
|
|
if (IS_CLI == true && $_SERVER['argc'] < 2)
|
|
{
|
|
throw new Exception('You must pass an environment (e.g. php script.php <environment>)');
|
|
}
|
|
|
|
// Loops through the environments and tries to match on IP or name
|
|
foreach ($config['environments'] as $name => $hosts)
|
|
{
|
|
if (!is_array($hosts))
|
|
{
|
|
$hosts = array($hosts);
|
|
}
|
|
|
|
// Tries to determine the environment name
|
|
foreach ($hosts as $host)
|
|
{
|
|
if (IS_CLI == true)
|
|
{
|
|
// Checks the first argument on the command line
|
|
if ($_SERVER['argv'][1] == $name)
|
|
{
|
|
$environment = $name;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Exact match
|
|
if ((preg_match('/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/', $host)
|
|
&& $_SERVER['SERVER_ADDR'] == $host)
|
|
|| $_SERVER['HTTP_HOST'] == $host)
|
|
{
|
|
$environment = $name;
|
|
break;
|
|
}
|
|
// Fuzzy match
|
|
elseif (substr($host,0,1) == '/' && (preg_match($host, $_SERVER['SERVER_NAME'], $matches) > 0 || preg_match($host, $_SERVER['HTTP_HOST'], $matches) > 0))
|
|
{
|
|
$environments[$name] = $matches[0];
|
|
$environment = $name;
|
|
$config['environments'][$name] = $matches[0];
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Flattens the array based on the environment
|
|
$this->data = $this->flatten($environment, $config);
|
|
|
|
// Restore environments value
|
|
if ($environments != false)
|
|
{
|
|
$this->data['environments'] = $environments;
|
|
}
|
|
|
|
// Sets the environment if it's not set already
|
|
if (!isset($this->data['environment']))
|
|
{
|
|
$this->data['environment'] = $environment;
|
|
}
|
|
|
|
// Defaults profiler to true if it doesn't match an option exactly
|
|
if (isset($this->data['pickles']['profiler']))
|
|
{
|
|
// If we have an array convert to a string
|
|
if (is_array($this->data['pickles']['profiler']))
|
|
{
|
|
$this->data['pickles']['profiler'] = implode(',', $this->data['pickles']['profiler']);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
$this->data['pickles']['profiler'] = false;
|
|
}
|
|
|
|
// Defaults expected PICKLES options to false
|
|
foreach (array('cache', 'logging', 'minify') as $variable)
|
|
{
|
|
if (!isset($this->data['pickles'][$variable]))
|
|
{
|
|
$this->data['pickles'][$variable] = false;
|
|
}
|
|
}
|
|
|
|
// Creates constants for the security levels
|
|
if (isset($this->data['security']['levels']) && is_array($this->data['security']['levels']))
|
|
{
|
|
foreach ($this->data['security']['levels'] as $value => $name)
|
|
{
|
|
$constant = 'SECURITY_LEVEL_' . strtoupper($name);
|
|
|
|
// Checks if constant is already defined, and throws an error
|
|
if (defined($constant))
|
|
{
|
|
throw new Exception('The constant ' . $constant . ' is already defined');
|
|
}
|
|
else
|
|
{
|
|
define($constant, $value);
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Flatten
|
|
*
|
|
* Flattens the configuration array around the specified environment.
|
|
*
|
|
* @param string $environment selected environment
|
|
* @param array $array configuration error to flatten
|
|
* @return array flattened configuration array
|
|
*/
|
|
private function flatten($environment, $array)
|
|
{
|
|
if (is_array($array))
|
|
{
|
|
foreach ($array as $key => $value)
|
|
{
|
|
if (is_array($value))
|
|
{
|
|
if (isset($value[$environment]))
|
|
{
|
|
$value = $value[$environment];
|
|
}
|
|
else
|
|
{
|
|
$value = $this->flatten($environment, $value);
|
|
}
|
|
}
|
|
|
|
$array[$key] = $value;
|
|
}
|
|
}
|
|
|
|
return $array;
|
|
}
|
|
|
|
/**
|
|
* Get instance of the object
|
|
*
|
|
* Let's the parent class do all the work
|
|
*
|
|
* @static
|
|
* @param string $class name of the class to instantiate
|
|
* @return object self::$instance instance of the Config class
|
|
*/
|
|
public static function getInstance($class = 'Config')
|
|
{
|
|
return parent::getInstance($class);
|
|
}
|
|
|
|
/**
|
|
* Magic Setter Method
|
|
*
|
|
* Prohibits the direct modification of module variables.
|
|
*
|
|
* @param string $name name of the variable to be set
|
|
* @param mixed $value value of the variable to be set
|
|
*/
|
|
public function __set($name, $value)
|
|
{
|
|
throw new Exception('Cannot set config variables directly', E_USER_ERROR);
|
|
}
|
|
|
|
/**
|
|
* Magic Getter Method
|
|
*
|
|
* Attempts to load the config variable. If it's not set, will override
|
|
* the variable with boolean false.
|
|
*
|
|
* @param string $name name of the variable requested
|
|
* @return mixed value of the variable or boolean false
|
|
*/
|
|
public function __get($name)
|
|
{
|
|
if (!isset($this->data[$name]))
|
|
{
|
|
$this->data[$name] = false;
|
|
}
|
|
|
|
return $this->data[$name];
|
|
}
|
|
}
|
|
|
|
?>
|