aboutsummaryrefslogtreecommitdiff
path: root/ratatoeskr
diff options
context:
space:
mode:
authorKevin Chabowski <kevin@kch42.de>2011-12-23 01:43:53 +0100
committerKevin Chabowski <kevin@kch42.de>2011-12-23 01:43:53 +0100
commitdf0658f7e10d2bf87460195f792398d16eee811e (patch)
tree1f7720ecc6c3ca5e94e84022766121f6f677c88f /ratatoeskr
parent7d6a5eca4e0a38ae615634542859d29ab79c94e8 (diff)
downloadratatoeskr-cms-df0658f7e10d2bf87460195f792398d16eee811e.tar.gz
ratatoeskr-cms-df0658f7e10d2bf87460195f792398d16eee811e.tar.bz2
ratatoeskr-cms-df0658f7e10d2bf87460195f792398d16eee811e.zip
Added plugin management to bakend and fixed db models.
Diffstat (limited to 'ratatoeskr')
-rw-r--r--ratatoeskr/backend.php264
-rw-r--r--ratatoeskr/main.php17
-rw-r--r--ratatoeskr/setup/create_tables.php6
-rw-r--r--ratatoeskr/sys/models.php67
-rw-r--r--ratatoeskr/sys/plugin_api.php2
-rw-r--r--ratatoeskr/sys/pluginpackage.php31
-rw-r--r--ratatoeskr/templates/src/systemtemplates/confirminstall.html26
-rw-r--r--ratatoeskr/templates/src/systemtemplates/pluginhelp.html4
-rw-r--r--ratatoeskr/templates/src/systemtemplates/plugininstall.html18
-rw-r--r--ratatoeskr/templates/src/systemtemplates/pluginlist.html66
-rw-r--r--ratatoeskr/translations/en.php25
11 files changed, 494 insertions, 32 deletions
diff --git a/ratatoeskr/backend.php b/ratatoeskr/backend.php
index 2efe00c..c5ae9c9 100644
--- a/ratatoeskr/backend.php
+++ b/ratatoeskr/backend.php
@@ -1532,8 +1532,268 @@ $backend_subactions = url_action_subactions(array(
echo $ste->exectemplate("systemtemplates/user.html");
}
- ))
- ))
+ )),
+ "repos" => function(&$data, $url_now, &$url_next)
+ {
+ global $ste, $translation, $languages, $rel_path_to_root;
+
+ $url_next = array();
+
+ $ste->vars["section"] = "admin";
+ $ste->vars["submenu"] = "repos";
+ $ste->vars["pagetitle"] = $translation["menu_plugin_repos"];
+
+
+
+ echo $ste->exectemplate("systemtemplates/repos.html");
+ }
+ )),
+ "plugin" => url_action_subactions(array(
+ "list" => function(&$data, $url_now, &$url_next)
+ {
+ global $ste, $translation, $languages, $rel_path_to_root, $plugin_objs;
+
+ $url_next = array();
+
+ $ste->vars["section"] = "plugins";
+ $ste->vars["submenu"] = "pluginlist";
+ $ste->vars["pagetitle"] = $translation["menu_pluginlist"];
+
+ /* Delete plugins? */
+ if(isset($_POST["delete"]) and ($_POST["really_delete"] == "yes") and (!empty($_POST["plugins_multiselect"])))
+ {
+ foreach($_POST["plugins_multiselect"] as $pid)
+ {
+ try
+ {
+ $plugin = Plugin::by_id($pid);
+ if(!isset($plugin_objs[$pid]))
+ {
+ eval($plugin->code);
+ $plugin_objs[$pid] = new $plugin->classname($pid);
+ }
+ $plugin_objs[$pid]->uninstall();
+ $plugin->delete();
+ }
+ catch(DoesNotExistError $e)
+ {
+ continue;
+ }
+ }
+
+ $ste->vars["success"] = $translation["successfully_deleted_plugins"];
+ }
+
+ /* Activate or deactivate plugins? */
+ if((isset($_POST["activate"]) or isset($_POST["deactivate"])) and (!empty($_POST["plugins_multiselect"])))
+ {
+ $newstatus = isset($_POST["activate"]);
+ foreach($_POST["plugins_multiselect"] as $pid)
+ {
+ try
+ {
+ $plugin = Plugin::by_id($pid);
+ if(!$plugin->installed)
+ continue;
+ $plugin->active = $newstatus;
+ $plugin->save();
+ if($newstatus and(!isset($plugin_objs[$pid])))
+ {
+ eval($plugin->code);
+ $plugin_objs[$pid] = new $plugin->classname($pid);
+ $plugin_objs[$pid]->init();
+ }
+ }
+ catch(DoesNotExistError $e)
+ {
+ continue;
+ }
+ }
+
+ $ste->vars["success"] = $translation[$newstatus ? "plugins_activated" : "plugins_deactivated"];
+ }
+
+ $stream_ctx = stream_context_create(array("http" => array("timeout" => 5)));
+
+ /* Update plugins? */
+ if(isset($_POST["update"]) and (!empty($_POST["plugins_multiselect"])))
+ {
+ $updated = array();
+ foreach($_POST["plugins_multiselect"] as $pid)
+ {
+ try
+ {
+ $plugin = Plugin::by_id($pid);
+ if(!empty($plugin->updatepath))
+ {
+ $update_info = @unserialize(@file_get_contents($plugin->updatepath, False, $stream_ctx));
+ if(is_array($update_info) and ($update_info["current-version"] > $plugin->versioncount))
+ {
+ $pkg = PluginPackage::load(@file_get_contents($update_info["dl-path"], False, $stream_ctx));
+ $plugin->fill_from_pluginpackage($pkg);
+ $plugin->update = True;
+ $plugin->save();
+ $updated[] = $plugin->name;
+ }
+ }
+ }
+ catch(DoesNotExistError $e)
+ {
+ continue;
+ }
+ catch(InvalidPackage $e)
+ {
+ continue;
+ }
+ }
+
+ if(empty($updated))
+ $ste->vars["success"] = $translation["nothing_to_update"];
+ else
+ $ste->vars["success"] = str_replace("[[PLUGINS]]", implode(", ", $updated), $translation["successfully_updated_plugins"]);
+ }
+
+ /* Load plugin data */
+ $all_plugins = Plugin::all();
+ $ste->vars["plugins"] = array();
+ foreach($all_plugins as $p)
+ {
+ if(!$p->installed)
+ continue;
+
+ $ste->vars["plugins"][] = array(
+ "id" => $p->get_id(),
+ "name" => $p->name,
+ "versiontext" => $p->versiontext,
+ "active" => $p->active,
+ "description" => $p->short_description,
+ "web" => $p->web,
+ "author" => $p->author,
+ "help" => !empty($p->help)
+ );
+ }
+
+ echo $ste->exectemplate("systemtemplates/pluginlist.html");
+ },
+ "help" => function(&$data, $url_now, &$url_next)
+ {
+ global $ste, $translation, $languages, $rel_path_to_root;
+
+ try
+ {
+ $plugin = Plugin::by_id($url_next[0]);
+ if(empty($plugin->help))
+ throw new NotFoundError();
+ }
+ catch(DoesNotExistError $e)
+ {
+ throw new NotFoundError();
+ }
+
+ $url_next = array();
+
+ $ste->vars["section"] = "plugins";
+ $ste->vars["submenu"] = "";
+ $ste->vars["pagetitle"] = $plugin->name;
+ $ste->vars["help"] = $plugin->help;
+
+ echo $ste->exectemplate("systemtemplates/pluginhelp.html");
+ },
+ "install" => function(&$data, $url_now, &$url_next)
+ {
+ global $ste, $translation, $languages, $rel_path_to_root, $api_compat;
+
+ $url_next = array();
+
+ $ste->vars["section"] = "plugins";
+ $ste->vars["submenu"] = "installplugins";
+ $ste->vars["pagetitle"] = $translation["menu_plugininstall"];
+
+ if(isset($_POST["installpackage"]))
+ {
+ if(is_uploaded_file($_FILES["pluginpackage"]["tmp_name"]))
+ {
+ try
+ {
+ $package = PluginPackage::load(file_get_contents($_FILES["pluginpackage"]["tmp_name"]));
+ unlink($_FILES["pluginpackage"]["tmp_name"]);
+ if(in_array($package->api, $api_compat))
+ {
+ $plugin = Plugin::create();
+ $plugin->fill_from_pluginpackage($package);
+ $plugin->installed = False;
+ $plugin->active = False;
+ $plugin->save();
+ $url_next = array("confirminstall", (string) $plugin->get_id());
+ return;
+ }
+ else
+ $ste->vars["error"] = str_replace("[[API]]", $package->api, $translation["incompatible_plugin"]);
+ }
+ catch(InvalidPackage $e)
+ {
+ $ste->vars["error"] = $translation["invalid_package"];
+ unlink($_FILES["pluginpackage"]["tmp_name"]);
+ }
+ }
+ else
+ $ste->vars["error"] = $translation["upload_failed"];
+ }
+
+ echo $ste->exectemplate("systemtemplates/plugininstall.html");
+ },
+ "confirminstall" => function(&$data, $url_now, &$url_next)
+ {
+ global $ste, $translation, $languages, $rel_path_to_root;
+
+ list($plugin_id) = $url_next;
+ $url_next = array();
+
+ $ste->vars["section"] = "plugins";
+ $ste->vars["submenu"] = "installplugins";
+ $ste->vars["pagetitle"] = $translation["menu_plugininstall"];
+
+ try
+ {
+ $plugin = Plugin::by_id($plugin_id);
+ }
+ catch(DoesNotExistError $e)
+ {
+ throw new NotFoundError();
+ }
+
+ if($plugin->installed)
+ throw new NotFoundError();
+
+ $ste->vars["plugin_id"] = $plugin->get_id();
+ $ste->vars["name"] = $plugin->name;
+ $ste->vars["description"] = $plugin->short_description;
+ $ste->vars["code"] = $plugin->code;
+ $ste->vars["license"] = $plugin->license;
+
+ if(isset($_POST["yes"]))
+ {
+ $plugin->installed = True;
+ $plugin->save();
+ eval($plugin->code);
+ $plugin_instance = new $plugin->classname($plugin->get_id());
+ $plugin_instance->install();
+ $ste->vars["success"] = $translation["plugin_installed_successfully"];
+ $url_next = array("list");
+ return;
+ }
+
+ if(isset($_POST["no"]))
+ {
+ $plugin->delete();
+ $url_next = array("install");
+ return;
+ }
+
+ echo $ste->exectemplate("systemtemplates/confirminstall.html");
+ }
+ )),
+ "pluginpages" => url_action_subactions($pluginpages_handlers)
));
?>
diff --git a/ratatoeskr/main.php b/ratatoeskr/main.php
index d3be695..2a31177 100644
--- a/ratatoeskr/main.php
+++ b/ratatoeskr/main.php
@@ -18,9 +18,11 @@ require_once(dirname(__FILE__) . "/sys/plugin_api.php");
require_once(dirname(__FILE__) . "/frontend.php");
require_once(dirname(__FILE__) . "/backend.php");
+$plugin_objs = array();
+
function ratatoeskr()
{
- global $backend_subactions, $ste, $url_handlers, $ratatoeskr_settings;
+ global $backend_subactions, $ste, $url_handlers, $ratatoeskr_settings, $plugin_objs;
session_start();
if(!CONFIG_FILLED_OUT)
return setup();
@@ -30,13 +32,18 @@ function ratatoeskr()
clean_database();
$activeplugins = array_filter(Plugin::all(), function($plugin) { return $plugin->active; });
- $plugin_objs = array();
foreach($activeplugins as $plugin)
{
- eval($plugin->phpcode);
- $plugin_obj = new $plugin->class;
+ eval($plugin->code);
+ $plugin_obj = new $plugin->classname($plugin->get_id());
+ if($plugin->update)
+ {
+ $plugin_obj->update();
+ $plugin->update = False;
+ $plugin->save();
+ }
$plugin_obj->init();
- $plugin_objs[] = $plugin_obj;
+ $plugin_objs[$plugin->get_id()] = $plugin_obj;
}
/* Register URL handlers */
diff --git a/ratatoeskr/setup/create_tables.php b/ratatoeskr/setup/create_tables.php
index 543a7e3..dd37d5a 100644
--- a/ratatoeskr/setup/create_tables.php
+++ b/ratatoeskr/setup/create_tables.php
@@ -61,7 +61,7 @@ CREATE TABLE `PREFIX_multilingual` (
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
-CREATE TABLE `ratatoeskr_plugins` (
+CREATE TABLE `PREFIX_plugins` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` text COLLATE utf8_unicode_ci NOT NULL,
`author` text COLLATE utf8_unicode_ci NOT NULL,
@@ -70,14 +70,16 @@ CREATE TABLE `ratatoeskr_plugins` (
`short_description` text COLLATE utf8_unicode_ci NOT NULL,
`updatepath` text COLLATE utf8_unicode_ci NOT NULL,
`web` text COLLATE utf8_unicode_ci NOT NULL,
+ `license` text COLLATE utf8_unicode_ci NOT NULL,
`help` text COLLATE utf8_unicode_ci NOT NULL,
`code` text COLLATE utf8_unicode_ci NOT NULL,
`classname` text COLLATE utf8_unicode_ci NOT NULL,
`active` tinyint(4) NOT NULL,
`installed` tinyint(4) NOT NULL,
`added` bigint(20) NOT NULL,
+ `update` tinyint(4) NOT NULL,
PRIMARY KEY (`id`)
-) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE `PREFIX_plugin_kvstorage` (
`plugin` int(11) NOT NULL,
diff --git a/ratatoeskr/sys/models.php b/ratatoeskr/sys/models.php
index f744fbf..a0a1fda 100644
--- a/ratatoeskr/sys/models.php
+++ b/ratatoeskr/sys/models.php
@@ -1179,6 +1179,7 @@ class Plugin
* $help - Help page.
* $license - License text.
* $installed - Is this plugin installed? Used during the installation process.
+ * $update - Should the plugin be updated at next start?
*/
public $name;
@@ -1194,6 +1195,7 @@ class Plugin
public $help;
public $license;
public $installed;
+ public $update;
private function __construct() { }
@@ -1224,6 +1226,35 @@ class Plugin
}
/*
+ * Function: fill_from_pluginpackage
+ * Fills plugin data from an <PluginPackage> object.
+ *
+ * Parameters:
+ * $pkg - The <PluginPackage> object.
+ */
+ public function fill_from_pluginpackage($pkg)
+ {
+ $this->name = $pkg->name;
+ $this->code = $pkg->code;
+ $this->classname = $pkg->classname;
+ $this->author = $pkg->author;
+ $this->versiontext = $pkg->versiontext;
+ $this->versioncount = $pkg->versioncount;
+ $this->short_description = $pkg->short_description;
+ $this->updatepath = $pkg->updatepath;
+ $this->web = $pkg->web;
+ $this->license = $pkg->license;
+ $this->help = $pkg->help;
+
+ if(!empty($pkg->custompub))
+ array2dir($pkg->custompub, dirname(__FILE__) . "/../plugin_extradata/public/" . $this->get_id());
+ if(!empty($pkg->custompriv))
+ array2dir($pkg->custompriv, dirname(__FILE__) . "/../plugin_extradata/private/" . $this->get_id());
+ if(!empty($pkg->tpls))
+ array2dir($pkg->tpls, dirname(__FILE__) . "/../templates/srv/plugintemplates/" . $this->get_id());
+ }
+
+ /*
* Constructor: by_id
* Gets plugin by ID.
*
@@ -1234,25 +1265,26 @@ class Plugin
{
$obj = new self;
- $result = qdb("SELECT `name`, `author`, `versiontext`, `versioncount`, `short_description`, `updatepath`, `web`, `help`, `code`, `classname`, `active`, `license`, `installed` FROM `PREFIX_plugins` WHERE `id` = %d", $id);
+ $result = qdb("SELECT `name`, `author`, `versiontext`, `versioncount`, `short_description`, `updatepath`, `web`, `help`, `code`, `classname`, `active`, `license`, `installed`, `update` FROM `PREFIX_plugins` WHERE `id` = %d", $id);
$sqlrow = mysql_fetch_assoc($result);
if($sqlrow === False)
throw new DoesNotExistError();
- $this->id = $id;
- $this->name = $sqlrow["name"];
- $this->code = $sqlrow["code"];
- $this->classname = $sqlrow["classname"];
- $this->active = ($sqlrow["active"] == 1);
- $this->author = $sqlrow["author"];
- $this->versiontext = $sqlrow["versiontext"];
- $this->versioncount = $sqlrow["versioncount"];
- $this->short_description = $sqlrow["short_description"];
- $this->updatepath = $sqlrow["updatepath"];
- $this->web = $sqlrow["web"];
- $this->help = $sqlrow["help"];
- $this->license = $sqlrow["license"];
- $this->installed = ($sqlrow["installed"] == 1);
+ $obj->id = $id;
+ $obj->name = $sqlrow["name"];
+ $obj->code = $sqlrow["code"];
+ $obj->classname = $sqlrow["classname"];
+ $obj->active = ($sqlrow["active"] == 1);
+ $obj->author = $sqlrow["author"];
+ $obj->versiontext = $sqlrow["versiontext"];
+ $obj->versioncount = $sqlrow["versioncount"];
+ $obj->short_description = $sqlrow["short_description"];
+ $obj->updatepath = $sqlrow["updatepath"];
+ $obj->web = $sqlrow["web"];
+ $obj->help = $sqlrow["help"];
+ $obj->license = $sqlrow["license"];
+ $obj->installed = ($sqlrow["installed"] == 1);
+ $obj->update = ($sqlrow["update"] == 1);
return $obj;
}
@@ -1278,8 +1310,8 @@ class Plugin
*/
public function save()
{
- qdb("UPDATE `PREFIX_plugins` SET `name` = '%s', `code` = '%s', `classname` = '%s', `active` = %d, `versiontext` = '%s', `versioncount` = %d, `short_description` = '%s', `updatepath` = '%s', `web` = '%s', `help` = '%s', `installed` = %d, `license` = '%s' WHERE `id` = %d",
- $this->name, $this->code, $this->classname, ($this->active ? 1 : 0), $this->versiontext, $this->versioncount, $this->short_description, $this>updatepath, $this->web, $this->help, ($this->installed ? 1 : 0), $this->license, $this->id);
+ qdb("UPDATE `PREFIX_plugins` SET `name` = '%s', `author` = '%s', `code` = '%s', `classname` = '%s', `active` = %d, `versiontext` = '%s', `versioncount` = %d, `short_description` = '%s', `updatepath` = '%s', `web` = '%s', `help` = '%s', `installed` = %d, `update` = %d, `license` = '%s' WHERE `id` = %d",
+ $this->name, $this>author, $this->code, $this->classname, ($this->active ? 1 : 0), $this->versiontext, $this->versioncount, $this->short_description, $this->updatepath, $this->web, $this->help, ($this->installed ? 1 : 0), ($this->update ? 1 : 0), $this->license, $this->id);
}
/*
@@ -1288,6 +1320,7 @@ class Plugin
public function delete()
{
qdb("DELETE FROM `PREFIX_plugins` WHERE `id` = %d", $this->id);
+ qdb("DELETE FROM `PREFIX_plugin_kvstorage` WHERE `plugin` = %d", $this->id);
if(is_dir(SITE_BASE_PATH . "/ratatoeskr/plugin_extradata/private/" . $this->id))
delete_directory(SITE_BASE_PATH . "/ratatoeskr/plugin_extradata/private/" . $this->id);
if(is_dir(SITE_BASE_PATH . "/ratatoeskr/plugin_extradata/public/" . $this->id))
diff --git a/ratatoeskr/sys/plugin_api.php b/ratatoeskr/sys/plugin_api.php
index 362fd9e..f34a42a 100644
--- a/ratatoeskr/sys/plugin_api.php
+++ b/ratatoeskr/sys/plugin_api.php
@@ -15,7 +15,7 @@ require_once(dirname(__FILE__) . "/../frontend.php");
/*
* Constant: APIVERSION
- * The current API version.
+ * The current API version (1).
*/
define("APIVERSION", 1);
diff --git a/ratatoeskr/sys/pluginpackage.php b/ratatoeskr/sys/pluginpackage.php
index 0200c79..d8ce170 100644
--- a/ratatoeskr/sys/pluginpackage.php
+++ b/ratatoeskr/sys/pluginpackage.php
@@ -39,6 +39,29 @@ function dir2array($dir)
}
/*
+ * Function: array2dir
+ * Unpack an array into a directory.
+ *
+ * Parameters:
+ * $a - Array to unpack.
+ * $dir - Directory to unpack to.
+ */
+function array2dir($a, $dir)
+{
+ if(!is_dir($dir))
+ mkdir($dir);
+
+ foreach($a as $k => $v)
+ {
+ $k = "$dir/$k";
+ if(is_array($v))
+ array2dir($v, $k);
+ else
+ file_put_contents($k, $v);
+ }
+}
+
+/*
* Class: InvalidPackage
* An Exception that <PluginPackage>'s function can throw, if the package is invalid.
*/
@@ -99,7 +122,7 @@ class PluginPackage
*/
public function validate()
{
- function validate_url ($u) { return preg_match("/^http[s]{0,1}://.*$/", $u) != 0; }
+ function validate_url ($u) { return preg_match("/^http[s]{0,1}:\\/\\/.*$/", $u) != 0; }
function validate_arraydir($a)
{
if(!is_array($a))
@@ -177,7 +200,7 @@ class PluginPackage
throw new InvalidPackage("Wrong SHA1 hash");
$plugin = @unserialize($pluginser);
- if(!($plugin instanceof this))
+ if(!($plugin instanceof self))
throw new InvalidPackage("Not the correct class or not unserializeable.");
$plugin->validate();
@@ -198,8 +221,8 @@ class PluginPackage
public function save()
{
$this->validate();
- $ser = serialize($self);
- return this::$magic . sha1($ser, True) . gzcompress($ser, 9);
+ $ser = serialize($this);
+ return self::$magic . sha1($ser, True) . gzcompress($ser, 9);
}
/*
diff --git a/ratatoeskr/templates/src/systemtemplates/confirminstall.html b/ratatoeskr/templates/src/systemtemplates/confirminstall.html
new file mode 100644
index 0000000..fdd15af
--- /dev/null
+++ b/ratatoeskr/templates/src/systemtemplates/confirminstall.html
@@ -0,0 +1,26 @@
+<ste:load name="master.html" />
+<ste:block name="content">
+ <h2><ste:escape>$name</ste:escape></h2>
+
+ <ste:escape>$description</ste:escape>
+
+ <h3><ste:get_translation for="plugin_src" /></h3>
+ <code><pre><ste:escape>$code</ste:escape></pre></code>
+
+ <ste:if>
+ $license
+ <ste:then>
+ <h3><ste:get_translation for="license" /></h3>
+ <code><pre><ste:escape>$license</ste:escape></pre></code>
+ </ste:then>
+ </ste:if>
+
+ <h3><ste:get_translation for="really_install" /></h3>
+ <div class="notice">
+ <ste:get_translation for="plugin_safety_warning" raw="1" />
+ </div>
+ <form action="$rel_path_to_root/backend/plugin/confirminstall/$plugin_id" method="POST">
+ <input type="submit" name="yes" value="<ste:get_translation for='yes' />" />
+ <input type="submit" name="no" value="<ste:get_translation for='no' />" />
+ </form>
+</ste:block>
diff --git a/ratatoeskr/templates/src/systemtemplates/pluginhelp.html b/ratatoeskr/templates/src/systemtemplates/pluginhelp.html
new file mode 100644
index 0000000..c1e748a
--- /dev/null
+++ b/ratatoeskr/templates/src/systemtemplates/pluginhelp.html
@@ -0,0 +1,4 @@
+<ste:load name="master.html" />
+<ste:block name="content">
+ $help
+</ste:block>
diff --git a/ratatoeskr/templates/src/systemtemplates/plugininstall.html b/ratatoeskr/templates/src/systemtemplates/plugininstall.html
new file mode 100644
index 0000000..039feef
--- /dev/null
+++ b/ratatoeskr/templates/src/systemtemplates/plugininstall.html
@@ -0,0 +1,18 @@
+<ste:load name="master.html" />
+<ste:block name="content">
+ <ste:if>$success
+ <ste:then>
+ <div class="success"><ste:escape>$success</ste:escape></div>
+ </ste:then>
+ </ste:if>
+ <ste:if>$error
+ <ste:then>
+ <div class="error"><ste:escape>$error</ste:escape></div>
+ </ste:then>
+ </ste:if>
+
+ <h2><ste:get_translation for="install_from_package" /></h2>
+ <form action="$rel_path_to_root/backend/plugin/install" method="POST" accept-charset="UTF-8" enctype="multipart/form-data">
+ <input type="file" name="pluginpackage" /> <input type="submit" name="installpackage" />
+ </form>
+</ste:block>
diff --git a/ratatoeskr/templates/src/systemtemplates/pluginlist.html b/ratatoeskr/templates/src/systemtemplates/pluginlist.html
new file mode 100644
index 0000000..ea01335
--- /dev/null
+++ b/ratatoeskr/templates/src/systemtemplates/pluginlist.html
@@ -0,0 +1,66 @@
+<ste:load name="master.html" />
+<ste:block name="content">
+ <ste:if>$success
+ <ste:then>
+ <div class="success"><ste:escape>$success</ste:escape></div>
+ </ste:then>
+ </ste:if>
+ <ste:if>$error
+ <ste:then>
+ <div class="error"><ste:escape>$error</ste:escape></div>
+ </ste:then>
+ </ste:if>
+
+ <form action="$rel_path_to_root/backend/plugin/list" method="POST">
+ <table class="listtab fullwidth">
+ <thead>
+ <tr>
+ <th>&nbsp;</th>
+ <th><ste:get_translation for="plugin_name" /></th>
+ <th><ste:get_translation for="plugin_version" /></th>
+ <th><ste:get_translation for="plugin_isactive" /></th>
+ <th><ste:get_translation for="plugin_description" /></th>
+ <th><ste:get_translation for="plugin_author" /></th>
+ <th><ste:get_translation for="plugin_web" /></th>
+ <th><ste:get_translation for="plugin_help" /></th>
+ </tr>
+ </thead>
+ <tbody>
+ <ste:set var="plugins_n"><ste:arraylen array="plugins" /></ste:set>
+ <ste:if>
+ ~{$plugins_n|gt|0}
+ <ste:then>
+ <ste:foreach array="plugins" value="p">
+ <tr>
+ <td><input type="checkbox" name="plugins_multiselect[]" value="$p[id]" /></td>
+ <td><ste:escape>$p[name]</ste:escape></td>
+ <td><ste:escape>$p[versiontext]</ste:escape></td>
+ <td>?{$p[active]|<strong><ste:get_translation for="yes" />|<ste:get_translation for="no" />}</td>
+ <td><ste:escape>$p[description]</ste:escape></td>
+ <td><ste:escape>$p[author]</ste:escape></td>
+ <td>?{$p[web]|<a href="<ste:escape>$p[web]</ste:escape>"><ste:escape>$p[web]</ste:escape></a>|}</td>
+ <td>?{$p[help]|<a href="$rel_path_to_root/backend/plugin/help/$p[id]"><ste:get_translation for="plugin_help" /></a>|}</td>
+ </tr>
+ </ste:foreach>
+ </ste:then>
+ <ste:else>
+ <tr><td colspan="8" style="text-align: center;"><em><ste:get_translation for="no_plugins" /></em></td></tr>
+ </ste:else>
+ </ste:if>
+ </tbody>
+ </table>
+ <div>
+ <input type="submit" name="delete" value="<ste:get_translation for='delete' />" />
+ <select name="really_delete">
+ <option value="no" selected="selected"><ste:get_translation for="no" /></option>
+ <option value="yes"><ste:get_translation for="yes" /></option>
+ </select>
+ |
+ <input type="submit" name="update" value="<ste:get_translation for='plugin_update' />" />
+ |
+ <input type="submit" name="activate" value="<ste:get_translation for='plugin_activate' />" />
+ |
+ <input type="submit" name="deactivate" value="<ste:get_translation for='plugin_deactivate' />" />
+ </div>
+ </form>
+</ste:block>
diff --git a/ratatoeskr/translations/en.php b/ratatoeskr/translations/en.php
index 80b9806..fb96479 100644
--- a/ratatoeskr/translations/en.php
+++ b/ratatoeskr/translations/en.php
@@ -201,7 +201,30 @@ $translation = array(
"mail_address" => "Mail Address",
"new_password" => "New password",
"successfully_modified_user" => "Successfully modified user.",
- "successfully_set_new_password" => "Successfully set new password."
+ "successfully_set_new_password" => "Successfully set new password.",
+ "plugin_name" => "Name",
+ "plugin_version" => "Version",
+ "plugin_isactive" => "Active",
+ "plugin_description" => "Description",
+ "plugin_author" => "Author",
+ "plugin_web" => "Web",
+ "plugin_help" => "Help",
+ "plugin_update" => "Update",
+ "plugin_activate" => "Activate",
+ "plugin_deactivate" => "Deactivate",
+ "no_plugins" => "No plugins installed",
+ "install_from_package" => "Install from package",
+ "invalid_package" => "Invalid package",
+ "incompatible_plugin" => "This plugin is not comatible wit this version of Ratatöskr. It requires the API version [[API]] or a compatible one.",
+ "plugin_safety_warning" => "<strong>Never</strong> install plugins you do not trust! Plugins have a lot of power and could potentially destroy your Ratatöskr installation!",
+ "plugin_src" => "Source code",
+ "license" => "License",
+ "plugin_installed_successfully" => "Plugin successfully installed.",
+ "successfully_deleted_plugins" => "Successfully deleted plugins.",
+ "plugins_activated" => "Plugins activated.",
+ "plugins_deactivated" => "Plugins deactivated.",
+ "successfully_updated_plugins" => "These plugins were updated: [[PLUGINS]]",
+ "nothing_to_update" => "Nothing to update."
);
?>