From 81521eae5f60c27a752af4726d2208fd703bc76d Mon Sep 17 00:00:00 2001 From: Ben Roberts Date: Sun, 10 Oct 2010 18:32:16 +0100 Subject: [PATCH] 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. --- source/lib/Sihnon/Exceptions.class.php | 24 ----- .../BackgroundTask.class.php | 2 +- .../Cache.class.php | 2 +- .../Config.class.php | 2 +- .../Config/IPlugin.class.php | 2 +- .../Config/Plugin/Database.class.php | 2 +- .../Config/Plugin/FlatFile.class.php | 2 +- .../Config/PluginFactory.class.php | 11 ++- .../Database.class.php | 2 +- .../lib/SihnonFramework/Exceptions.class.php | 24 +++++ .../ForegroundTask.class.php | 2 +- .../IPlugin.class.php | 2 +- .../IPluginFactory.class.php | 2 +- .../{Sihnon => SihnonFramework}/Log.class.php | 4 +- .../Log/IPlugin.class.php | 2 +- .../Log/Plugin/Database.class.php | 2 +- .../Log/Plugin/FlatFile.class.php | 2 +- .../Log/PluginFactory.class.php | 11 ++- .../LogEntry.class.php | 2 +- .../Main.class.php | 97 +++++++++++++------ .../PluginBase.class.php | 4 +- .../PluginFactory.class.php | 26 +++-- .../Utility/ClassFilesIterator.class.php | 2 +- .../Utility/VisibleFilesIterator.class.php | 2 +- .../VisibleFilesRecursiveIterator.class.php | 2 +- 25 files changed, 145 insertions(+), 90 deletions(-) delete mode 100644 source/lib/Sihnon/Exceptions.class.php rename source/lib/{Sihnon => SihnonFramework}/BackgroundTask.class.php (85%) rename source/lib/{Sihnon => SihnonFramework}/Cache.class.php (98%) rename source/lib/{Sihnon => SihnonFramework}/Config.class.php (98%) rename source/lib/{Sihnon => SihnonFramework}/Config/IPlugin.class.php (91%) rename source/lib/{Sihnon => SihnonFramework}/Config/Plugin/Database.class.php (86%) rename source/lib/{Sihnon => SihnonFramework}/Config/Plugin/FlatFile.class.php (83%) rename source/lib/{Sihnon => SihnonFramework}/Config/PluginFactory.class.php (53%) rename source/lib/{Sihnon => SihnonFramework}/Database.class.php (99%) create mode 100644 source/lib/SihnonFramework/Exceptions.class.php rename source/lib/{Sihnon => SihnonFramework}/ForegroundTask.class.php (98%) rename source/lib/{Sihnon => SihnonFramework}/IPlugin.class.php (72%) rename source/lib/{Sihnon => SihnonFramework}/IPluginFactory.class.php (55%) rename source/lib/{Sihnon => SihnonFramework}/Log.class.php (95%) rename source/lib/{Sihnon => SihnonFramework}/Log/IPlugin.class.php (93%) rename source/lib/{Sihnon => SihnonFramework}/Log/Plugin/Database.class.php (95%) rename source/lib/{Sihnon => SihnonFramework}/Log/Plugin/FlatFile.class.php (93%) rename source/lib/{Sihnon => SihnonFramework}/Log/PluginFactory.class.php (55%) rename source/lib/{Sihnon => SihnonFramework}/LogEntry.class.php (98%) rename source/lib/{Sihnon => SihnonFramework}/Main.class.php (56%) rename source/lib/{Sihnon => SihnonFramework}/PluginBase.class.php (86%) rename source/lib/{Sihnon => SihnonFramework}/PluginFactory.class.php (67%) rename source/lib/{Sihnon => SihnonFramework}/Utility/ClassFilesIterator.class.php (63%) rename source/lib/{Sihnon => SihnonFramework}/Utility/VisibleFilesIterator.class.php (61%) rename source/lib/{Sihnon => SihnonFramework}/Utility/VisibleFilesRecursiveIterator.class.php (56%) diff --git a/source/lib/Sihnon/Exceptions.class.php b/source/lib/Sihnon/Exceptions.class.php deleted file mode 100644 index ff4b7b3..0000000 --- a/source/lib/Sihnon/Exceptions.class.php +++ /dev/null @@ -1,24 +0,0 @@ - diff --git a/source/lib/Sihnon/BackgroundTask.class.php b/source/lib/SihnonFramework/BackgroundTask.class.php similarity index 85% rename from source/lib/Sihnon/BackgroundTask.class.php rename to source/lib/SihnonFramework/BackgroundTask.class.php index 28d6148..783dad4 100644 --- a/source/lib/Sihnon/BackgroundTask.class.php +++ b/source/lib/SihnonFramework/BackgroundTask.class.php @@ -1,6 +1,6 @@ 'SihnonFramework/Config/Plugin', + Sihnon_Lib => 'Sihnon/Config/Plugin/', + ); public static function init() { diff --git a/source/lib/Sihnon/Database.class.php b/source/lib/SihnonFramework/Database.class.php similarity index 99% rename from source/lib/Sihnon/Database.class.php rename to source/lib/SihnonFramework/Database.class.php index 952e5c3..61978f6 100644 --- a/source/lib/Sihnon/Database.class.php +++ b/source/lib/SihnonFramework/Database.class.php @@ -1,6 +1,6 @@ diff --git a/source/lib/Sihnon/ForegroundTask.class.php b/source/lib/SihnonFramework/ForegroundTask.class.php similarity index 98% rename from source/lib/Sihnon/ForegroundTask.class.php rename to source/lib/SihnonFramework/ForegroundTask.class.php index 60adea4..3434c4f 100644 --- a/source/lib/Sihnon/ForegroundTask.class.php +++ b/source/lib/SihnonFramework/ForegroundTask.class.php @@ -1,6 +1,6 @@ diff --git a/source/lib/Sihnon/Log/IPlugin.class.php b/source/lib/SihnonFramework/Log/IPlugin.class.php similarity index 93% rename from source/lib/Sihnon/Log/IPlugin.class.php rename to source/lib/SihnonFramework/Log/IPlugin.class.php index b6fec93..a30d404 100644 --- a/source/lib/Sihnon/Log/IPlugin.class.php +++ b/source/lib/SihnonFramework/Log/IPlugin.class.php @@ -1,6 +1,6 @@ 'SihnonFramework/Log/Plugin/', + Sihnon_Lib => 'Sihnon/Log/Plugin/', + ); public static function init() { diff --git a/source/lib/Sihnon/LogEntry.class.php b/source/lib/SihnonFramework/LogEntry.class.php similarity index 98% rename from source/lib/Sihnon/LogEntry.class.php rename to source/lib/SihnonFramework/LogEntry.class.php index 0d3916c..b3494f6 100644 --- a/source/lib/Sihnon/LogEntry.class.php +++ b/source/lib/SihnonFramework/LogEntry.class.php @@ -1,6 +1,6 @@ config; @@ -56,7 +56,7 @@ class Sihnon_Main { /** * - * @return Sihnon_Database + * @return SihnonFramework_Database */ public function database() { return $this->database; @@ -64,7 +64,7 @@ class Sihnon_Main { /** * - * @return Sihnon_Log + * @return SihnonFramework_Log */ public function log() { return $this->log; @@ -72,7 +72,7 @@ class Sihnon_Main { /** * - * @return Sihnon_Cache + * @return SihnonFramework_Cache */ public function cache() { return $this->cache; @@ -91,35 +91,74 @@ class Sihnon_Main { } public static function initialise() { - spl_autoload_register(array('Sihnon_Main','autoload')); + 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'); // TODO Subclass this exception + throw new Exception('Illegal characters in classname'); } // Ensure the class to load begins with our prefix - if (!preg_match('/^Sihnon_/', $classname)) { - return; - } - - // Special case: All exceptions are stored in the same file - if (preg_match('/^Sihnon_Exception/', $classname)) { - require_once(Sihnon_Lib . 'Sihnon/Exceptions.class.php'); - return; - } - - // Replace any underscores with directory separators - $filename = Sihnon_Lib . preg_replace('/_/', '/', $classname); - - // Tack on the class file suffix - $filename .= '.class.php'; - - // If this file exists, load it - if (file_exists($filename)) { - require_once $filename; + 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; + } } } @@ -155,7 +194,7 @@ class Sihnon_Main { return $var; } - if (is_string($default) && preg_match('/^Sihnon_Exception/', $default) && class_exists($default) && is_subclass_of($default, Sihnon_Exception)) { + if (is_string($default) && preg_match('/^Sihnon(Framework)?_Exception/', $default) && class_exists($default) && is_subclass_of($default, SihnonFramework_Exception)) { throw new $default(); } @@ -191,6 +230,6 @@ class Sihnon_Main { } -Sihnon_Main::initialise(); +SihnonFramework_Main::initialise(); ?> diff --git a/source/lib/Sihnon/PluginBase.class.php b/source/lib/SihnonFramework/PluginBase.class.php similarity index 86% rename from source/lib/Sihnon/PluginBase.class.php rename to source/lib/SihnonFramework/PluginBase.class.php index 360e38f..e2e42fa 100644 --- a/source/lib/Sihnon/PluginBase.class.php +++ b/source/lib/SihnonFramework/PluginBase.class.php @@ -4,9 +4,9 @@ * Base class for all plugins, providing default implementations for * standard plugin methods. * - * @class Sihnon_PluginBase + * @class SihnonFramework_PluginBase */ -class Sihnon_PluginBase { +class SihnonFramework_PluginBase { /** * Provides a basic initialisation function that does nothing. diff --git a/source/lib/Sihnon/PluginFactory.class.php b/source/lib/SihnonFramework/PluginFactory.class.php similarity index 67% rename from source/lib/Sihnon/PluginFactory.class.php rename to source/lib/SihnonFramework/PluginFactory.class.php index b1e0102..4598d6d 100644 --- a/source/lib/Sihnon/PluginFactory.class.php +++ b/source/lib/SihnonFramework/PluginFactory.class.php @@ -1,6 +1,6 @@ $directories); + } - foreach ($iterator as /** @var SplFileInfo */ $file) { - $plugin = preg_replace('/.class.php$/', '', $file->getFilename()); - $plugins[] = $plugin; + 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; diff --git a/source/lib/Sihnon/Utility/ClassFilesIterator.class.php b/source/lib/SihnonFramework/Utility/ClassFilesIterator.class.php similarity index 63% rename from source/lib/Sihnon/Utility/ClassFilesIterator.class.php rename to source/lib/SihnonFramework/Utility/ClassFilesIterator.class.php index ba4941b..70fdcb7 100644 --- a/source/lib/Sihnon/Utility/ClassFilesIterator.class.php +++ b/source/lib/SihnonFramework/Utility/ClassFilesIterator.class.php @@ -1,6 +1,6 @@ current()->getFilename()); } diff --git a/source/lib/Sihnon/Utility/VisibleFilesIterator.class.php b/source/lib/SihnonFramework/Utility/VisibleFilesIterator.class.php similarity index 61% rename from source/lib/Sihnon/Utility/VisibleFilesIterator.class.php rename to source/lib/SihnonFramework/Utility/VisibleFilesIterator.class.php index 88ec65e..ed01180 100644 --- a/source/lib/Sihnon/Utility/VisibleFilesIterator.class.php +++ b/source/lib/SihnonFramework/Utility/VisibleFilesIterator.class.php @@ -1,6 +1,6 @@ current()->getFilename(), 0, 1) == '.'); } diff --git a/source/lib/Sihnon/Utility/VisibleFilesRecursiveIterator.class.php b/source/lib/SihnonFramework/Utility/VisibleFilesRecursiveIterator.class.php similarity index 56% rename from source/lib/Sihnon/Utility/VisibleFilesRecursiveIterator.class.php rename to source/lib/SihnonFramework/Utility/VisibleFilesRecursiveIterator.class.php index 6a5c65b..4fa559f 100644 --- a/source/lib/Sihnon/Utility/VisibleFilesRecursiveIterator.class.php +++ b/source/lib/SihnonFramework/Utility/VisibleFilesRecursiveIterator.class.php @@ -1,6 +1,6 @@ current()->getFilename(), 0, 1) == '.'); }