diff options
-rw-r--r-- | app/Core/Plugin/Base.php | 4 | ||||
-rw-r--r-- | app/Core/Plugin/Hook.php | 4 | ||||
-rw-r--r-- | app/Core/Plugin/Loader.php | 137 | ||||
-rw-r--r-- | app/Core/Plugin/SchemaHandler.php | 122 | ||||
-rw-r--r-- | tests/units/Base.php | 6 | ||||
-rw-r--r-- | tests/units/Core/Plugin/SchemaHandlerTest.php (renamed from tests/units/Core/Plugin/LoaderTest.php) | 6 |
6 files changed, 171 insertions, 108 deletions
diff --git a/app/Core/Plugin/Base.php b/app/Core/Plugin/Base.php index ba95e3de..9d8167a9 100644 --- a/app/Core/Plugin/Base.php +++ b/app/Core/Plugin/Base.php @@ -5,8 +5,8 @@ namespace Kanboard\Core\Plugin; /** * Plugin Base class * - * @package plugin - * @author Frederic Guillot + * @package Kanboard\Core\Plugin + * @author Frederic Guillot */ abstract class Base extends \Kanboard\Core\Base { diff --git a/app/Core/Plugin/Hook.php b/app/Core/Plugin/Hook.php index a3bcd918..ade69150 100644 --- a/app/Core/Plugin/Hook.php +++ b/app/Core/Plugin/Hook.php @@ -5,8 +5,8 @@ namespace Kanboard\Core\Plugin; /** * Plugin Hooks Handler * - * @package plugin - * @author Frederic Guillot + * @package Kanboard\Core\Plugin + * @author Frederic Guillot */ class Hook { diff --git a/app/Core/Plugin/Loader.php b/app/Core/Plugin/Loader.php index 3482b7ee..400517b7 100644 --- a/app/Core/Plugin/Loader.php +++ b/app/Core/Plugin/Loader.php @@ -4,33 +4,35 @@ namespace Kanboard\Core\Plugin; use Composer\Autoload\ClassLoader; use DirectoryIterator; -use PDOException; use LogicException; -use RuntimeException; use Kanboard\Core\Tool; /** * Plugin Loader * - * @package plugin - * @author Frederic Guillot + * @package Kanboard\Core\Plugin + * @author Frederic Guillot */ class Loader extends \Kanboard\Core\Base { /** - * Schema version table for plugins + * Plugin instances * - * @var string + * @access public + * @var array */ - const TABLE_SCHEMA = 'plugin_schema_versions'; + public $plugins = array(); /** - * Plugin instances + * Get list of loaded plugins * * @access public - * @var array + * @return array */ - public $plugins = array(); + public function getPlugins() + { + return $this->plugins; + } /** * Scan plugin folder and load plugins @@ -46,120 +48,65 @@ class Loader extends \Kanboard\Core\Base $dir = new DirectoryIterator(PLUGINS_DIR); - foreach ($dir as $fileinfo) { - if (! $fileinfo->isDot() && $fileinfo->isDir()) { - $plugin = $fileinfo->getFilename(); - $this->loadSchema($plugin); - $this->load($plugin); + foreach ($dir as $fileInfo) { + if ($fileInfo->isDir() && substr($fileInfo->getFilename(), 0, 1) !== '.') { + $pluginName = $fileInfo->getFilename(); + $this->loadSchema($pluginName); + $this->initializePlugin($this->loadPlugin($pluginName)); } } } } /** - * Load plugin - * - * @access public - * @throws LogicException - * @param string $plugin - */ - public function load($plugin) - { - $class = '\Kanboard\Plugin\\'.$plugin.'\\Plugin'; - - if (! class_exists($class)) { - throw new LogicException('Unable to load this plugin class '.$class); - } - - $instance = new $class($this->container); - - Tool::buildDIC($this->container, $instance->getClasses()); - Tool::buildDICHelpers($this->container, $instance->getHelpers()); - - $instance->initialize(); - - if (method_exists($instance, 'onStartup')) { - $this->dispatcher->addListener('app.bootstrap', array($instance, 'onStartup')); - } - - $this->plugins[] = $instance; - } - - /** * Load plugin schema * * @access public - * @param string $plugin + * @param string $pluginName */ - public function loadSchema($plugin) + public function loadSchema($pluginName) { - $filename = PLUGINS_DIR.'/'.$plugin.'/Schema/'.ucfirst(DB_DRIVER).'.php'; - - if (file_exists($filename)) { - require_once($filename); - $this->migrateSchema($plugin); + if (SchemaHandler::hasSchema($pluginName)) { + $schemaHandler = new SchemaHandler($this->container); + $schemaHandler->loadSchema($pluginName); } } /** - * Execute plugin schema migrations + * Load plugin * * @access public - * @param string $plugin + * @throws LogicException + * @param string $pluginName + * @return Base */ - public function migrateSchema($plugin) + public function loadPlugin($pluginName) { - $last_version = constant('\Kanboard\Plugin\\'.$plugin.'\Schema\VERSION'); - $current_version = $this->getSchemaVersion($plugin); - - try { - $this->db->startTransaction(); - $this->db->getDriver()->disableForeignKeys(); + $className = '\Kanboard\Plugin\\'.$pluginName.'\\Plugin'; - for ($i = $current_version + 1; $i <= $last_version; $i++) { - $function_name = '\Kanboard\Plugin\\'.$plugin.'\Schema\version_'.$i; - - if (function_exists($function_name)) { - call_user_func($function_name, $this->db->getConnection()); - } - } - - $this->db->getDriver()->enableForeignKeys(); - $this->db->closeTransaction(); - $this->setSchemaVersion($plugin, $i - 1); - } catch (PDOException $e) { - $this->db->cancelTransaction(); - $this->db->getDriver()->enableForeignKeys(); - throw new RuntimeException('Unable to migrate schema for the plugin: '.$plugin.' => '.$e->getMessage()); + if (! class_exists($className)) { + throw new LogicException('Unable to load this plugin class '.$className); } - } - /** - * Get current plugin schema version - * - * @access public - * @param string $plugin - * @return integer - */ - public function getSchemaVersion($plugin) - { - return (int) $this->db->table(self::TABLE_SCHEMA)->eq('plugin', strtolower($plugin))->findOneColumn('version'); + return new $className($this->container); } /** - * Save last plugin schema version + * Initialize plugin * * @access public - * @param string $plugin - * @param integer $version - * @return boolean + * @param Base $plugin */ - public function setSchemaVersion($plugin, $version) + public function initializePlugin(Base $plugin) { - $dictionary = array( - strtolower($plugin) => $version - ); + if (method_exists($plugin, 'onStartup')) { + $this->dispatcher->addListener('app.bootstrap', array($plugin, 'onStartup')); + } + + Tool::buildDIC($this->container, $plugin->getClasses()); + Tool::buildDICHelpers($this->container, $plugin->getHelpers()); - return $this->db->getDriver()->upsert(self::TABLE_SCHEMA, 'plugin', 'version', $dictionary); + $plugin->initialize(); + $this->plugins[] = $plugin; } } diff --git a/app/Core/Plugin/SchemaHandler.php b/app/Core/Plugin/SchemaHandler.php new file mode 100644 index 00000000..551141b8 --- /dev/null +++ b/app/Core/Plugin/SchemaHandler.php @@ -0,0 +1,122 @@ +<?php + +namespace Kanboard\Core\Plugin; + +use PDOException; +use RuntimeException; + +/** + * Class SchemaHandler + * + * @package Kanboard\Core\Plugin + * @author Frederic Guillot + */ +class SchemaHandler extends \Kanboard\Core\Base +{ + /** + * Schema version table for plugins + * + * @var string + */ + const TABLE_SCHEMA = 'plugin_schema_versions'; + + /** + * Get schema filename + * + * @static + * @access public + * @param string $pluginName + * @return string + */ + public static function getSchemaFilename($pluginName) + { + return PLUGINS_DIR.'/'.$pluginName.'/Schema/'.ucfirst(DB_DRIVER).'.php'; + } + + /** + * Return true if the plugin has schema + * + * @static + * @access public + * @param string $pluginName + * @return boolean + */ + public static function hasSchema($pluginName) + { + return file_exists(self::getSchemaFilename($pluginName)); + } + + /** + * Load plugin schema + * + * @access public + * @param string $pluginName + */ + public function loadSchema($pluginName) + { + require_once self::getSchemaFilename($pluginName); + $this->migrateSchema($pluginName); + } + + /** + * Execute plugin schema migrations + * + * @access public + * @param string $pluginName + */ + public function migrateSchema($pluginName) + { + $lastVersion = constant('\Kanboard\Plugin\\'.$pluginName.'\Schema\VERSION'); + $currentVersion = $this->getSchemaVersion($pluginName); + + try { + $this->db->startTransaction(); + $this->db->getDriver()->disableForeignKeys(); + + for ($i = $currentVersion + 1; $i <= $lastVersion; $i++) { + $functionName = '\Kanboard\Plugin\\'.$pluginName.'\Schema\version_'.$i; + + if (function_exists($functionName)) { + call_user_func($functionName, $this->db->getConnection()); + } + } + + $this->db->getDriver()->enableForeignKeys(); + $this->db->closeTransaction(); + $this->setSchemaVersion($pluginName, $i - 1); + } catch (PDOException $e) { + $this->db->cancelTransaction(); + $this->db->getDriver()->enableForeignKeys(); + throw new RuntimeException('Unable to migrate schema for the plugin: '.$pluginName.' => '.$e->getMessage()); + } + } + + /** + * Get current plugin schema version + * + * @access public + * @param string $plugin + * @return integer + */ + public function getSchemaVersion($plugin) + { + return (int) $this->db->table(self::TABLE_SCHEMA)->eq('plugin', strtolower($plugin))->findOneColumn('version'); + } + + /** + * Save last plugin schema version + * + * @access public + * @param string $plugin + * @param integer $version + * @return boolean + */ + public function setSchemaVersion($plugin, $version) + { + $dictionary = array( + strtolower($plugin) => $version + ); + + return $this->db->getDriver()->upsert(self::TABLE_SCHEMA, 'plugin', 'version', $dictionary); + } +} diff --git a/tests/units/Base.php b/tests/units/Base.php index a3dedafd..171f9b2b 100644 --- a/tests/units/Base.php +++ b/tests/units/Base.php @@ -8,7 +8,6 @@ use Symfony\Component\EventDispatcher\EventDispatcher; use Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcher; use Symfony\Component\Stopwatch\Stopwatch; use SimpleLogger\Logger; -use SimpleLogger\File; use Kanboard\Core\Session\FlashMessage; use Kanboard\Core\Session\SessionStorage; use Kanboard\ServiceProvider\ActionProvider; @@ -91,9 +90,4 @@ abstract class Base extends PHPUnit_Framework_TestCase { $this->container['db']->closeConnection(); } - - public function isWindows() - { - return substr(PHP_OS, 0, 3) === 'WIN'; - } } diff --git a/tests/units/Core/Plugin/LoaderTest.php b/tests/units/Core/Plugin/SchemaHandlerTest.php index 448723d8..98a00e0b 100644 --- a/tests/units/Core/Plugin/LoaderTest.php +++ b/tests/units/Core/Plugin/SchemaHandlerTest.php @@ -2,13 +2,13 @@ require_once __DIR__.'/../../Base.php'; -use Kanboard\Core\Plugin\Loader; +use Kanboard\Core\Plugin\SchemaHandler; -class LoaderTest extends Base +class SchemaHandlerTest extends Base { public function testGetSchemaVersion() { - $p = new Loader($this->container); + $p = new SchemaHandler($this->container); $this->assertEquals(0, $p->getSchemaVersion('not_found')); $this->assertTrue($p->setSchemaVersion('plugin1', 1)); |