Updates framework to support automated framework subclasses
All framework classes have been renamed to use the SihnonFramework_ prefix. The class autoloader now looks for subclasses of the framework classes in the Sihnon_Lib directory, and automatically creates them if they don't exist. The autoloader correctly creates interfaces and abstract classes as needed, by using reflection to check the type of the parent class. All references to classes within the framework now use the Sihnon_ prefix. The PluginFactory supports multiple scan directories, and will search both the framework and subclass class tree to find candidate plugins.
This commit is contained in:
17
source/lib/SihnonFramework/BackgroundTask.class.php
Normal file
17
source/lib/SihnonFramework/BackgroundTask.class.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
class SihnonFramework_BackgroundTask {
|
||||
|
||||
protected function __construct() {
|
||||
|
||||
}
|
||||
|
||||
public static function run($command) {
|
||||
$pipes = array();
|
||||
$pid = proc_open($command . ' &', array(), $pipes);
|
||||
proc_close($pid);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
?>
|
||||
62
source/lib/SihnonFramework/Cache.class.php
Normal file
62
source/lib/SihnonFramework/Cache.class.php
Normal file
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
class SihnonFramework_Cache {
|
||||
|
||||
protected $config;
|
||||
protected $cache_dir;
|
||||
|
||||
public function __construct(Sihnon_Config $config) {
|
||||
$this->config = $config;
|
||||
$this->cache_dir = $config->get('cache.base_dir');
|
||||
|
||||
if (is_dir($this->cache_dir)) {
|
||||
if ( ! is_writeable($this->cache_dir)) {
|
||||
throw new Sihnon_Exception_InvalidCacheDir();
|
||||
}
|
||||
} else {
|
||||
if ( ! Sihnon_Main::mkdir_recursive($this->cache_dir)) {
|
||||
throw new Sihnon_Exception_InvalidCacheDir();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function cacheFilename($source_filename) {
|
||||
return $this->cache_dir . sha1($source_filename);
|
||||
}
|
||||
|
||||
public function exists($source_filename, $ttl = 3600) {
|
||||
$cache_filename = $this->cacheFilename($source_filename);
|
||||
|
||||
// Check to see if the file is cached
|
||||
if (!file_exists($cache_filename)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check to see if the cache has expired
|
||||
if (filemtime($cache_filename) + $ttl < time()) {
|
||||
// Delete the cached item
|
||||
unlink($cache_filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function store($source_filename, $content) {
|
||||
$cache_filename = $this->cacheFilename($source_filename);
|
||||
return file_put_contents($cache_filename, $content);
|
||||
}
|
||||
|
||||
public function fetch($source_filename, $ttl = 3600) {
|
||||
$cache_filename = $this->cacheFilename($source_filename);
|
||||
|
||||
if (!$this->exists($source_filename)) {
|
||||
throw new Sihnon_Exception_CacheObjectNotFound($source_filename);
|
||||
}
|
||||
|
||||
return file_get_contents($cache_filename);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
?>
|
||||
90
source/lib/SihnonFramework/Config.class.php
Normal file
90
source/lib/SihnonFramework/Config.class.php
Normal file
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
class SihnonFramework_Config {
|
||||
|
||||
/**
|
||||
* Boolean value type
|
||||
* @var bool
|
||||
*/
|
||||
const TYPE_BOOL = 'bool';
|
||||
|
||||
/**
|
||||
* Integer value type
|
||||
* @var int
|
||||
*/
|
||||
const TYPE_INT = 'int';
|
||||
|
||||
/**
|
||||
* Float value type
|
||||
* @var float
|
||||
*/
|
||||
const TYPE_FLOAT = 'float';
|
||||
|
||||
/**
|
||||
* String value type
|
||||
* @var string
|
||||
*/
|
||||
const TYPE_STRING = 'string';
|
||||
|
||||
/**
|
||||
* String List value type; list of newline separated strings
|
||||
* @var array(string)
|
||||
*/
|
||||
const TYPE_STRING_LIST = 'array(string)';
|
||||
|
||||
/**
|
||||
* Backend to be used for this Config object
|
||||
* @var Sihnon_Config_IPlugin
|
||||
*/
|
||||
private $backend;
|
||||
|
||||
/**
|
||||
* Associative array of settings loaded from the database
|
||||
* @var array(string=>array(string=>string))
|
||||
*/
|
||||
private $settings = array();
|
||||
|
||||
/**
|
||||
* Constructs a new instance of the Config class
|
||||
*
|
||||
* @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($backend, $options) {
|
||||
$this->backend = Sihnon_Config_PluginFactory::create($backend, $options);
|
||||
$this->settings = $this->backend->preload();
|
||||
}
|
||||
|
||||
/**
|
||||
* Identifies whether the named setting exists
|
||||
*
|
||||
* @param string $key Name of the setting
|
||||
* @return bool
|
||||
*/
|
||||
public function exists($key) {
|
||||
return isset($this->settings[$key]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the value of the named setting
|
||||
*
|
||||
* @param string $key Name of the setting
|
||||
*/
|
||||
public function get($key) {
|
||||
if (!isset($this->settings[$key])) {
|
||||
throw new Sihnon_Exception_UnknownSetting($key);
|
||||
}
|
||||
|
||||
switch ($this->settings[$key]['type']) {
|
||||
case self::TYPE_STRING_LIST:
|
||||
return array_map('trim', explode("\n", $this->settings[$key]['value']));
|
||||
|
||||
default:
|
||||
return $this->settings[$key]['value'];
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
?>
|
||||
29
source/lib/SihnonFramework/Config/IPlugin.class.php
Normal file
29
source/lib/SihnonFramework/Config/IPlugin.class.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
interface SihnonFramework_Config_IPlugin extends Sihnon_IPlugin {
|
||||
|
||||
/**
|
||||
* Returns a new instance of the Plugin class
|
||||
*
|
||||
* @param array(string=>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();
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
33
source/lib/SihnonFramework/Config/Plugin/Database.class.php
Normal file
33
source/lib/SihnonFramework/Config/Plugin/Database.class.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
class SihnonFramework_Config_Plugin_Database extends Sihnon_PluginBase implements Sihnon_Config_IPlugin {
|
||||
|
||||
/**
|
||||
* Name of this plugin
|
||||
* @var string
|
||||
*/
|
||||
const PLUGIN_NAME = "Database";
|
||||
|
||||
private $database;
|
||||
private $table;
|
||||
|
||||
protected function __construct($options) {
|
||||
$this->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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
31
source/lib/SihnonFramework/Config/Plugin/FlatFile.class.php
Normal file
31
source/lib/SihnonFramework/Config/Plugin/FlatFile.class.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
class SihnonFramework_Config_Plugin_FlatFile extends Sihnon_PluginBase implements Sihnon_Config_IPlugin {
|
||||
|
||||
/**
|
||||
* Name of this plugin
|
||||
* @var string
|
||||
*/
|
||||
const PLUGIN_NAME = "FlatFile";
|
||||
|
||||
protected $filename;
|
||||
|
||||
protected function __construct($options) {
|
||||
$this->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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
30
source/lib/SihnonFramework/Config/PluginFactory.class.php
Normal file
30
source/lib/SihnonFramework/Config/PluginFactory.class.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
class SihnonFramework_Config_PluginFactory extends Sihnon_PluginFactory {
|
||||
|
||||
protected static $plugin_prefix = 'Sihnon_Config_Plugin_';
|
||||
protected static $plugin_interface = 'Sihnon_Config_IPlugin';
|
||||
protected static $plugin_dir = array(
|
||||
SihnonFramework_Lib => 'SihnonFramework/Config/Plugin',
|
||||
Sihnon_Lib => 'Sihnon/Config/Plugin/',
|
||||
);
|
||||
|
||||
public static function init() {
|
||||
|
||||
}
|
||||
|
||||
public static function create($plugin, $options) {
|
||||
self::ensureScanned();
|
||||
|
||||
if (! self::isValidPlugin($plugin)) {
|
||||
throw new Sihnon_Exception_InvalidPluginName($plugin);
|
||||
}
|
||||
|
||||
$classname = self::classname($plugin);
|
||||
|
||||
return call_user_func(array($classname, 'create'), $options);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
161
source/lib/SihnonFramework/Database.class.php
Normal file
161
source/lib/SihnonFramework/Database.class.php
Normal file
@@ -0,0 +1,161 @@
|
||||
<?php
|
||||
|
||||
class SihnonFramework_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;
|
||||
private $dbname;
|
||||
|
||||
private $prepared_statements = array();
|
||||
|
||||
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);
|
||||
} catch (PDOException $e) {
|
||||
throw new Sihnon_Exception_DatabaseConnectFailed($e->getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
foreach ($this->dbh->query($sql) as $row) {
|
||||
if (is_array($value_cols)) {
|
||||
$values = array();
|
||||
foreach ($value_cols as $value_col) {
|
||||
$values[$value_col] = $row[$value_col];
|
||||
}
|
||||
|
||||
$results[$row[$key_col]] = $values;
|
||||
} else {
|
||||
$results[$row[$key_col]] = $row[$value_col];
|
||||
}
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
public function selectList($sql, $bind_params = null) {
|
||||
if ($bind_params) {
|
||||
$stmt = $this->dbh->prepare($sql);
|
||||
|
||||
foreach ($bind_params as $param) {
|
||||
$stmt->bindValue(':'.$param['name'], $param['value'], $param['type']);
|
||||
}
|
||||
|
||||
$result = $stmt->execute();
|
||||
if (!$result) {
|
||||
list($dummy, $code, $message) = $stmt->errorInfo();
|
||||
throw new Sihnon_Exception_DatabaseQueryFailed($message, $code);
|
||||
}
|
||||
|
||||
return $stmt->fetchAll();
|
||||
|
||||
} else {
|
||||
$results = array();
|
||||
|
||||
$result = $this->dbh->query($sql);
|
||||
foreach ($result as $row) {
|
||||
$results[] = $row;
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
}
|
||||
|
||||
public function selectOne($sql, $bind_params = null) {
|
||||
$rows = $this->selectList($sql, $bind_params);
|
||||
if (count($rows) != 1) {
|
||||
throw new Sihnon_Exception_ResultCountMismatch(count($rows));
|
||||
}
|
||||
|
||||
return $rows[0];
|
||||
}
|
||||
|
||||
public function insert($sql, $bind_params = null) {
|
||||
$stmt = $this->dbh->prepare($sql);
|
||||
|
||||
if ($bind_params) {
|
||||
foreach ($bind_params as $param) {
|
||||
if (isset($param['type'])) {
|
||||
$stmt->bindValue(':'.$param['name'], $param['value'], $param['type']);
|
||||
} else {
|
||||
$stmt->bindValue(':'.$param['name'], $param['value']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$result = $stmt->execute();
|
||||
if (!$result) {
|
||||
list($code, $dummy, $message) = $stmt->errorInfo();
|
||||
throw new Sihnon_Exception_DatabaseQueryFailed($message, $code);
|
||||
}
|
||||
}
|
||||
|
||||
public function update($sql, $bind_params = null) {
|
||||
$stmt = $this->dbh->prepare($sql);
|
||||
|
||||
if ($bind_params) {
|
||||
foreach ($bind_params as $param) {
|
||||
if (isset($param['type'])) {
|
||||
$stmt->bindValue(':'.$param['name'], $param['value'], $param['type']);
|
||||
} else {
|
||||
$stmt->bindValue(':'.$param['name'], $param['value']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$result = $stmt->execute();
|
||||
if (!$result) {
|
||||
list($code, $dummy, $message) = $stmt->errorInfo();
|
||||
throw new Sihnon_Exception_DatabaseQueryFailed($message, $code);
|
||||
}
|
||||
}
|
||||
|
||||
public function errorInfo() {
|
||||
return $this->dbh->errorInfo();
|
||||
}
|
||||
|
||||
public function lastInsertId() {
|
||||
return $this->dbh->lastInsertId();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
24
source/lib/SihnonFramework/Exceptions.class.php
Normal file
24
source/lib/SihnonFramework/Exceptions.class.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
class SihnonFramework_Exception extends Exception {};
|
||||
|
||||
class SihnonFramework_Exception_NotImplemented extends Sihnon_Exception {};
|
||||
class SihnonFramework_Exception_MissingDefinition extends Sihnon_Exception {};
|
||||
|
||||
class SihnonFramework_Exception_DatabaseException extends Sihnon_Exception {};
|
||||
class SihnonFramework_Exception_DatabaseConfigMissing extends Sihnon_Exception_DatabaseException {};
|
||||
class SihnonFramework_Exception_DatabaseConnectFailed extends Sihnon_Exception_DatabaseException {};
|
||||
class SihnonFramework_Exception_NoDatabaseConnection extends Sihnon_Exception_DatabaseException {};
|
||||
class SihnonFramework_Exception_DatabaseQueryFailed extends Sihnon_Exception_DatabaseException {};
|
||||
class SihnonFramework_Exception_ResultCountMismatch extends Sihnon_Exception_DatabaseException {};
|
||||
|
||||
class SihnonFramework_Exception_ConfigException extends Sihnon_Exception {};
|
||||
class SihnonFramework_Exception_UnknownSetting extends Sihnon_Exception_ConfigException {};
|
||||
|
||||
class SihnonFramework_Exception_CacheException extends Sihnon_Exception {};
|
||||
class SihnonFramework_Exception_InvalidCacheDir extends Sihnon_Exception_CacheException {};
|
||||
class SihnonFramework_Exception_CacheObjectNotFound extends Sihnon_Exception_CacheException {};
|
||||
|
||||
class SihnonFramework_Exception_InvalidPluginName extends Sihnon_Exception {};
|
||||
|
||||
?>
|
||||
113
source/lib/SihnonFramework/ForegroundTask.class.php
Normal file
113
source/lib/SihnonFramework/ForegroundTask.class.php
Normal file
@@ -0,0 +1,113 @@
|
||||
<?php
|
||||
|
||||
class SihnonFramework_ForegroundTask {
|
||||
|
||||
const PIPE_STDIN = 0;
|
||||
const PIPE_STDOUT = 1;
|
||||
const PIPE_STDERR = 2;
|
||||
|
||||
private function __construct() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Code largely taken from user submitted comment on http://php.sihnon.net/manual/en/function.proc-open.php
|
||||
* @param unknown_type $command
|
||||
* @param unknown_type $cwd
|
||||
* @param unknown_type $env
|
||||
* @param unknown_type $stdin
|
||||
* @param unknown_type $callback_stdout
|
||||
* @param unknown_type $callback_stderr
|
||||
*/
|
||||
public static function execute($command, $cwd = null, $env = null, $stdin = null, $callback_stdout = null, $callback_stderr = null, $identifier = null) {
|
||||
$txOff = 0;
|
||||
$txLen = strlen($stdin);
|
||||
$stdout = '';
|
||||
$stdoutDone = FALSE;
|
||||
$stderr = '';
|
||||
$stderrDone = FALSE;
|
||||
|
||||
$descriptors = array(
|
||||
self::PIPE_STDIN => array('pipe', 'r'),
|
||||
self::PIPE_STDOUT => array('pipe', 'w'),
|
||||
self::PIPE_STDERR => array('pipe', 'w'),
|
||||
);
|
||||
|
||||
$pipes = array();
|
||||
$process = proc_open($command, $descriptors, $pipes);
|
||||
|
||||
stream_set_blocking($pipes[self::PIPE_STDIN], 0); // Make stdin/stdout/stderr non-blocking
|
||||
stream_set_blocking($pipes[self::PIPE_STDOUT], 0);
|
||||
stream_set_blocking($pipes[self::PIPE_STDERR], 0);
|
||||
|
||||
if ($txLen == 0) {
|
||||
fclose($pipes[0]);
|
||||
}
|
||||
|
||||
while (true) {
|
||||
$rx = array(); // The program's stdout/stderr
|
||||
if (!$stdoutDone) {
|
||||
$rx[] = $pipes[self::PIPE_STDOUT];
|
||||
}
|
||||
if (!$stderrDone) {
|
||||
$rx[] = $pipes[self::PIPE_STDERR];
|
||||
}
|
||||
|
||||
$tx = array(); // The program's stdin
|
||||
if ($txOff < $txLen) {
|
||||
$tx[] = $pipes[self::PIPE_STDIN];
|
||||
}
|
||||
|
||||
$ex = array();
|
||||
|
||||
stream_select($rx, $tx, $ex, null, null); // Block til r/w possible
|
||||
if (!empty($tx)) {
|
||||
$txRet = fwrite($pipes[self::PIPE_STDIN], substr($stdin, $txOff, 8192));
|
||||
if ($txRet !== false) {
|
||||
$txOff += $txRet;
|
||||
}
|
||||
if ($txOff >= $txLen) {
|
||||
fclose($pipes[self::PIPE_STDIN]);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($rx as $r) {
|
||||
if ($r == $pipes[self::PIPE_STDOUT]) {
|
||||
$chunk = fread($pipes[self::PIPE_STDOUT], 8192);
|
||||
if (feof($pipes[self::PIPE_STDOUT])) {
|
||||
fclose($pipes[self::PIPE_STDOUT]); $stdoutDone = true;
|
||||
}
|
||||
|
||||
if ($callback_stdout) {
|
||||
call_user_func($callback_stdout, $identifier, $chunk);
|
||||
} else {
|
||||
$stdout .= $chunk;
|
||||
}
|
||||
|
||||
} else if ($r == $pipes[self::PIPE_STDERR]) {
|
||||
$chunk = fread($pipes[self::PIPE_STDERR], 8192);
|
||||
if (feof($pipes[self::PIPE_STDERR])) {
|
||||
fclose($pipes[self::PIPE_STDERR]); $stderrDone = true;
|
||||
}
|
||||
|
||||
if ($callback_stderr) {
|
||||
call_user_func($callback_stderr, $identifier, $chunk);
|
||||
} else {
|
||||
$stderr .= $chunk;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_resource($process))
|
||||
break;
|
||||
|
||||
if ($txOff >= $txLen && $stdoutDone && $stderrDone)
|
||||
break;
|
||||
}
|
||||
|
||||
return array(proc_close($process), $stdout, $stderr);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
11
source/lib/SihnonFramework/IPlugin.class.php
Normal file
11
source/lib/SihnonFramework/IPlugin.class.php
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
interface SihnonFramework_IPlugin {
|
||||
|
||||
public static function init();
|
||||
|
||||
public static function name();
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
9
source/lib/SihnonFramework/IPluginFactory.class.php
Normal file
9
source/lib/SihnonFramework/IPluginFactory.class.php
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
interface SihnonFramework_IPluginFactory {
|
||||
|
||||
public static function init();
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
54
source/lib/SihnonFramework/Log.class.php
Normal file
54
source/lib/SihnonFramework/Log.class.php
Normal file
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
class SihnonFramework_Log {
|
||||
|
||||
const LEVEL_DEBUG = 'DEBUG';
|
||||
const LEVEL_INFO = 'INFO';
|
||||
const LEVEL_WARNING = 'WARNING';
|
||||
const LEVEL_ERROR = 'ERROR';
|
||||
|
||||
private static $hostname = '';
|
||||
|
||||
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($level, $message) {
|
||||
$this->backend->log($level, time(), 0, self::$hostname, $this->progname, 0, $message);
|
||||
}
|
||||
|
||||
public function debug($message) {
|
||||
return $this->log(self::LEVEL_DEBUG, $message);
|
||||
}
|
||||
|
||||
public function info($message) {
|
||||
return $this->log(self::LEVEL_INFO, $message);
|
||||
}
|
||||
|
||||
public function warning($message) {
|
||||
return $this->log(self::LEVEL_WARNING, $message);
|
||||
}
|
||||
|
||||
public function error($message) {
|
||||
return $this->log(self::LEVEL_ERROR, $message);
|
||||
}
|
||||
|
||||
public static function initialise() {
|
||||
self::$hostname = trim(`hostname`);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
SihnonFramework_Log::initialise();
|
||||
|
||||
?>
|
||||
27
source/lib/SihnonFramework/Log/IPlugin.class.php
Normal file
27
source/lib/SihnonFramework/Log/IPlugin.class.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
interface SihnonFramework_Log_IPlugin extends Sihnon_IPlugin {
|
||||
|
||||
/**
|
||||
* Returns a new instance of the Plugin class
|
||||
*
|
||||
* @param array(string=>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);
|
||||
}
|
||||
|
||||
?>
|
||||
49
source/lib/SihnonFramework/Log/Plugin/Database.class.php
Normal file
49
source/lib/SihnonFramework/Log/Plugin/Database.class.php
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
class SihnonFramework_Log_Plugin_Database extends Sihnon_PluginBase implements Sihnon_Log_IPlugin {
|
||||
|
||||
/**
|
||||
* Name of this plugin
|
||||
* @var string
|
||||
*/
|
||||
const PLUGIN_NAME = "Database";
|
||||
|
||||
private $database;
|
||||
private $table;
|
||||
|
||||
protected function __construct($options) {
|
||||
$this->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)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
44
source/lib/SihnonFramework/Log/Plugin/FlatFile.class.php
Normal file
44
source/lib/SihnonFramework/Log/Plugin/FlatFile.class.php
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
class SihnonFramework_Log_Plugin_FlatFile extends Sihnon_PluginBase implements Sihnon_Log_IPlugin {
|
||||
|
||||
/**
|
||||
* Name of this plugin
|
||||
* @var string
|
||||
*/
|
||||
const PLUGIN_NAME = "FlatFile";
|
||||
|
||||
protected $filename;
|
||||
protected $fp;
|
||||
|
||||
protected function __construct($options) {
|
||||
$this->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));
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
30
source/lib/SihnonFramework/Log/PluginFactory.class.php
Normal file
30
source/lib/SihnonFramework/Log/PluginFactory.class.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
class SihnonFramework_Log_PluginFactory extends Sihnon_PluginFactory {
|
||||
|
||||
protected static $plugin_prefix = 'Sihnon_Log_Plugin_';
|
||||
protected static $plugin_interface = 'Sihnon_Log_IPlugin';
|
||||
protected static $plugin_dir = array(
|
||||
SihnonFramework_Lib => 'SihnonFramework/Log/Plugin/',
|
||||
Sihnon_Lib => 'Sihnon/Log/Plugin/',
|
||||
);
|
||||
|
||||
public static function init() {
|
||||
|
||||
}
|
||||
|
||||
public static function create($plugin, $options) {
|
||||
self::ensureScanned();
|
||||
|
||||
if (! self::isValidPlugin($plugin)) {
|
||||
throw new Sihnon_Exception_InvalidPluginName($plugin);
|
||||
}
|
||||
|
||||
$classname = self::classname($plugin);
|
||||
|
||||
return call_user_func(array($classname, 'create'), $options);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
97
source/lib/SihnonFramework/LogEntry.class.php
Normal file
97
source/lib/SihnonFramework/LogEntry.class.php
Normal file
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
|
||||
abstract class SihnonFramework_LogEntry {
|
||||
|
||||
protected static $table_name = "";
|
||||
|
||||
protected $id;
|
||||
protected $level;
|
||||
protected $ctime;
|
||||
protected $pid;
|
||||
protected $hostname;
|
||||
protected $progname;
|
||||
protected $line;
|
||||
protected $message;
|
||||
|
||||
protected function __construct($id, $level, $ctime, $pid, $hostname, $progname, $line, $message) {
|
||||
$this->id = $id;
|
||||
$this->level = $level;
|
||||
$this->ctime = $ctime;
|
||||
$this->pid = $pid;
|
||||
$this->hostname = $hostname;
|
||||
$this->progname = $progname;
|
||||
$this->line = $line;
|
||||
$this->message = $message;
|
||||
}
|
||||
|
||||
public static function fromDatabaseRow($row) {
|
||||
return new Sihnon_ClientLogEntry(
|
||||
$row['id'],
|
||||
$row['level'],
|
||||
$row['ctime'],
|
||||
$row['pid'],
|
||||
$row['hostname'],
|
||||
$row['progname'],
|
||||
$row['line'],
|
||||
$row['message']
|
||||
);
|
||||
}
|
||||
|
||||
public static function fromId($id) {
|
||||
$database = Sihnon_Main::instance()->database();
|
||||
return Sihnon_ClientLogEntry::fromDatabaseRow(
|
||||
$database->selectOne('SELECT * FROM '.self::$table_name.' WHERE id=:id', array(
|
||||
array('name' => 'id', 'value' => $id, 'type' => PDO::PARAM_INT)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public static function recent($limit = 100) {
|
||||
$entries = array();
|
||||
|
||||
$database = Sihnon_Main::instance()->database();
|
||||
foreach ($database->selectList('SELECT * FROM '.self::$table_name.' ORDER BY ctime DESC LIMIT :limit', array(
|
||||
array('name' => 'limit', 'value' => $limit, 'type' => PDO::PARAM_INT)
|
||||
)) as $row) {
|
||||
$entries[] = self::fromDatabaseRow($row);
|
||||
}
|
||||
|
||||
return $entries;
|
||||
}
|
||||
|
||||
public function id() {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function level() {
|
||||
return $this->level;
|
||||
}
|
||||
|
||||
public function ctime() {
|
||||
return $this->ctime;
|
||||
}
|
||||
|
||||
public function pid() {
|
||||
return $this->pid;
|
||||
}
|
||||
|
||||
public function hostname() {
|
||||
return $this->hostname;
|
||||
}
|
||||
|
||||
public function progname() {
|
||||
return $this->progname;
|
||||
}
|
||||
|
||||
public function line() {
|
||||
return $this->line;
|
||||
}
|
||||
|
||||
public function message() {
|
||||
return $this->message;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
?>
|
||||
235
source/lib/SihnonFramework/Main.class.php
Normal file
235
source/lib/SihnonFramework/Main.class.php
Normal file
@@ -0,0 +1,235 @@
|
||||
<?php
|
||||
|
||||
class SihnonFramework_Main {
|
||||
|
||||
protected static $instance;
|
||||
|
||||
protected $config;
|
||||
protected $database;
|
||||
protected $log;
|
||||
protected $cache;
|
||||
|
||||
protected $base_uri;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return SihnonFramework_Main
|
||||
*/
|
||||
public static function instance() {
|
||||
if (!self::$instance) {
|
||||
self::$instance = new Sihnon_Main();
|
||||
self::$instance->init();
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return SihnonFramework_Config
|
||||
*/
|
||||
public function config() {
|
||||
return $this->config;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return SihnonFramework_Database
|
||||
*/
|
||||
public function database() {
|
||||
return $this->database;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return SihnonFramework_Log
|
||||
*/
|
||||
public function log() {
|
||||
return $this->log;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return SihnonFramework_Cache
|
||||
*/
|
||||
public function cache() {
|
||||
return $this->cache;
|
||||
}
|
||||
|
||||
public function baseUri() {
|
||||
return $this->base_uri;
|
||||
}
|
||||
|
||||
public function absoluteUrl($relative_url) {
|
||||
$secure = isset($_SERVER['secure']);
|
||||
$port = $_SERVER['SERVER_PORT'];
|
||||
return 'http' . ($secure ? 's' : '') . '://'
|
||||
. $_SERVER['HTTP_HOST'] . (($port == 80 || ($secure && $port == 443)) ? '' : ':' . $port)
|
||||
. '/' . $this->base_uri . $relative_url;
|
||||
}
|
||||
|
||||
public static function initialise() {
|
||||
spl_autoload_register(array('SihnonFramework_Main','autoload'));
|
||||
}
|
||||
|
||||
public static function autoload($classname) {
|
||||
// Ensure the classname contains only valid class name characters
|
||||
if (!preg_match('/^[A-Z][a-zA-Z0-9_]*$/', $classname)) {
|
||||
throw new Exception('Illegal characters in classname');
|
||||
}
|
||||
|
||||
// Ensure the class to load begins with our prefix
|
||||
if (preg_match('/^SihnonFramework_/', $classname)) {
|
||||
// Special case: all related exceptions are grouped into a single file
|
||||
if (preg_match('/^(Sihnon(?:Framework)?_(?:.*_))Exception/', $classname, $matches = array())) {
|
||||
require_once(Sihnon_Lib . preg_replace('/_/', '/', $matches[1]) . 'Exceptions.class.php');
|
||||
return;
|
||||
}
|
||||
|
||||
// Replace any underscores with directory separators
|
||||
$filename = SihnonFramework_Lib . preg_replace('/_/', '/', $classname) . '.class.php';
|
||||
|
||||
// If this file exists, load it
|
||||
if (file_exists($filename)) {
|
||||
require_once $filename;
|
||||
return;
|
||||
}
|
||||
} elseif (preg_match('/^Sihnon_/', $classname)) {
|
||||
// Sihnon_ classes subclass the SihnonFramework_ classes.
|
||||
// If a subclass doesn't exist, create it on the fly
|
||||
|
||||
// Special case: all related exceptions are grouped into a single file
|
||||
if (preg_match('/^(Sihnon(?:Framework)?_(?:.*_))Exception/', $classname, $matches = array())) {
|
||||
require_once(Sihnon_Lib . preg_replace('/_/', '/', $matches[1]) . 'Exceptions.class.php');
|
||||
return;
|
||||
}
|
||||
|
||||
// Replace any underscores with directory separators
|
||||
$filename = Sihnon_Lib . preg_replace('/_/', '/', $classname) . '.class.php';
|
||||
|
||||
// If this file exists, load it
|
||||
if (file_exists($filename)) {
|
||||
require_once $filename;
|
||||
return;
|
||||
} else {
|
||||
// Create this class to extend the Framework parent
|
||||
$parent_classname = preg_replace('/^Sihnon_/', 'SihnonFramework_', $classname);
|
||||
|
||||
// Determine if the classname represents a class or an interface
|
||||
$parent_class = new ReflectionClass($parent_classname);
|
||||
$class_definition = '';
|
||||
if ($parent_class->isFinal()) {
|
||||
// Final classes cannot be extended
|
||||
return;
|
||||
}
|
||||
if ($parent_class->isInterface()) {
|
||||
$class_definition .= 'interface ';
|
||||
} else {
|
||||
if ($parent_class->isAbstract()) {
|
||||
$class_definition .= 'abstract ';
|
||||
}
|
||||
|
||||
$class_definition .= 'class ';
|
||||
}
|
||||
$class_definition .= "{$classname} extends {$parent_classname} {};";
|
||||
|
||||
eval($class_definition);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 = '';
|
||||
for ($i=1,$l=count($parts); $i<=$l; $i++) {
|
||||
$iPath = $parts;
|
||||
$path = join('/', array_slice($iPath, 0, $i));
|
||||
if (empty($path)) continue;
|
||||
if (!file_exists($path)) {
|
||||
if (!mkdir($path)) return false;
|
||||
if (!chmod($path, $permissions)) return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function issetelse($var, $default = null) {
|
||||
if (isset($var)) {
|
||||
return $var;
|
||||
}
|
||||
|
||||
if (is_string($default) && preg_match('/^Sihnon(Framework)?_Exception/', $default) && class_exists($default) && is_subclass_of($default, SihnonFramework_Exception)) {
|
||||
throw new $default();
|
||||
}
|
||||
|
||||
return $default;
|
||||
}
|
||||
|
||||
public static function formatDuration($time) {
|
||||
if (is_null($time)) {
|
||||
return 'unknown';
|
||||
}
|
||||
|
||||
$labels = array('seconds', 'minutes', 'hours', 'days', 'weeks', 'months', 'years');
|
||||
$limits = array(1, 60, 3600, 86400, 604800, 2592000, 31556926, PHP_INT_MAX);
|
||||
|
||||
$working_time = $time;
|
||||
|
||||
$result = "";
|
||||
$ptr = count($labels) - 1;
|
||||
|
||||
while ($ptr >= 0 && $working_time < $limits[$ptr]) {
|
||||
--$ptr;
|
||||
}
|
||||
|
||||
while ($ptr >= 0) {
|
||||
$unit_time = floor($working_time / $limits[$ptr]);
|
||||
$working_time -= $unit_time * $limits[$ptr];
|
||||
$result = $result . ' ' . $unit_time . ' ' . $labels[$ptr];
|
||||
--$ptr;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
SihnonFramework_Main::initialise();
|
||||
|
||||
?>
|
||||
30
source/lib/SihnonFramework/PluginBase.class.php
Normal file
30
source/lib/SihnonFramework/PluginBase.class.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Base class for all plugins, providing default implementations for
|
||||
* standard plugin methods.
|
||||
*
|
||||
* @class SihnonFramework_PluginBase
|
||||
*/
|
||||
class SihnonFramework_PluginBase {
|
||||
|
||||
/**
|
||||
* Provides a basic initialisation function that does nothing.
|
||||
*
|
||||
*/
|
||||
public static function init() {
|
||||
// Nothing to do
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of this plugin
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function name() {
|
||||
return static::PLUGIN_NAME;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
90
source/lib/SihnonFramework/PluginFactory.class.php
Normal file
90
source/lib/SihnonFramework/PluginFactory.class.php
Normal file
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
abstract class SihnonFramework_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();
|
||||
}
|
||||
}
|
||||
|
||||
protected static function isValidPlugin($plugin) {
|
||||
return isset(self::$validPlugins[get_called_class()][$plugin]);
|
||||
}
|
||||
|
||||
public static function getValidPlugins() {
|
||||
static::ensureScanned();
|
||||
return array_keys(self::$validPlugins[get_called_class()]);
|
||||
}
|
||||
|
||||
protected static function findPlugins($directories) {
|
||||
$plugins = array();
|
||||
|
||||
if (! is_array($directories)) {
|
||||
$directories = array(SihnonLib => $directories);
|
||||
}
|
||||
|
||||
foreach ($directories as $base_dir => $directory) {
|
||||
if (! file_exists($base_dir . $directory)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$iterator = new Sihnon_Utility_ClassFilesIterator(new Sihnon_Utility_VisibleFilesIterator(new DirectoryIterator($base_dir . $directory)));
|
||||
|
||||
foreach ($iterator as /** @var SplFileInfo */ $file) {
|
||||
$plugin = preg_replace('/.class.php$/', '', $file->getFilename());
|
||||
$plugins[] = $plugin;
|
||||
}
|
||||
}
|
||||
|
||||
return $plugins;
|
||||
}
|
||||
|
||||
protected static function loadPlugins($plugins, $prefix, $interface) {
|
||||
self::$validPlugins[get_called_class()] = array();
|
||||
|
||||
foreach ($plugins as $plugin) {
|
||||
$fullClassname = $prefix . $plugin;
|
||||
if ( ! class_exists($fullClassname, true)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( ! in_array($interface, class_implements($fullClassname))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Initialise the plugin
|
||||
call_user_func(array($fullClassname, 'init'));
|
||||
|
||||
self::$validPlugins[get_called_class()][$plugin] = $fullClassname;
|
||||
}
|
||||
}
|
||||
|
||||
public static function classname($plugin) {
|
||||
static::ensureScanned();
|
||||
|
||||
if ( ! self::isValidPlugin($plugin)) {
|
||||
throw new Sihnon_Exception_InvalidPluginName($plugin);
|
||||
}
|
||||
|
||||
return self::$validPlugins[get_called_class()][$plugin];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
class SihnonFramework_Utility_ClassFilesIterator extends FilterIterator {
|
||||
public function accept() {
|
||||
return preg_match('/.class.php$/i', $this->current()->getFilename());
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
class SihnonFramework_Utility_VisibleFilesIterator extends FilterIterator {
|
||||
public function accept() {
|
||||
return !(substr($this->current()->getFilename(), 0, 1) == '.');
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
class SihnonFramework_Utility_VisibleFilesRecursiveIterator extends RecursiveFilterIterator {
|
||||
public function accept() {
|
||||
return !(substr($this->current()->getFilename(), 0, 1) == '.');
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
Reference in New Issue
Block a user