aboutsummaryrefslogtreecommitdiff
path: root/ratatoeskr
diff options
context:
space:
mode:
authorKevin Chabowski <kevin@kch42.de>2012-05-20 14:08:34 +0200
committerKevin Chabowski <kevin@kch42.de>2012-05-20 14:08:34 +0200
commit0915d74865b0cab61c3a505e802b80ac048cdd3f (patch)
tree5d914d22078ded1b65e60517326b8aa1911ca508 /ratatoeskr
parent40cafe0ca0699647781e8953b413622b8e341913 (diff)
parent793b0e31beb22fe33402c8a9ceebf47a5a950635 (diff)
downloadratatoeskr-cms-0915d74865b0cab61c3a505e802b80ac048cdd3f.tar.gz
ratatoeskr-cms-0915d74865b0cab61c3a505e802b80ac048cdd3f.tar.bz2
ratatoeskr-cms-0915d74865b0cab61c3a505e802b80ac048cdd3f.zip
Merge branch 'feature-plugin-articledata' into develop
Diffstat (limited to 'ratatoeskr')
-rw-r--r--ratatoeskr/backend.php79
-rw-r--r--ratatoeskr/frontend.php15
-rw-r--r--ratatoeskr/setup/create_tables.php49
-rw-r--r--ratatoeskr/sys/models.php221
-rw-r--r--ratatoeskr/sys/plugin_api.php55
-rw-r--r--ratatoeskr/templates/src/systemtemplates/content_write.html5
6 files changed, 322 insertions, 102 deletions
diff --git a/ratatoeskr/backend.php b/ratatoeskr/backend.php
index 19d3891..a1ab570 100644
--- a/ratatoeskr/backend.php
+++ b/ratatoeskr/backend.php
@@ -12,6 +12,7 @@
require_once(dirname(__FILE__) . "/sys/models.php");
require_once(dirname(__FILE__) . "/sys/pwhash.php");
require_once(dirname(__FILE__) . "/sys/textprocessors.php");
+require_once(dirname(__FILE__) . "/sys/plugin_api.php");
require_once(dirname(__FILE__) . "/languages.php");
$admin_grp = NULL;
@@ -116,6 +117,7 @@ $backend_subactions = url_action_subactions(array(
}
}
load_language();
+
/* If we are here, user is not logged in... */
$url_next = array("login");
},
@@ -159,7 +161,7 @@ $backend_subactions = url_action_subactions(array(
"content" => url_action_subactions(array(
"write" => function(&$data, $url_now, &$url_next)
{
- global $ste, $translation, $textprocessors, $ratatoeskr_settings, $languages;
+ global $ste, $translation, $textprocessors, $ratatoeskr_settings, $languages, $articleeditor_plugins;
list($article, $editlang) = array_slice($url_next, 0);
if(!isset($editlang))
@@ -234,14 +236,21 @@ $backend_subactions = url_action_subactions(array(
if(isset($_POST["saveaslang"]))
$editlang = $_POST["saveaslang"];
}
+ else
+ {
+ /* Call articleeditor plugins */
+ $article = empty($article) ? NULL : Article::by_urlname($article);
+ foreach($articleeditor_plugins as $plugin)
+ call_user_func($plugin["fx"], $article, False);
+ }
function fill_article(&$article, $inputs, $editlang)
{
$article->urlname = $inputs["urlname"];
$article->status = $inputs["article_status"];
$article->timestamp = $inputs["date"];
- $article->title [$editlang] = new Translation($inputs["title"], "" );
- $article->text [$editlang] = new Translation($inputs["content"], $inputs["content_txtproc"]);
+ $article->title[$editlang] = new Translation($inputs["title"], "");
+ $article->text[$editlang] = new Translation($inputs["content"], $inputs["content_txtproc"]);
$article->excerpt[$editlang] = new Translation($inputs["excerpt"], $inputs["excerpt_txtproc"]);
$article->set_tags(maketags($inputs["tags"], $editlang));
$article->set_section($inputs["article_section"]);
@@ -256,15 +265,32 @@ $backend_subactions = url_action_subactions(array(
{
$article = Article::create($inputs["urlname"]);
fill_article($article, $inputs, $editlang);
- try
+
+ /* Calling articleeditor plugins */
+ $call_after_save = array();
+ foreach($articleeditor_plugins as $plugin)
{
- $article->save();
- $ste->vars["article_editurl"] = urlencode($article->urlname) . "/" . urlencode($editlang);
- $ste->vars["success"] = htmlesc($translation["article_save_success"]);
+ $result = call_user_func($plugin["fx"], $article, True);
+ if(is_string($result))
+ $fail_reasons[] = $result;
+ elseif($result !== NULL)
+ $call_after_save[] = $result;
}
- catch(AlreadyExistsError $e)
+
+ if(empty($fail_reasons))
{
- $fail_reasons[] = $translation["article_name_already_in_use"];
+ try
+ {
+ $article->save();
+ foreach($call_after_save as $cb)
+ call_user_func($cb, $article);
+ $ste->vars["article_editurl"] = urlencode($article->urlname) . "/" . urlencode($editlang);
+ $ste->vars["success"] = htmlesc($translation["article_save_success"]);
+ }
+ catch(AlreadyExistsError $e)
+ {
+ $fail_reasons[] = $translation["article_name_already_in_use"];
+ }
}
}
}
@@ -272,7 +298,8 @@ $backend_subactions = url_action_subactions(array(
{
try
{
- $article = Article::by_urlname($article);
+ if(!($article instanceof Article))
+ $article = Article::by_urlname($article);
}
catch(DoesNotExistError $e)
{
@@ -282,15 +309,32 @@ $backend_subactions = url_action_subactions(array(
if(empty($fail_reasons) and isset($_POST["save_article"]))
{
fill_article($article, $inputs, $editlang);
- try
+
+ /* Calling articleeditor plugins */
+ $call_after_save = array();
+ foreach($articleeditor_plugins as $plugin)
{
- $article->save();
- $ste->vars["article_editurl"] = urlencode($article->urlname) . "/" . urlencode($editlang);
- $ste->vars["success"] = htmlesc($translation["article_save_success"]);
+ $result = call_user_func($plugin["fx"], $article, True);
+ if(is_string($result))
+ $fail_reasons[] = $result;
+ elseif($result !== NULL)
+ $call_after_save[] = $result;
}
- catch(AlreadyExistsError $e)
+
+ if(empty($fail_reasons))
{
- $fail_reasons[] = $translation["article_name_already_in_use"];
+ try
+ {
+ $article->save();
+ foreach($call_after_save as $cb)
+ call_user_func($cb, $article);
+ $ste->vars["article_editurl"] = urlencode($article->urlname) . "/" . urlencode($editlang);
+ $ste->vars["success"] = htmlesc($translation["article_save_success"]);
+ }
+ catch(AlreadyExistsError $e)
+ {
+ $fail_reasons[] = $translation["article_name_already_in_use"];
+ }
}
}
@@ -366,6 +410,9 @@ $backend_subactions = url_action_subactions(array(
$ste->vars[$k_out] = $inputs[$k_in];
}
+ /* Displaying article editor plugins */
+ $ste->vars["displayed_plugins"] = array_map(function($x) { return array("label" => $x["label"], "template" => $x["template"]); }, array_filter($articleeditor_plugins, function($x) { return $x["display"]; }));
+
if(!empty($fail_reasons))
$ste->vars["failed"] = $fail_reasons;
diff --git a/ratatoeskr/frontend.php b/ratatoeskr/frontend.php
index 883f842..0bc083b 100644
--- a/ratatoeskr/frontend.php
+++ b/ratatoeskr/frontend.php
@@ -25,9 +25,10 @@ require_once(dirname(__FILE__) . "/libs/kses.php");
*
* Returns:
* Array with these fields:
- * * id
- * * name
- * * title
+ * * id - The ID of the section.
+ * * name - The name of the section.
+ * * title - The title of the section in the current language
+ * * __obj - The <Section> object. Useful for plugins, so they do not need to fetch the object from the database again.
*/
function section_transform_ste($section, $lang)
{
@@ -49,9 +50,10 @@ function section_transform_ste($section, $lang)
*
* Returns:
* Array with these fields:
- * * id
- * * name
- * * title
+ * * id - The ID of the tag.
+ * * name - The name of the tag.
+ * * title - The title in the current language.
+ * * __obj - The <Tag> object. Useful for plugins, so they do not need to fetch the object from the database again.
*/
function tag_transform_ste($tag, $lang)
{
@@ -93,6 +95,7 @@ function tag_transform_ste($tag, $lang)
* * tags (array(sub-fields: <tag_transform_ste>))
* * languages (array: language name=>url)
* * comments_allowed
+ * * __obj - Useful for plugins, so they do not need to fetch the object from the database again.
*/
function article_transform_ste($article, $lang)
{
diff --git a/ratatoeskr/setup/create_tables.php b/ratatoeskr/setup/create_tables.php
index 819970a..97a4cd5 100644
--- a/ratatoeskr/setup/create_tables.php
+++ b/ratatoeskr/setup/create_tables.php
@@ -20,12 +20,12 @@ CREATE TABLE IF NOT EXISTS `PREFIX_articles` (
`timestamp` bigint(20) NOT NULL,
`allow_comments` int(11) NOT NULL,
PRIMARY KEY (`id`)
-) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+) DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE IF NOT EXISTS `PREFIX_article_tag_relations` (
`tag` int(11) NOT NULL,
`article` int(11) NOT NULL
-) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+) DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE IF NOT EXISTS `PREFIX_comments` (
`id` int(11) NOT NULL AUTO_INCREMENT,
@@ -38,30 +38,30 @@ CREATE TABLE IF NOT EXISTS `PREFIX_comments` (
`visible` tinyint(4) NOT NULL,
`read_by_admin` tinyint(4) NOT NULL,
PRIMARY KEY (`id`)
-) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+) DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE IF NOT EXISTS `PREFIX_groups` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` text COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (`id`)
-) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+) DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE IF NOT EXISTS `PREFIX_group_members` (
`user` int(11) NOT NULL,
`group` int(11) NOT NULL
-) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+) DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE IF NOT EXISTS `PREFIX_images` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` text COLLATE utf8_unicode_ci NOT NULL,
`file` text COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (`id`)
-) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+) DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE IF NOT EXISTS `PREFIX_multilingual` (
`id` int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
-) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+) DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE IF NOT EXISTS `PREFIX_plugins` (
`id` int(11) NOT NULL AUTO_INCREMENT,
@@ -82,13 +82,13 @@ CREATE TABLE IF NOT EXISTS `PREFIX_plugins` (
`update` tinyint(4) NOT NULL,
`api` int(11) NOT NULL,
PRIMARY KEY (`id`)
-) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+) DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE IF NOT EXISTS `PREFIX_plugin_kvstorage` (
`plugin` int(11) NOT NULL,
`key` text COLLATE utf8_unicode_ci NOT NULL,
`value` text COLLATE utf8_unicode_ci NOT NULL
-) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+) DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE IF NOT EXISTS `PREFIX_repositories` (
`id` int(11) NOT NULL AUTO_INCREMENT,
@@ -98,7 +98,7 @@ CREATE TABLE IF NOT EXISTS `PREFIX_repositories` (
`pkgcache` text COLLATE utf8_unicode_ci NOT NULL,
`lastrefresh` bigint(20) NOT NULL,
PRIMARY KEY (`id`)
-) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+) DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE IF NOT EXISTS `PREFIX_sections` (
`id` int(11) NOT NULL AUTO_INCREMENT,
@@ -107,38 +107,38 @@ CREATE TABLE IF NOT EXISTS `PREFIX_sections` (
`template` text COLLATE utf8_unicode_ci NOT NULL,
`styles` text COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (`id`)
-) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+) DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE IF NOT EXISTS `PREFIX_section_style_relations` (
`section` int(11) NOT NULL,
`style` int(11) NOT NULL
-) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+) DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE IF NOT EXISTS `PREFIX_settings_kvstorage` (
`key` text COLLATE utf8_unicode_ci NOT NULL,
`value` text COLLATE utf8_unicode_ci NOT NULL
-) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+) DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE IF NOT EXISTS `PREFIX_styles` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` text COLLATE utf8_unicode_ci NOT NULL,
`code` text COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (`id`)
-) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+) DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE IF NOT EXISTS `PREFIX_tags` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` text COLLATE utf8_unicode_ci NOT NULL,
`title` int(11) NOT NULL,
PRIMARY KEY (`id`)
-) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+) DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE IF NOT EXISTS `PREFIX_translations` (
`multilingual` int(11) NOT NULL,
`language` varchar(10) COLLATE utf8_unicode_ci NOT NULL,
`text` text COLLATE utf8_unicode_ci NOT NULL,
`texttype` text COLLATE utf8_unicode_ci NOT NULL
-) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+) DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE IF NOT EXISTS `PREFIX_users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
@@ -148,7 +148,20 @@ CREATE TABLE IF NOT EXISTS `PREFIX_users` (
`fullname` text COLLATE utf8_unicode_ci NOT NULL,
`language` varchar(10) COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (`id`)
-) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+) DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+
+CREATE TABLE IF NOT EXISTS `PREFIX_meta` (
+ `key` text COLLATE utf8_unicode_ci NOT NULL,
+ `value` text COLLATE utf8_unicode_ci NOT NULL
+) DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+
+
+CREATE TABLE IF NOT EXISTS `PREFIX_article_extradata` (
+ `article` int(11) NOT NULL,
+ `plugin` int(11) NOT NULL,
+ `key` text COLLATE utf8_unicode_ci NOT NULL,
+ `value` text COLLATE utf8_unicode_ci NOT NULL
+) DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
SQL;
function create_mysql_tables()
@@ -161,6 +174,8 @@ function create_mysql_tables()
if(!empty($q))
qdb($q);
}
+
+ qdb("INSERT INTO `PREFIX_meta` (`key`, `value`) VALUES ('dbversion', '%s')", base64_encode(serialize(1)));
}
?>
diff --git a/ratatoeskr/sys/models.php b/ratatoeskr/sys/models.php
index fe80ce4..3cda168 100644
--- a/ratatoeskr/sys/models.php
+++ b/ratatoeskr/sys/models.php
@@ -89,6 +89,101 @@ abstract class BySQLRowEnabled
}
/*
+ * Class: KVStorage
+ * An abstract class for a KVStorage.
+ *
+ * See also:
+ * <PluginKVStorage>, <ArticleExtradata>
+ */
+abstract class KVStorage implements Countable, ArrayAccess, Iterator
+{
+ private $keybuffer;
+ private $counter;
+ private $prepared_queries;
+ private $silent_mode;
+
+ final protected function init($sqltable, $common_fields)
+ {
+ $this->silent_mode = False;
+ $this->keybuffer = array();
+
+ $selector = "WHERE " . (empty($common_fields) ? 1 : implode(" AND ", array_map(function($x) { return qdb_fmt("`{$x[0]}` = {$x[1]}", $x[2]); }, $common_fields)));
+ $this->prepared_queries = array(
+ "get" => "SELECT `value` FROM `$sqltable` $selector AND `key` = '%s'",
+ "unset" => "DELETE FROM `$sqltable` $selector AND `key` = '%s'",
+ "update" => "UPDATE `$sqltable` SET `value` = '%s' $selector AND `key` = '%s'",
+ "create" => "INSERT INTO `$sqltable` (`key`, `value` "
+ . (empty($common_fields) ?: ", " . implode(", ", array_map(function($x) { return "`".$x[0]."`"; }, $common_fields)))
+ . ") VALUES ('%s', '%s'"
+ . (empty($common_fields) ?: ", " . implode(", ", array_map(function($x) { return qdb_fmt($x[1], $x[2]); }, $common_fields)))
+ . ")"
+ );
+
+ $result = qdb("SELECT `key` FROM `$sqltable` $selector");
+ while($sqlrow = mysql_fetch_assoc($result))
+ $this->keybuffer[] = $sqlrow["key"];
+
+ $this->counter = 0;
+ }
+
+ /*
+ * Functions: Silent mode
+ * If the silent mode is enabled, the KVStorage behaves even more like a PHP array, i.e. it just returns NULL,
+ * if a unknown key was requested and does not throw an DoesNotExistError Exception.
+ *
+ * enable_silent_mode - Enable the silent mode.
+ * disable_silent_mode - Disable the silent mode (default).
+ */
+ final public function enable_silent_mode() { $this->silent_mode = True; }
+ final public function disable_silent_mode() { $this->silent_mode = False; }
+
+ /* Countable interface implementation */
+ final public function count() { return count($this->keybuffer); }
+
+ /* ArrayAccess interface implementation */
+ final public function offsetExists($offset) { return in_array($offset, $this->keybuffer); }
+ final public function offsetGet($offset)
+ {
+ if($this->offsetExists($offset))
+ {
+ $result = qdb($this->prepared_queries["get"], $offset);
+ $sqlrow = mysql_fetch_assoc($result);
+ return unserialize(base64_decode($sqlrow["value"]));
+ }
+ elseif($this->silent_mode)
+ return NULL;
+ else
+ throw new DoesNotExistError();
+ }
+ final public function offsetUnset($offset)
+ {
+ if($this->offsetExists($offset))
+ {
+ unset($this->keybuffer[array_search($offset, $this->keybuffer)]);
+ $this->keybuffer = array_merge($this->keybuffer);
+ qdb($this->prepared_queries["unset"], $offset);
+ }
+ }
+ final public function offsetSet($offset, $value)
+ {
+ if($this->offsetExists($offset))
+ qdb($this->prepared_queries["update"], base64_encode(serialize($value)), $offset);
+ else
+ {
+ qdb($this->prepared_queries["create"], $offset, base64_encode(serialize($value)));
+ $this->keybuffer[] = $offset;
+ }
+ }
+
+ /* Iterator interface implementation */
+ final public function rewind() { return $this->counter = 0; }
+ final public function current() { return $this->offsetGet($this->keybuffer[$this->counter]); }
+ final public function key() { return $this->keybuffer[$this->counter]; }
+ final public function next() { ++$this->counter; }
+ final public function valid() { return isset($this->keybuffer[$this->counter]); }
+}
+
+/*
* Class: User
* Data model for Users
*/
@@ -771,13 +866,11 @@ $ratatoeskr_settings = Settings::get_instance();
* A Key-Value-Storage for Plugins
* Can be accessed like an array.
* Keys are strings and Values can be everything serialize() can process.
+ *
+ * Extends the abstract <KVStorage> class.
*/
-class PluginKVStorage implements Countable, ArrayAccess, Iterator
+class PluginKVStorage extends KVStorage
{
- private $plugin_id;
- private $keybuffer;
- private $counter;
-
/*
* Constructor: __construct
*
@@ -786,60 +879,10 @@ class PluginKVStorage implements Countable, ArrayAccess, Iterator
*/
public function __construct($plugin_id)
{
- $this->keybuffer = array();
- $this->plugin_id = $plugin_id;
-
- $result = qdb("SELECT `key` FROM `PREFIX_plugin_kvstorage` WHERE `plugin` = %d", $plugin_id);
- while($sqlrow = mysql_fetch_assoc($result))
- $this->keybuffer[] = $sqlrow["key"];
-
- $this->counter = 0;
- }
-
- /* Countable interface implementation */
- public function count() { return count($this->keybuffer); }
-
- /* ArrayAccess interface implementation */
- public function offsetExists($offset) { return in_array($offset, $this->keybuffer); }
- public function offsetGet($offset)
- {
- if($this->offsetExists($offset))
- {
- $result = qdb("SELECT `value` FROM `PREFIX_plugin_kvstorage` WHERE `key` = '%s' AND `plugin` = %d", $offset, $this->plugin_id);
- $sqlrow = mysql_fetch_assoc($result);
- return unserialize(base64_decode($sqlrow["value"]));
- }
- else
- throw new DoesNotExistError();
- }
- public function offsetUnset($offset)
- {
- if($this->offsetExists($offset))
- {
- unset($this->keybuffer[array_search($offset, $this->keybuffer)]);
- $this->keybuffer = array_merge($this->keybuffer);
- qdb("DELETE FROM `PREFIX_plugin_kvstorage` WHERE `key` = '%s' AND `plugin` = %d", $offset, $this->plugin_id);
- }
- }
- public function offsetSet($offset, $value)
- {
- if($this->offsetExists($offset))
- qdb("UPDATE `PREFIX_plugin_kvstorage` SET `value` = '%s' WHERE `key` = '%s' AND `plugin` = %d",
- base64_encode(serialize($value)), $offset, $this->plugin_id);
- else
- {
- qdb("INSERT INTO `PREFIX_plugin_kvstorage` (`plugin`, `key`, `value`) VALUES (%d, '%s', '%s')",
- $this->plugin_id, $offset, base64_encode(serialize($value)));
- $this->keybuffer[] = $offset;
- }
+ $this->init("PREFIX_plugin_kvstorage", array(
+ array("plugin", "%d", $plugin_id)
+ ));
}
-
- /* Iterator interface implementation */
- function rewind() { return $this->position = 0; }
- function current() { return $this->offsetGet($this->keybuffer[$this->position]); }
- function key() { return $this->keybuffer[$this->position]; }
- function next() { ++$this->position; }
- function valid() { return isset($this->keybuffer[$this->position]); }
}
/*
@@ -1372,6 +1415,7 @@ class Plugin extends BySQLRowEnabled
{
qdb("DELETE FROM `PREFIX_plugins` WHERE `id` = %d", $this->id);
qdb("DELETE FROM `PREFIX_plugin_kvstorage` WHERE `plugin` = %d", $this->id);
+ qdb("DELETE FROM `PREFIX_article_extradata` 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))
@@ -2562,6 +2606,21 @@ WHERE " . implode(" AND ", $subqueries) . " $sorting");
}
/*
+ * Function: get_extradata
+ * Get the extradata for this article and the given plugin.
+ *
+ * Parameters:
+ * $plugin_id - The ID of the plugin.
+ *
+ * Returns:
+ * An <ArticleExtradata> object.
+ */
+ public function get_extradata($plugin_id)
+ {
+ return new ArticleExtradata($this->id, $plugin_id);
+ }
+
+ /*
* Function: save
*/
public function save()
@@ -2604,11 +2663,57 @@ WHERE " . implode(" AND ", $subqueries) . " $sorting");
$comment->delete();
qdb("DELETE FROM `PREFIX_article_tag_relations` WHERE `article` = %d", $this->id);
+ qdb("DELETE FROM `PREFIX_article_extradata` WHERE `article` = %d", $this->id);
qdb("DELETE FROM `PREFIX_articles` WHERE `id` = %d", $this->id);
}
}
/*
+ * Class: ArticleExtradata
+ * A Key-Value-Storage assigned to Articles for plugins to store additional data.
+ * Can be accessed like an array.
+ * Keys are strings and Values can be everything serialize() can process.
+ *
+ * Extends the abstract <KVStorage> class.
+ */
+class ArticleExtradata extends KVStorage
+{
+ /*
+ * Constructor: __construct
+ *
+ * Parameters:
+ * $article_id - The ID of the Article.
+ * $plugin_id - The ID of the Plugin.
+ */
+ public function __construct($article_id, $plugin_id)
+ {
+ $this->init("PREFIX_article_extradata", array(
+ array("article", "%d", $article_id),
+ array("plugin", "%d", $plugin_id)
+ ));
+ }
+}
+
+/*
+ * Function: dbversion
+ * Get the version of the database structure currently used.
+ *
+ * Returns:
+ * The numerical version of the current database structure.
+ */
+function dbversion()
+{
+ /* Is the meta table present? If no, the version is 0. */
+ $result = qdb("SHOW TABLES LIKE 'PREFIX_meta'");
+ if(mysql_num_rows($result) == 0)
+ return 0;
+
+ $result = qdb("SELECT `value` FROM `PREFIX_meta` WHERE `key` = 'dbversion'");
+ $sqlrow = mysql_fetch_assoc($result);
+ return unserialize(base64_decode($sqlrow["value"]));
+}
+
+/*
* Function: clean_database
* Clean up the database
*/
diff --git a/ratatoeskr/sys/plugin_api.php b/ratatoeskr/sys/plugin_api.php
index f6d1c2d..cd3e42b 100644
--- a/ratatoeskr/sys/plugin_api.php
+++ b/ratatoeskr/sys/plugin_api.php
@@ -15,17 +15,18 @@ require_once(dirname(__FILE__) . "/../frontend.php");
/*
* Constant: APIVERSION
- * The current API version (5).
+ * The current API version (6).
*/
-define("APIVERSION", 5);
+define("APIVERSION", 6);
/*
* Array: $api_compat
* Array of API versions, this version is compatible to (including itself).
*/
-$api_compat = array(3, 4, 5);
+$api_compat = array(3, 4, 5, 6);
+
+$url_handlers = array(); /* master URL handler */
-$url_handlers = array();
/*
* Function: register_url_handler
* Register an URL handler. See <ratatoeskr/sys/urlprocess.php> for more details.
@@ -42,6 +43,8 @@ function register_url_handler($name, $callback)
$pluginpages_handlers = array();
+$articleeditor_plugins = array();
+
/*
* Class: RatatoeskrPlugin
* An abstract class to be extended in order to write your own Plugin.
@@ -93,7 +96,7 @@ abstract class RatatoeskrPlugin
final protected function get_custompub_dir() { return SITE_BASE_PATH . "/ratatoeskr/plugin_extradata/public/" . $this->id; }
final protected function get_custompub_url() { return $GLOBALS["rel_path_to_root"] . "/ratatoeskr/plugin_extradata/public/" . $this->id; }
final protected function get_template_dir() { return "/plugintemplates/" . $this->id; }
-
+
/*
* Function: register_url_handler
* Register a URL handler
@@ -194,6 +197,33 @@ abstract class RatatoeskrPlugin
}
/*
+ * Function: register_articleeditor_plugin
+ * Register a plugin for the article editor in the backend.
+ *
+ * Parameters:
+ * $label - The label for the plugin.
+ * $fx - A function that will be called during the articleeditor.
+ * This function must accept these parameters:
+ * * $article - An <Article> object or NULL, if no Article is edited right now.
+ * * $about_to_save - If True, the article is about to be saved.
+ * If you want to veto the saving, return the rejection reason as a string.
+ * If everything is okay and you need to save additional data, return a callback function that accepts the saved <Article> object (that callback should also write data back to the template, if necessary).
+ * If everything is okay and you do not need to save additional data, return NULL.
+ * $template - The name of the template to display in the editor, relative to your template directory. If you do not want to display anything, you can set ths to NULL.
+ */
+ final protected function register_articleeditor_plugin($label, $fx, $template)
+ {
+ global $articleeditor_plugins;
+
+ $articleeditor_plugins[] = array(
+ "label" => $label,
+ "fx" => $fx,
+ "template" => $this->get_template_dir() . "/" . $template,
+ "display" => $template != NULL
+ );
+ }
+
+ /*
* Function: get_backend_pluginpage_url
* Get the URL to your backend plugin page.
*
@@ -207,6 +237,21 @@ abstract class RatatoeskrPlugin
}
/*
+ * Function: get_article_extradata
+ * Get the <ArticleExtradata> object for this plugin and the given article.
+ *
+ * Parameters:
+ * $article - An <Article> object.
+ *
+ * Returns:
+ * An <ArticleExtradata> object for this plugin and the given article.
+ */
+ final protected function get_article_extradata($article)
+ {
+ return new ArticleExtradata($article->get_id(), $this->id);
+ }
+
+ /*
* Function: prepare_backend_pluginpage
* Automatically sets the page title and highlights the menu-entry of your backend subpage.
*/
diff --git a/ratatoeskr/templates/src/systemtemplates/content_write.html b/ratatoeskr/templates/src/systemtemplates/content_write.html
index 82c86c4..3d63c61 100644
--- a/ratatoeskr/templates/src/systemtemplates/content_write.html
+++ b/ratatoeskr/templates/src/systemtemplates/content_write.html
@@ -49,6 +49,11 @@
</select>
</p>
<p><ste:get_translation for="allow_comments" />: <input type="checkbox" name="allow_comments" value="yes" ?{$allow_comments|checked="checked" |}/></p>
+
+ <ste:foreach array="displayed_plugins" value="plugin">
+ <h2><ste:escape>$plugin[label]</ste:escape></h2>
+ <ste:load name="$plugin[template]" />
+ </ste:foreach>
</div>
<div class="column_main">