aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Chabowski <kevin@kch42.de>2012-05-20 13:00:31 +0200
committerKevin Chabowski <kevin@kch42.de>2012-05-20 13:00:31 +0200
commit793b0e31beb22fe33402c8a9ceebf47a5a950635 (patch)
treee85697db943d0aa4b32821125324fbd1ba557616
parent1bfb9653d6e9139445ca9cde5808228c3b16399e (diff)
downloadratatoeskr-cms-feature-plugin-articledata.tar.gz
ratatoeskr-cms-feature-plugin-articledata.tar.bz2
ratatoeskr-cms-feature-plugin-articledata.zip
Plugins can now hook into the Article editor.feature-plugin-articledata
* Plugins can display additional fields in the article editor. * Plugins can perform actions when saving an article and even veto the saving. * Plugins can get their ArticleExtradata objects.
-rw-r--r--ratatoeskr/backend.php79
-rw-r--r--ratatoeskr/frontend.php15
-rw-r--r--ratatoeskr/sys/models.php15
-rw-r--r--ratatoeskr/sys/plugin_api.php55
-rw-r--r--ratatoeskr/templates/src/systemtemplates/content_write.html5
5 files changed, 142 insertions, 27 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/sys/models.php b/ratatoeskr/sys/models.php
index 9f3a96a..3cda168 100644
--- a/ratatoeskr/sys/models.php
+++ b/ratatoeskr/sys/models.php
@@ -2606,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()
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">