diff --git a/private/config.php.dist b/private/config.php.dist index 45705ec..e66f8c2 100644 --- a/private/config.php.dist +++ b/private/config.php.dist @@ -10,23 +10,54 @@ */ define('Sihnon_Lib', '../lib/'); +/** + * Sihnon Database Support + * + * Specifies whether or not to include database support in the Framework + * + * @var bool + */ +define('Sihnon_DatabaseSupport', false); + /** * Sihnon Database Configuration * - * Specifies the absolute or relative path to the Sihnon database configuration file. + * Specifies the absolute or relative path to the Sihnon database configuration file, required when Database support is enabled. * This is a standard ini type file, containing the config required to connect to the database. * * @var string */ -define('Sihnon_DBConfig', '../dbconfig.conf'); +define('Sihnon_DBConfig', '../private/dbconfig.conf'); /** - * Sihnon Log Table - * - * Specifies the name of the database table used to store log entries for this application. + * Sihnon Config Plugin + * + * Specifies the plugin to use for configuration value storage. + * Options include: + * - Database (Requires Database Support to be enabled, and the Sihnon_ConfigTable option set) + * - FlatFile (Requires the Sihnon_ConfigFile option set) * * @var string */ -define('Sihnon_Log_Table', 'logs'); +define('Sihnon_ConfigPlugin', 'FlatFile'); + +/** + * Sihnon Config Table + * + * Specifies the name of the database table thats used for storing configuration values + * when the Database Config Plugin is used. + * + * @var string + */ +define('Sihnon_ConfigTable', 'settings'); + +/** + * Sihnon Config File + * + * Specifies the name of the file used to store configuration values when the FlatFile Config Plugin is used + * + * @var string + */ +define('Sihnon_ConfigFile', '../private/settings.txt'); ?> \ No newline at end of file diff --git a/source/lib/Sihnon/Config.class.php b/source/lib/Sihnon/Config.class.php index bea4c86..8b2218c 100644 --- a/source/lib/Sihnon/Config.class.php +++ b/source/lib/Sihnon/Config.class.php @@ -31,25 +31,13 @@ class Sihnon_Config { * @var array(string) */ const TYPE_STRING_LIST = 'array(string)'; - - /** - * Contents of the dbconfig file - * @var string - */ - private $dbconfig; /** - * Database object created for the lifetime of this script - * @var Sihnon_Database + * Backend to be used for this Config object + * @var Sihnon_Config_IPlugin */ - private $database; + private $backend; - /** - * Associative array of connection parameters for the database configuration - * @var array(string=>string) - */ - private $databaseConfig = array(); - /** * Associative array of settings loaded from the database * @var array(string=>array(string=>string)) @@ -59,56 +47,13 @@ class Sihnon_Config { /** * Constructs a new instance of the Config class * - * @param string $dbconfig Database configuration file contents + * @param string $backend Backend to use for storing and retrieving configuration items + * @param mixed $options Parameters to configure the Config backend * @return Sihnon_Config */ - public function __construct($dbconfig) { - $this->dbconfig = $dbconfig; - - $this->parseDatabaseConfig(); - } - - /** - * Parses the contents of the database configuration file so that individual settings can be retrieved. - * - */ - public function parseDatabaseConfig() { - $this->databaseConfig = parse_ini_file($this->dbconfig); - } - - /** - * Returns the value of the named item from the database configuration file - * - * @param string $key Name of the setting to retrieve - */ - public function getDatabase($key) { - if (!isset($this->databaseConfig[$key])) { - throw new Sihnon_Exception_DatabaseConfigMissing($key); - } - - return $this->databaseConfig[$key]; - } - - /** - * Sets the database instance used by this object - * - * @param Sihnon_Database $database Database instance - */ - public function setDatabase(Sihnon_Database $database) { - $this->database = $database; - $this->preload(); - } - - /** - * Loads the entire list of settings from the database - * - */ - private function preload() { - if (!$this->database) { - throw new Sihnon_Exception_NoDatabaseConnection(); - } - - $this->settings = $this->database->selectAssoc('SELECT name,type,value FROM settings', 'name', array('name', 'value', 'type')); + public function __construct($backend, $options) { + $this->backend = Sihnon_Config_PluginFactory::create($backend, $options); + $this->settings = $this->backend->preload(); } /** diff --git a/source/lib/Sihnon/Config/IPlugin.class.php b/source/lib/Sihnon/Config/IPlugin.class.php new file mode 100644 index 0000000..0e9bc20 --- /dev/null +++ b/source/lib/Sihnon/Config/IPlugin.class.php @@ -0,0 +1,29 @@ +mixed) $options Configuration options for the Plugin object + */ + public static function create($options); + + /** + * Loads all the configuration items from the storage backend + * + * @param string $source_filename Filename of the source + * @param bool $scan Request that the source be scanned for content. Defaults to true. + * @param bool $use_cache Request that the cache be used. Defaults to true. + * @return RippingCluster_Source + */ + public function preload(); + + /** + * Saves the value of all configuration items back into the storage backend + */ + public function save(); + +} + +?> \ No newline at end of file diff --git a/source/lib/Sihnon/Config/Plugin/Database.class.php b/source/lib/Sihnon/Config/Plugin/Database.class.php new file mode 100644 index 0000000..d40faf4 --- /dev/null +++ b/source/lib/Sihnon/Config/Plugin/Database.class.php @@ -0,0 +1,33 @@ +database = $options['database']; + $this->table = $options['table']; + } + + public static function create($options) { + return new self($options); + } + + public function preload() { + return $this->database->selectAssoc("SELECT name,type,value FROM {$this->table}", 'name', array('name', 'value', 'type')); + } + + public function save() { + throw new Sihnon_Exception_NotImplemented(); + } + +} + +?> \ No newline at end of file diff --git a/source/lib/Sihnon/Config/Plugin/FlatFile.class.php b/source/lib/Sihnon/Config/Plugin/FlatFile.class.php new file mode 100644 index 0000000..9b90e95 --- /dev/null +++ b/source/lib/Sihnon/Config/Plugin/FlatFile.class.php @@ -0,0 +1,31 @@ +filename = $options['filename']; + } + + public static function create($options) { + return new self($options); + } + + public function preload() { + return parse_ini_file($this->filename, true);; + } + + public function save() { + throw new Sihnon_Exception_NotImplemented(); + } + +} + +?> \ No newline at end of file diff --git a/source/lib/Sihnon/Config/PluginFactory.class.php b/source/lib/Sihnon/Config/PluginFactory.class.php new file mode 100644 index 0000000..315f873 --- /dev/null +++ b/source/lib/Sihnon/Config/PluginFactory.class.php @@ -0,0 +1,27 @@ + \ No newline at end of file diff --git a/source/lib/Sihnon/Database.class.php b/source/lib/Sihnon/Database.class.php index 6582273..952e5c3 100644 --- a/source/lib/Sihnon/Database.class.php +++ b/source/lib/Sihnon/Database.class.php @@ -5,6 +5,12 @@ class Sihnon_Database { private $config; private $dbh; + /** + * Associative array of connection parameters for the database configuration + * @var array(string=>string) + */ + private $database_config; + private $hostname; private $username; private $password; @@ -12,13 +18,14 @@ class Sihnon_Database { private $prepared_statements = array(); - public function __construct(Sihnon_Config $config) { - $this->config = $config; - - $this->hostname = $this->config->getDatabase('hostname'); - $this->username = $this->config->getDatabase('username'); - $this->password = $this->config->getDatabase('password'); - $this->dbname = $this->config->getDatabase('dbname'); + public function __construct($dbconfig) { + $this->database_cconfig = parse_ini_file($dbconfig); + var_dump($this->database_config); + + $this->hostname = $this->getDatabaseConfig('hostname'); + $this->username = $this->getDatabaseConfig('username'); + $this->password = $this->getDatabaseConfig('password'); + $this->dbname = $this->getDatabaseConfig('dbname'); try { $this->dbh = new PDO("mysql:host={$this->hostname};dbname={$this->dbname}", $this->username, $this->password); @@ -31,6 +38,19 @@ class Sihnon_Database { public function __destruct() { $this->dbh = null; } + + /** + * Returns the value of the named item from the database configuration file + * + * @param string $key Name of the setting to retrieve + */ + private function getDatabaseConfig($key) { + if (!isset($this->database_config[$key])) { + throw new Sihnon_Exception_DatabaseConfigMissing($key); + } + + return $this->database_config[$key]; + } public function selectAssoc($sql, $key_col, $value_cols) { $results = array(); diff --git a/source/lib/Sihnon/Exceptions.class.php b/source/lib/Sihnon/Exceptions.class.php index 1b6e318..ff4b7b3 100644 --- a/source/lib/Sihnon/Exceptions.class.php +++ b/source/lib/Sihnon/Exceptions.class.php @@ -2,6 +2,9 @@ class Sihnon_Exception extends Exception {}; +class Sihnon_Exception_NotImplemented extends Sihnon_Exception {}; +class Sihnon_Exception_MissingDefinition extends Sihnon_Exception {}; + class Sihnon_Exception_DatabaseException extends Sihnon_Exception {}; class Sihnon_Exception_DatabaseConfigMissing extends Sihnon_Exception_DatabaseException {}; class Sihnon_Exception_DatabaseConnectFailed extends Sihnon_Exception_DatabaseException {}; diff --git a/source/lib/Sihnon/Log.class.php b/source/lib/Sihnon/Log.class.php index 781dd65..441e44b 100644 --- a/source/lib/Sihnon/Log.class.php +++ b/source/lib/Sihnon/Log.class.php @@ -9,29 +9,22 @@ class Sihnon_Log { private static $hostname = ''; - private $database; - private $config; - private $table; - - public function __construct(Sihnon_Database $database, Sihnon_Config $config, $table) { - $this->database = $database; - $this->config = $config; - $this->table = $table; - + private $backend; + private $progname; + + public function __construct($backend, $options = array(), $progname = '') { + $this->progname = $progname; + + $this->backend = Sihnon_Log_PluginFactory::create($backend, $options); + $this->log(self::LEVEL_INFO, "Logging started"); + } + + public function __destruct() { + $this->log(self::LEVEL_INFO, "Logging shutdown"); } - public function log($severity, $message) { - $this->database->insert("INSERT INTO {$this->table} (level,ctime,pid,hostname,progname,line,message) VALUES(:level, :ctime, :pid, :hostname, :progname, :line, :message)", - array( - array('name' => 'level', 'value' => $severity, 'type' => PDO::PARAM_STR), - array('name' => 'ctime', 'value' => time(), 'type' => PDO::PARAM_INT), - array('name' => 'pid', 'value' => 0, 'type' => PDO::PARAM_INT), - array('name' => 'hostname', 'value' => self::$hostname, 'type' => PDO::PARAM_STR), - array('name' => 'progname', 'value' => 'webui', 'type' => PDO::PARAM_STR), - array('name' => 'line', 'value' => 0, 'type' => PDO::PARAM_INT), - array('name' => 'message', 'value' => $message, 'type' => PDO::PARAM_STR) - ) - ); + public function log($level, $message) { + $this->backend->log($level, time(), 0, self::$hostname, $this->progname, 0, $message); } public function debug($message) { diff --git a/source/lib/Sihnon/Log/IPlugin.class.php b/source/lib/Sihnon/Log/IPlugin.class.php new file mode 100644 index 0000000..b6fec93 --- /dev/null +++ b/source/lib/Sihnon/Log/IPlugin.class.php @@ -0,0 +1,27 @@ +mixed) $options Configuration options for the Plugin object + */ + public static function create($options); + + + /** + * Records a new entry in the storage backend used by this logging plugin + * + * @param string $level Severity of the log entry + * @param int $ctime Time the log entry was created + * @param int $pid ID of the process that created the log entry + * @param string $hostname Hostname of the system that created the log entry + * @param string $progname Name of the application that created the log entry + * @param int $line Line number of the code that created the log entry + * @param string $message Message to be logged + */ + public function log($level, $ctime, $pid, $hostname, $progname, $line, $message); +} + +?> \ No newline at end of file diff --git a/source/lib/Sihnon/Log/Plugin/Database.class.php b/source/lib/Sihnon/Log/Plugin/Database.class.php new file mode 100644 index 0000000..964d3fa --- /dev/null +++ b/source/lib/Sihnon/Log/Plugin/Database.class.php @@ -0,0 +1,49 @@ +database = $options['database']; + $this->table = Sihnon_Main::instance()->config()->get('logging.database.table'); + } + + public static function create($options) { + return new self($options); + } + + /** + * Records a new entry in the storage backend used by this logging plugin + * + * @param string $level Severity of the log entry + * @param int $ctime Time the log entry was created + * @param int $pid ID of the process that created the log entry + * @param string $hostname Hostname of the system that created the log entry + * @param string $progname Name of the application that created the log entry + * @param int $line Line number of the code that created the log entry + * @param string $message Message to be logged + */ + public function log($level, $ctime, $pid, $hostname, $progname, $line, $message) { + $this->database->insert("INSERT INTO {$this->table} (level,ctime,pid,hostname,progname,line,message) VALUES(:level, :ctime, :pid, :hostname, :progname, :line, :message)", + array( + array('name' => 'level', 'value' => $level, 'type' => PDO::PARAM_STR), + array('name' => 'ctime', 'value' => $ctime, 'type' => PDO::PARAM_INT), + array('name' => 'pid', 'value' => $pid, 'type' => PDO::PARAM_INT), + array('name' => 'hostname', 'value' => $hostname, 'type' => PDO::PARAM_STR), + array('name' => 'progname', 'value' => $progname, 'type' => PDO::PARAM_STR), + array('name' => 'line', 'value' => $line, 'type' => PDO::PARAM_INT), + array('name' => 'message', 'value' => $message, 'type' => PDO::PARAM_STR) + ) + ); + } +} + +?> \ No newline at end of file diff --git a/source/lib/Sihnon/Log/Plugin/FlatFile.class.php b/source/lib/Sihnon/Log/Plugin/FlatFile.class.php new file mode 100644 index 0000000..03bb45a --- /dev/null +++ b/source/lib/Sihnon/Log/Plugin/FlatFile.class.php @@ -0,0 +1,44 @@ +filename = Sihnon_Main::instance()->config()->get('logging.flatfile.filename'); + $this->fp = fopen($this->filename, 'a'); + } + + public function __destruct() { + fclose($this->fp); + } + + public static function create($options) { + return new self($options); + } + + /** + * Records a new entry in the storage backend used by this logging plugin + * + * @param string $level Severity of the log entry + * @param int $ctime Time the log entry was created + * @param int $pid ID of the process that created the log entry + * @param string $hostname Hostname of the system that created the log entry + * @param string $progname Name of the application that created the log entry + * @param int $line Line number of the code that created the log entry + * @param string $message Message to be logged + */ + public function log($level, $ctime, $pid, $hostname, $progname, $line, $message) { + $log_entry = implode(',', array($level, $ctime, $pid, $hostname, $progname, $line, $message)) . "\n"; + fwrite($this->fp, $log_entry, strlen($log_entry)); + } +} + +?> \ No newline at end of file diff --git a/source/lib/Sihnon/Log/PluginFactory.class.php b/source/lib/Sihnon/Log/PluginFactory.class.php new file mode 100644 index 0000000..6fd8ba1 --- /dev/null +++ b/source/lib/Sihnon/Log/PluginFactory.class.php @@ -0,0 +1,27 @@ + \ No newline at end of file diff --git a/source/lib/Sihnon/Main.class.php b/source/lib/Sihnon/Main.class.php index 3a98ebe..becbfce 100644 --- a/source/lib/Sihnon/Main.class.php +++ b/source/lib/Sihnon/Main.class.php @@ -1,26 +1,37 @@ config = new Sihnon_Config(Sihnon_DBConfig); - $this->database = new Sihnon_Database($this->config); - $this->config->setDatabase($this->database); + protected $config; + protected $database; + protected $log; + protected $cache; + + protected $base_uri; - $this->log = new Sihnon_Log($this->database, $this->config, Sihnon_Log_Table); - $this->cache = new Sihnon_Cache($this->config); - + protected function __construct() { $this->base_uri = dirname($_SERVER['SCRIPT_NAME']) . '/'; } + + protected function init() { + if (Sihnon_DatabaseSupport) { + $this->database = new Sihnon_Database(Sihnon_DBConfig); + } + + $this->config = new Sihnon_Config(Sihnon_ConfigPlugin, array( + 'database' => $this->database, + 'table' => Sihnon_ConfigTable, + 'filename' => Sihnon_ConfigFile) + ); + + $this->log = new Sihnon_Log($this->config->get('logging.plugin'), array( + 'database' => $this->database) + ); + + $this->cache = new Sihnon_Cache($this->config); + } /** * @@ -29,6 +40,7 @@ class Sihnon_Main { public static function instance() { if (!self::$instance) { self::$instance = new Sihnon_Main(); + self::$instance->init(); } return self::$instance; @@ -111,6 +123,18 @@ class Sihnon_Main { } } + /** + * Throws an exception if the requested name has not been defined. + * + * @param string $name Name of the definition to check for the existence of + * @throws Sihnon_Exception_MissingDefinition + */ + public static function ensureDefined($name) { + if (! defined($name)) { + throw new Sihnon_Exception_MissingDefinition($name); + } + } + public static function mkdir_recursive($directory, $permissions=0777) { $parts = explode('/', $directory); $path = ''; diff --git a/source/lib/Sihnon/PluginFactory.class.php b/source/lib/Sihnon/PluginFactory.class.php index 6f623ef..b1e0102 100644 --- a/source/lib/Sihnon/PluginFactory.class.php +++ b/source/lib/Sihnon/PluginFactory.class.php @@ -4,6 +4,19 @@ abstract class Sihnon_PluginFactory implements Sihnon_IPluginFactory { static private $validPlugins = array(); + /** + * Scan the plugin directory for potential plugins, and load any valid ones found + * + * @param bool $force Rescan the plugin directory even if it has already been scanned before + */ + public static function scan($force = false) { + if ($force || ! isset(self::$validPlugins[get_called_class()])) { + $candidatePlugins = static::findPlugins(static::PLUGIN_DIR); + + static::loadPlugins($candidatePlugins, static::PLUGIN_PREFIX, static::PLUGIN_INTERFACE); + } + } + protected static function ensureScanned() { if (! isset(self::$validPlugins[get_called_class()])) { static::scan();