Merge pull request #184 from Mibew/fix_143

This commit is contained in:
Fedor A. Fetisov 2016-12-29 17:49:37 +03:00 committed by GitHub
commit 16b7297d19
12 changed files with 113 additions and 14 deletions

View File

@ -1,6 +1,6 @@
{
"name": "mibew/mibew",
"version": "2.1.2",
"version": "2.2.0",
"description": "Mibew Messenger - open-source live support application",
"type": "project",
"homepage": "http://mibew.org",

View File

@ -1 +1 @@
Mibew/2.1.2
Mibew/2.2.0

View File

@ -314,6 +314,8 @@ plugin:
installed: "tinyint NOT NULL DEFAULT 0"
# Indicates if the plugin is enabled or not.
enabled: "tinyint NOT NULL DEFAULT 0"
# Indicates if the plugin is initialized or not.
initialized: "tinyint NOT NULL DEFAULT 0"
unique_keys:
name: [name]

View File

@ -22,6 +22,7 @@ require_once(dirname(__FILE__) . '/libs/init.php');
use Mibew\Cache\CacheFactory;
use Mibew\Maintenance\CronWorker;
use Mibew\Plugin\PluginManager;
$configs = load_system_configs();
@ -30,6 +31,13 @@ $cache_factory = new CacheFactory($configs['cache']);
// For now directory for cache files cannot be changed via the configs file.
$cache_factory->setOption('path', MIBEW_FS_ROOT . '/cache/stash');
// Run plugins
if (get_maintenance_mode() === false) {
$plugin_manager = PluginManager::getInstance();
$plugin_manager->setCache($cache_factory->getCache());
$plugin_manager->loadPlugins($configs['plugins']);
}
// Do the job.
$worker = new CronWorker($cache_factory->getCache());
$success = $worker->run();

View File

@ -24,6 +24,7 @@ use Mibew\Application;
use Mibew\Authentication\AuthenticationManager;
use Mibew\Cache\CacheFactory;
use Mibew\Mail\MailerFactory;
use Mibew\Plugin\PluginManager;
use Mibew\Routing\Router;
use Mibew\Routing\Loader\CacheLoader;
use Mibew\Routing\Loader\PluginLoader;
@ -40,6 +41,13 @@ $cache_factory = new CacheFactory($configs['cache']);
// TODO: Evaluate possibility of using custom cache directory.
$cache_factory->setOption('path', MIBEW_FS_ROOT . '/cache/stash');
// Run plugins
if (get_maintenance_mode() === false) {
$plugin_manager = PluginManager::getInstance();
$plugin_manager->setCache($cache_factory->getCache());
$plugin_manager->loadPlugins($configs['plugins']);
}
// The main route loader which loads nothig but works as a cache proxy for other
// loaders.
$route_loader = new CacheLoader($cache_factory->getCache());

View File

@ -412,4 +412,30 @@ class Updater
return true;
}
/**
* Performs all database updates needed for 2.2.0.
*
* @return boolean True if the updates have been applied successfully and
* false otherwise.
*/
protected function update20200()
{
$db = $this->getDatabase();
if (!$db) {
return false;
}
try {
// Alter plugin table.
$db->query('ALTER TABLE {plugin} ADD COLUMN initialized tinyint NOT NULL DEFAULT 0 AFTER enabled');
} catch (\Exception $e) {
$this->errors[] = getlocal('Cannot update tables: {0}', $e->getMessage());
return false;
}
return true;
}
}

View File

@ -81,6 +81,7 @@ class PluginInfo
$state->version = false;
$state->installed = false;
$state->enabled = false;
$state->initialized = false;
}
$this->pluginState = $state;
}
@ -209,6 +210,16 @@ class PluginInfo
return new $plugin_class($configs);
}
/**
* Checks if the plugin is initialized.
*
* @return bool
*/
public function isInitialized()
{
return $this->getState()->initialized;
}
/**
* Checks if the plugin is enabled.
*

View File

@ -19,15 +19,18 @@
namespace Mibew\Plugin;
use Mibew\Cache\CacheAwareInterface;
use Mibew\Plugin\Utils as PluginUtils;
use Mibew\Maintenance\Utils as MaintenanceUtils;
use Stash\Interfaces\PoolInterface;
/**
* Manage plugins.
*
* Implements singleton pattern.
*/
class PluginManager
class PluginManager implements
CacheAwareInterface
{
/**
* An instance of Plugin Manager class.
@ -35,6 +38,11 @@ class PluginManager
*/
protected static $instance = null;
/**
* @var PoolInterface|null
*/
protected $cache = null;
/**
* Contains all loaded plugins
*
@ -56,6 +64,22 @@ class PluginManager
return self::$instance;
}
/**
* {@inheritdoc}
*/
public function setCache(PoolInterface $cache)
{
$this->cache = $cache;
}
/**
* {@inheritdoc}
*/
public function getCache()
{
return $this->cache;
}
/**
* Returns plugin instance.
*
@ -181,12 +205,28 @@ class PluginManager
$this->loadedPlugins[$name] = $instance;
$running_queue[$instance->getWeight() . "_" . $offset] = $instance;
$offset++;
if (!$plugin_info->isInitialized()) {
$plugin_info->getState()->initialized = true;
$plugin_info->getState()->save();
// Plugins can have own routing files and when the plugin becomes
// initialized after non-initialized state its routes should be
// reset. So the cache is cleared to make sure the routes set is up to date.
$this->getCache()->getItem('routing/resources')->clear();
}
} else {
// The plugin cannot be loaded. Just skip it.
trigger_error(
"Plugin '{$name}' was not initialized correctly!",
E_USER_WARNING
);
if ($plugin_info->isInitialized()) {
$plugin_info->getState()->initialized = false;
$plugin_info->getState()->save();
// Plugins can have own routing files and when the plugin becomes
// non-initialized after initialized state its routes should be
// removed. So the cache is cleared to make sure the routes set is up to date.
$this->getCache()->getItem('routing/resources')->clear();
}
}
}
@ -256,6 +296,7 @@ class PluginManager
}
$plugin->getState()->enabled = false;
$plugin->getState()->initialized = false;
$plugin->getState()->save();
return true;

View File

@ -193,6 +193,7 @@ class State
$this->version = null;
$this->installed = false;
$this->enabled = false;
$this->initialized = false;
}
/**
@ -205,13 +206,14 @@ class State
if (!$this->id) {
// This state is new.
$db->query(
("INSERT INTO {plugin} (name, version, installed, enabled) "
. "VALUES (:name, :version, :installed, :enabled)"),
("INSERT INTO {plugin} (name, version, installed, enabled, initialized) "
. "VALUES (:name, :version, :installed, :enabled, :initialized)"),
array(
':name' => $this->pluginName,
':version' => $this->version,
':installed' => (int)$this->installed,
':enabled' => (int)$this->enabled,
':initialized' => (int)$this->initialized,
)
);
$this->id = $db->insertedId();
@ -219,13 +221,14 @@ class State
// Update existing state
$db->query(
("UPDATE {plugin} SET name = :name, version = :version, "
. "installed = :installed, enabled = :enabled WHERE id = :id"),
. "installed = :installed, enabled = :enabled, initialized = :initialized WHERE id = :id"),
array(
':id' => $this->id,
':name' => $this->pluginName,
':version' => $this->version,
':installed' => (int)$this->installed,
':enabled' => (int)$this->enabled,
':initialized' => (int)$this->initialized,
)
);
}
@ -261,5 +264,6 @@ class State
$this->version = $db_fields['version'];
$this->enabled = (bool)$db_fields['enabled'];
$this->installed = (bool)$db_fields['installed'];
$this->initialized = (bool)$db_fields['initialized'];
}
}

View File

@ -53,6 +53,12 @@ function load_system_configs()
$configs['cache'] = array();
}
// Plugins section should exists too. The logic behind "empty" statement is
// the same as above.
if (empty($configs['plugins'])) {
$configs['plugins'] = array();
}
// Database section should exists too. Also it should have an appropriate structure.
if (empty($configs['database'])) {
$configs['database'] = array();

View File

@ -20,7 +20,7 @@
/**
* Current version of Mibew Messenger
*/
define('MIBEW_VERSION', '2.1.2');
define('MIBEW_VERSION', '2.2.0');
/**
* Prefix for session variables.

View File

@ -101,10 +101,3 @@ require_once(MIBEW_FS_ROOT . '/libs/pagination.php');
require_once(MIBEW_FS_ROOT . '/libs/statistics.php');
require_once(MIBEW_FS_ROOT . '/libs/track.php');
require_once(MIBEW_FS_ROOT . '/libs/userinfo.php');
// Run plugins only after all libs are loaded.
if (get_maintenance_mode() === false && !empty($configs['plugins'])) {
// A list of plugins is defined in $plugins_list variable in
// configs/config.yml
\Mibew\Plugin\PluginManager::getInstance()->loadPlugins($configs['plugins']);
}