diff --git a/include/class.forms.php b/include/class.forms.php index 35121204b94e991dcb25764a49a2fd2377bbace7..67b05e16ddf8aaae0f6e37056b2cade65b5595db 100644 --- a/include/class.forms.php +++ b/include/class.forms.php @@ -87,6 +87,7 @@ class Form { $this->_clean[$key] = $this->_clean[$field->get('name')] = $field->getClean(); } + unset($this->_clean[""]); } return $this->_clean; } diff --git a/include/class.plugin.php b/include/class.plugin.php index 76ad2d24c5aecc6b16e72310b632573e5883695e..74fddc0766906a4f4966f573f06311453e4cee03 100644 --- a/include/class.plugin.php +++ b/include/class.plugin.php @@ -50,22 +50,24 @@ class PluginConfig extends Config { */ function commit(&$errors=array()) { $f = $this->getForm(); + $commit = false; if ($f->isValid()) { $config = $f->getClean(); - $this->pre_save($config, $errors); + $commit = $this->pre_save($config, $errors); } $errors += $f->errors(); - if (count($errors) === 0) + if ($commit && count($errors) === 0) return $this->updateAll($config); return false; } /** * Pre-save hook to check configuration for errors (other than obvious - * validation errors) prior to saving + * validation errors) prior to saving. Add an error to the errors list + * or return boolean FALSE if the config commit should be aborted. */ function pre_save($config, &$errors) { - return; + return true; } /** @@ -81,6 +83,7 @@ class PluginConfig extends Config { class PluginManager { static private $plugin_info = array(); + static private $plugin_list = array(); /** * boostrap @@ -104,14 +107,12 @@ class PluginManager { * and active plugins */ static function allInstalled() { - static $plugins = null; - if ($plugins !== null) - return $plugins; + if (static::$plugin_list) + return static::$plugin_list; - $plugins = array(); $sql = 'SELECT * FROM '.PLUGIN_TABLE; if (!($res = db_query($sql))) - return $plugins; + return static::$plugin_list; $infos = static::allInfos(); while ($ht = db_fetch_array($res)) { @@ -121,15 +122,20 @@ class PluginManager { $info = $infos[$ht['install_path']]; if ($ht['isactive']) { list($path, $class) = explode(':', $info['plugin']); - require_once(INCLUDE_DIR . '/' . $ht['install_path'] . '/' . $path); - $plugins[$ht['install_path']] = new $class($ht['id']); + if (!$class) + $class = $path; + else + require_once(INCLUDE_DIR . $ht['install_path'] + . '/' . $path); + static::$plugin_list[$ht['install_path']] + = new $class($ht['id']); } else { - $plugins[$ht['install_path']] = $ht; + static::$plugin_list[$ht['install_path']] = $ht; } } } - return $plugins; + return static::$plugin_list; } static function allActive() { @@ -193,7 +199,10 @@ class PluginManager { return $ht; // Usually this happens when the plugin is being enabled list($path, $class) = explode(':', $info['plugin']); - require_once(INCLUDE_DIR . $info['install_path'] . '/' . $path); + if (!$class) + $class = $path; + else + require_once(INCLUDE_DIR . $info['install_path'] . '/' . $path); $instances[$path] = new $class($ht['id']); } return $instances[$path]; @@ -209,10 +218,14 @@ class PluginManager { if (!($info = $this->getInfoForPath($path))) return false; - $sql='INSERT INTO '.PLUGIN_TABLE.'SET installed=NOW() ' + $sql='INSERT INTO '.PLUGIN_TABLE.' SET installed=NOW() ' .', install_path='.db_input($path) .', name='.db_input($info['name']); - return (db_query($sql) && db_affected_rows()); + if (!db_query($sql) || !db_affected_rows()) + return false; + + static::$plugin_list = array(); + return true; } } @@ -265,6 +278,9 @@ class Plugin { * reinstalled, it will have to be reconfigured. */ function uninstall() { + if ($this->pre_uninstall() === false) + return false; + $sql = 'DELETE FROM '.PLUGIN_TABLE .' WHERE id='.db_input($this->getId()); if (db_query($sql) && db_affected_rows()) @@ -272,6 +288,17 @@ class Plugin { return false; } + /** + * pre_uninstall + * + * Hook function to veto the uninstallation request. Return boolean + * FALSE if the uninstall operation should be aborted. + * TODO: Recommend a location to stash an error message if aborting + */ + function pre_uninstall() { + return true; + } + function enable() { $sql = 'UPDATE '.PLUGIN_TABLE .' SET isactive=1 WHERE id='.db_input($this->getId()); diff --git a/include/staff/plugin-add.inc.php b/include/staff/plugin-add.inc.php new file mode 100644 index 0000000000000000000000000000000000000000..46251f66d1c2269e8c2417ed0e238613d1e1f8e6 --- /dev/null +++ b/include/staff/plugin-add.inc.php @@ -0,0 +1,35 @@ + +<h2>Install a new plugin</h2> +<p> +To add a plugin into the system, download and place the plugin into the +<code>include/plugins</code> folder. Once in the plugin is in the +<code>plugins/</code> folder, it will be shown in the list below. +</p> + +<form method="post" action="?"> + <?php echo csrf_token(); ?> + <input type="hidden" name="do" value="install"/> +<table class="list" width="100%"><tbody> +<?php + +$installed = $ost->plugins->allInstalled(); +foreach ($ost->plugins->allInfos() as $info) { + // Ignore installed plugins + if (isset($installed[$info['install_path']])) + continue; + ?> + <tr><td><button type="submit" name="install_path" + value="<?php echo $info['install_path']; + ?>">Install</button></td> + <td> + <div><strong><?php echo $info['name']; ?></strong><br/> + <div><?php echo $info['description']; ?></div> + <div class="faded"><em>Version: <?php echo $info['version']; ?></em></div> + <div class="faded"><em>Author: <?php echo $info['author']; ?></em></div> + </div> + </td></tr> + <?php +} +?> +</tbody></table> +</form> diff --git a/include/staff/plugin.inc.php b/include/staff/plugin.inc.php index f57b12b93a7f86d969231f20bb88ae7819990311..89c056d006dec8d368208b6f14658c0c29af09f0 100644 --- a/include/staff/plugin.inc.php +++ b/include/staff/plugin.inc.php @@ -9,12 +9,6 @@ if($plugin && $_REQUEST['a']!='add') { $action = 'update'; $submit_text='Save Changes'; $info = $plugin->ht; - $newcount=2; -} else { - $title = 'Install plugin'; - $action = 'add'; - $submit_text='Install'; - $newcount=4; } $info=Format::htmlchars(($errors && $_POST)?$_POST:$info); ?> diff --git a/scp/plugins.php b/scp/plugins.php index 7fdcb12aec33022ea9641895c59b3e59bbc1e5cd..c5e7e8918027296970b717289626fb4c5982d6ac 100644 --- a/scp/plugins.php +++ b/scp/plugins.php @@ -31,14 +31,30 @@ if($_POST) { $p->disable(); } } + break; + case 'delete': + foreach ($_POST['ids'] as $id) { + if ($p = Plugin::lookup($id)) { + var_dump($p); + $p->uninstall(); + } + } + break; } } + break; + case 'install': + if ($ost->plugins->install($_POST['install_path'])) + $msg = 'Plugin successfully installed'; + break; } } $page = 'plugins.inc.php'; if ($plugin) $page = 'plugin.inc.php'; +elseif ($_REQUEST['a']=='add') + $page = 'plugin-add.inc.php'; $nav->setTabActive('manage'); require(STAFFINC_DIR.'header.inc.php');