Reworked config to be an arrayobject

Death to the mix of object variable and array. Also cleaned up the profiler
sanity checks as the variable will always be present now. Profiler is now an
all or nothing action.
This commit is contained in:
Josh Sherman 2014-09-29 21:32:08 -04:00
parent f2f1cbc166
commit 1c974fc9ad
8 changed files with 98 additions and 200 deletions

View file

@ -75,9 +75,9 @@ class Cache extends Object
parent::__construct(); parent::__construct();
// @todo Shouldn't need the isset() but Travis is failing some tests // @todo Shouldn't need the isset() but Travis is failing some tests
if (isset($this->config->pickles['cache']) && $this->config->pickles['cache']) if (isset($this->config['pickles']['cache']) && $this->config['pickles']['cache'])
{ {
$datasources = $this->config->pickles['cache']; $datasources = $this->config['pickles']['cache'];
if (!is_array($datasources)) if (!is_array($datasources))
{ {
@ -88,9 +88,9 @@ class Cache extends Object
foreach ($datasources as $name) foreach ($datasources as $name)
{ {
if (isset($this->config->datasources[$name])) if (isset($this->config['datasources'][$name]))
{ {
$datasource = $this->config->datasources[$name]; $datasource = $this->config['datasources'][$name];
$this->connection->addServer($datasource['hostname'], $datasource['port']); $this->connection->addServer($datasource['hostname'], $datasource['port']);
$this->servers++; $this->servers++;

View file

@ -26,17 +26,10 @@ namespace Pickles;
* custom config files on the fly as well. The core of PICKLES uses the class * 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 * as a Singleton so we're not loading the configuration multiple times per
* page load. * page load.
*
* @usage <code>$config = new Config($filename);</code>
*/ */
class Config extends Object class Config extends \ArrayObject
{ {
/** private static $_instance = false;
* Config data
*
* @var array
*/
public $data = [];
/** /**
* Constructor * Constructor
@ -45,22 +38,20 @@ class Config extends Object
*/ */
public function __construct() public function __construct()
{ {
parent::__construct(); $filename = getcwd() . '/../../pickles.php';
$filename = SITE_PATH . 'config.php';
$environments = false; $environments = false;
$environment = false; $environment = false;
$is_cli = !isset($_SERVER['REQUEST_METHOD']); $cli = PHP_SAPI == 'cli';
// Sanity checks the config file // Only require in case you want to reload the config
if (file_exists($filename) && is_file($filename) && is_readable($filename))
{
require $filename; require $filename;
}
// Checks that we have the config array // Checks that we have the config array
if (isset($config)) if (!isset($config))
{ {
throw new \Exception('Missing $config array.');
}
// Determines the environment // Determines the environment
if (isset($config['environment'])) if (isset($config['environment']))
{ {
@ -73,13 +64,12 @@ class Config extends Object
$environments = $config['environments']; $environments = $config['environments'];
// If we're on the CLI, check an environment was even passed in // If we're on the CLI, check an environment was even passed in
// @todo is checking for argc enough? if ($cli && $_SERVER['argc'] < 2)
if ($is_cli && $_SERVER['argc'] < 2)
{ {
throw new \Exception('You must pass an environment (e.g. php script.php <environment>)'); 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 // Loops through the environments and looks for a match
foreach ($config['environments'] as $name => $hosts) foreach ($config['environments'] as $name => $hosts)
{ {
if (!is_array($hosts)) if (!is_array($hosts))
@ -90,7 +80,7 @@ class Config extends Object
// Tries to determine the environment name // Tries to determine the environment name
foreach ($hosts as $host) foreach ($hosts as $host)
{ {
if ($is_cli) if ($cli)
{ {
// Checks the first argument on the command line // Checks the first argument on the command line
if ($_SERVER['argv'][1] == $name) if ($_SERVER['argv'][1] == $name)
@ -110,7 +100,9 @@ class Config extends Object
break; break;
} }
// Fuzzy match // Fuzzy match
elseif (substr($host,0,1) == '/' && (preg_match($host, $_SERVER['SERVER_NAME'], $matches) > 0 || preg_match($host, $_SERVER['HTTP_HOST'], $matches) > 0)) 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]; $environments[$name] = $matches[0];
$environment = $name; $environment = $name;
@ -121,69 +113,34 @@ class Config extends Object
} }
} }
} }
}
// Flattens the array based on the environment // Flattens the array based on the environment
$this->data = $this->flatten($environment, $config); $config = $this->flatten($environment, $config);
// Restore environments value // Restore environments value
if ($environments != false) if ($environments != false)
{ {
$this->data['environments'] = $environments; $config['environments'] = $environments;
} }
// Sets the environment if it's not set already // Sets the environment if it's not set already
if (!isset($this->data['environment'])) if (!isset($config['environment']))
{ {
$this->data['environment'] = $environment; $config['environment'] = $environment;
} }
// Defaults profiler to true if it doesn't match an option exactly // Defaults expected Pickles options to false
if (isset($this->data['pickles']['profiler'])) $this['pickles'] = [
{ 'cache' => false,
// If we have an array convert to a string 'profiler' => false,
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 // Assigns the config variables to the object
foreach (['cache', 'logging', 'minify'] as $variable) foreach ($config as $variable => $value)
{ {
if (!isset($this->data['pickles'][$variable])) $this[$variable] = $value;
{
$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;
} }
/** /**
@ -229,28 +186,14 @@ class Config extends Object
* @param string $class name of the class to instantiate * @param string $class name of the class to instantiate
* @return object self::$instance instance of the Config class * @return object self::$instance instance of the Config class
*/ */
public static function getInstance($class = 'Config') public static function getInstance()
{ {
return parent::getInstance($class); if (!self::$_instance)
{
self::$_instance = new Config();
} }
/** return self::$_instance;
* 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];
} }
} }

View file

@ -135,13 +135,13 @@ class Database extends Object
// Tries to load a datasource if one wasn't specified // Tries to load a datasource if one wasn't specified
if (!$datasource_name) if (!$datasource_name)
{ {
if (isset($config->pickles['datasource'])) if (isset($config['pickles']['datasource']))
{ {
$datasource_name = $config->pickles['datasource']; $datasource_name = $config['pickles']['datasource'];
} }
elseif (is_array($config->datasources)) elseif (is_array($config['datasources']))
{ {
$datasources = $config->datasources; $datasources = $config['datasources'];
foreach ($datasources as $name => $datasource) foreach ($datasources as $name => $datasource)
{ {
@ -158,12 +158,12 @@ class Database extends Object
{ {
if (!isset(self::$instances['Database'][$datasource_name])) if (!isset(self::$instances['Database'][$datasource_name]))
{ {
if (!isset($config->datasources[$datasource_name])) if (!isset($config['datasources'][$datasource_name]))
{ {
throw new \Exception('The specified datasource is not defined in the config.'); throw new \Exception('The specified datasource is not defined in the config.');
} }
$datasource = $config->datasources[$datasource_name]; $datasource = $config['datasources'][$datasource_name];
if (!isset($datasource['driver'])) if (!isset($datasource['driver']))
{ {
@ -328,13 +328,13 @@ class Database extends Object
$sql .= "\n" . '/* [' . implode('|', $files) . '] */'; $sql .= "\n" . '/* [' . implode('|', $files) . '] */';
// Establishes if we're working on an EXPLAIN // Establishes if we're working on an EXPLAIN
if (Profiler::enabled('explains')) if ($this->config['pickles']['profiler'])
{ {
$explain = preg_match('/^SELECT /i', $sql); $explain = preg_match('/^SELECT /i', $sql);
} }
else else
{ {
$explain = null; $explain = false;
} }
// Executes a standard query // Executes a standard query
@ -367,9 +367,9 @@ class Database extends Object
$duration = $end_time - $start_time; $duration = $end_time - $start_time;
// Logs the information to the profiler // Logs the information to the profiler
if (Profiler::enabled('explains', 'queries')) if ($this->config['pickles']['profiler'])
{ {
Profiler::logQuery($sql, $input_parameters, (isset($explain) ? $explain : false), $duration); Profiler::logQuery($sql, $input_parameters, $explain, $duration);
} }
} }
else else

View file

@ -55,13 +55,6 @@ class Object
*/ */
public $db = null; public $db = null;
/**
* Profiler flag
*
* @var mixed
*/
public $profiler = false;
/** /**
* Constructor * Constructor
* *
@ -96,14 +89,8 @@ class Object
} }
} }
// Assigns the profiler flag
$this->profiler = (isset($this->config->pickles['profiler']) && $this->config->pickles['profiler'] != '' ? $this->config->pickles['profiler'] : false);
// Optionally logs the constructor to the profiler // Optionally logs the constructor to the profiler
if ($this->profiler === true if ($this->config['pickles']['profiler'])
|| ((is_array($this->profiler)
&& in_array('objects', $this->profiler))
|| stripos($this->profiler, 'objects') !== false))
{ {
Profiler::log($this, '__construct'); Profiler::log($this, '__construct');
} }
@ -143,10 +130,7 @@ class Object
public function __destruct() public function __destruct()
{ {
// Optionally logs the destructor to the profiler // Optionally logs the destructor to the profiler
if ($this->profiler === true if ($this->config['pickles']['profiler'])
|| ((is_array($this->profiler)
&& in_array('objects', $this->profiler))
|| stripos($this->profiler, 'objects') !== false))
{ {
Profiler::log($this, '__destruct'); Profiler::log($this, '__destruct');
} }

View file

@ -80,7 +80,7 @@ class Profiler
public static function enabled(/* polymorphic */) public static function enabled(/* polymorphic */)
{ {
$config = Config::getInstance(); $config = Config::getInstance();
$config = isset($config->pickles['profiler']) ? $config->pickles['profiler'] : false; $config = $config['pickles']['profiler'];
// Checks if we're set to boolean true // Checks if we're set to boolean true
if ($config === true) if ($config === true)

View file

@ -98,18 +98,18 @@ class Resource extends Object
if ($this->auth === true if ($this->auth === true
|| (isset($this->auth[$method]) && $this->auth[$method])) || (isset($this->auth[$method]) && $this->auth[$method]))
{ {
if (!$this->config->pickles['auth']) if (!$this->config['pickles']['auth'])
{ {
throw new \Exception('Authentication is not configured properly.', 401); throw new \Exception('Authentication is not configured properly.', 401);
} }
/* /*
// This class should be in the classes directory of the service // This class should be in the classes directory of the service
$auth = '\\' . $this->config->pickles['namespace'] . '\\Auth'; $auth = '\\' . $this->config['pickles']['namespace'] . '\\Auth';
var_dump($auth); var_dump($auth);
$auth = new $auth(); $auth = new $auth();
switch ($this->config->pickles['auth']) switch ($this->config['pickles']['auth'])
{ {
case 'basic': case 'basic':
$auth->basic(); $auth->basic();
@ -327,11 +327,8 @@ class Resource extends Object
else else
{ {
/* /*
// Gets the profiler status
$profiler = $this->config['pickles']['profiler'];
// Starts a timer before the resource is executed // Starts a timer before the resource is executed
if ($profiler) if ($this->config['pickles']['profiler'])
{ {
Profiler::timer('resource ' . $method); Profiler::timer('resource ' . $method);
} }
@ -341,7 +338,7 @@ class Resource extends Object
/* /*
// Stops the resource timer // Stops the resource timer
if ($profiler) if ($this->config['pickles']['profiler'])
{ {
Profiler::timer('resource ' . $method); Profiler::timer('resource ' . $method);
} }

View file

@ -63,7 +63,7 @@ class Router extends Object
} }
// Creates our class name // Creates our class name
array_unshift($nouns, '', $this->config->pickles['namespace'], 'Resources', $version); array_unshift($nouns, '', $this->config['pickles']['namespace'], 'Resources', $version);
$class = implode('\\', $nouns); $class = implode('\\', $nouns);
// Strips preceding slashs when there is no namespace // Strips preceding slashs when there is no namespace

View file

@ -21,18 +21,6 @@
* @usage <code>require_once 'pickles.php';</code> * @usage <code>require_once 'pickles.php';</code>
*/ */
// {{{ PICKLES Constants
// @todo Finish reworking constants to be part of the Config object
if (!defined('SITE_PATH'))
{
// Establishes our site paths, sanity check is to allow vfsStream in our tests
define('SITE_PATH', getcwd() . '/../');
}
// }}}
// {{{ Defaults some important configuration options
// Turns on error before the config is loaded to help catch parse errors // Turns on error before the config is loaded to help catch parse errors
ini_set('display_errors', true); ini_set('display_errors', true);
error_reporting(-1); error_reporting(-1);
@ -43,29 +31,15 @@ if (ini_get('date.timezone') == '')
ini_set('date.timezone', 'Etc/UTC'); ini_set('date.timezone', 'Etc/UTC');
} }
// Sets the session variables
ini_set('session.cache_expire', 86400);
ini_set('session.entropy_file', '/dev/urandom');
ini_set('session.entropy_length', 512);
ini_set('session.gc_maxlifetime', 86400);
ini_set('session.gc_probability', 1);
ini_set('session.gc_divisor', 1000);
ini_set('session.hash_function', 1);
// }}}
// {{{ Loads the configuration file and sets any configuration options
// Loads the base config // Loads the base config
$config = Pickles\Config::getInstance(); $config = Pickles\Config::getInstance();
// Configures any available PHP configuration options // Configures any available PHP configuration options
if (is_array($config->php) && count($config->php)) if (isset($config['php']) && is_array($config['php']))
{ {
foreach ($config->php as $variable => $value) foreach ($config['php'] as $variable => $value)
{ {
ini_set($variable, $value); ini_set($variable, $value);
} }
} }
// }}}