aboutsummaryrefslogtreecommitdiff
path: root/ratatoeskr/backend.php
diff options
context:
space:
mode:
authorLaria Carolin Chabowski <laria@laria.me>2020-04-26 16:33:36 +0200
committerLaria Carolin Chabowski <laria@laria.me>2020-04-26 16:33:36 +0200
commit82d40e32363c4e96996eca7ee44ade879589aa0e (patch)
tree44c819d2472697de1e8eb404148f4a087109b27e /ratatoeskr/backend.php
parent11c7214cb58be4100422b8f905bc629a8906e6ff (diff)
downloadratatoeskr-cms-82d40e32363c4e96996eca7ee44ade879589aa0e.tar.gz
ratatoeskr-cms-82d40e32363c4e96996eca7ee44ade879589aa0e.tar.bz2
ratatoeskr-cms-82d40e32363c4e96996eca7ee44ade879589aa0e.zip
Expand tabs and remove trailing whitespace
Diffstat (limited to 'ratatoeskr/backend.php')
-rw-r--r--ratatoeskr/backend.php3938
1 files changed, 1969 insertions, 1969 deletions
diff --git a/ratatoeskr/backend.php b/ratatoeskr/backend.php
index 326d82c..a5d5155 100644
--- a/ratatoeskr/backend.php
+++ b/ratatoeskr/backend.php
@@ -2,7 +2,7 @@
/*
* File: ratatoeskr/backend.php
* The backend.
- *
+ *
* License:
* This file is part of Ratatöskr.
* Ratatöskr is licensed unter the MIT / X11 License.
@@ -20,23 +20,23 @@ $admin_grp = NULL;
/* Mass creation of tags. */
function maketags($tagnames, $lang)
{
- $rv = array();
- foreach($tagnames as $tagname)
- {
- if(empty($tagname))
- continue;
- try
- {
- $tag = Tag::by_name($tagname);
- }
- catch(DoesNotExistError $e)
- {
- $tag = Tag::create($tagname);
- $tag->title[$lang] = new Translation($tagname, "");
- }
- $rv[] = $tag;
- }
- return $rv;
+ $rv = array();
+ foreach($tagnames as $tagname)
+ {
+ if(empty($tagname))
+ continue;
+ try
+ {
+ $tag = Tag::by_name($tagname);
+ }
+ catch(DoesNotExistError $e)
+ {
+ $tag = Tag::create($tagname);
+ $tag->title[$lang] = new Translation($tagname, "");
+ }
+ $rv[] = $tag;
+ }
+ return $rv;
}
$backend_subactions = NULL;
@@ -46,1957 +46,1957 @@ function build_backend_subactions()
global $backend_subactions, $pluginpages_handlers;
$backend_subactions = url_action_subactions(array(
- "_index" => url_action_alias(array("login")),
- "index" => url_action_alias(array("login")),
- /* _prelude guarantees that the user is logged in properly, so we do not have to care about that later, and sets some STE vars. */
- "_prelude" => function(&$data, $url_now, &$url_next)
- {
- global $ratatoeskr_settings, $admin_grp, $ste, $languages;
-
- if($admin_grp === NULL)
- $admin_grp = Group::by_name("admins");
-
- $ste->vars["all_languages"] = array();
- $ste->vars["all_langcodes"] = array();
- foreach($languages as $code => $data)
- {
- $ste->vars["all_languages"][$code] = $data["language"];
- $ste->vars["all_langcodes"][] = $code;
- }
- ksort($ste->vars["all_languages"]);
- sort($ste->vars["all_langcodes"]);
-
-
- /* Check authentification */
- if(isset($_SESSION["ratatoeskr_uid"]))
- {
- try
- {
- $user = User::by_id($_SESSION["ratatoeskr_uid"]);
- if(($user->pwhash == $_SESSION["ratatoeskr_pwhash"]) and $user->member_of($admin_grp))
- {
- if(empty($user->language))
- {
- $user->language = $ratatoeskr_settings["default_language"];
- $user->save();
- }
- load_language($user->language);
-
- if($url_next[0] == "login")
- $url_next = array("content", "write");
- $data["user"] = $user;
- $ste->vars["user"] = array("id" => $user->get_id(), "name" => $user->username, "lang" => $user->language);
-
- return; /* Authentification successful, continue */
- }
- else
- unset($_SESSION["ratatoeskr_uid"]);
- }
- catch(DoesNotExistError $e)
- {
- unset($_SESSION["ratatoeskr_uid"]);
- }
- }
- load_language();
-
- /* If we are here, user is not logged in... */
- $url_next = array("login");
- },
- "login" => url_action_simple(function($data)
- {
- global $ste, $admin_grp;
- if(!empty($_POST["user"]))
- {
- try
- {
- $user = User::by_name($_POST["user"]);
- if(!PasswordHash::validate($_POST["password"], $user->pwhash))
- throw new Exception();
- if(!$user->member_of($admin_grp))
- throw new Exception();
-
- /* Login successful. */
- $_SESSION["ratatoeskr_uid"] = $user->get_id();
- $_SESSION["ratatoeskr_pwhash"] = $user->pwhash;
- load_language($user->language);
- $data["user"] = $user;
- $ste->vars["user"] = array("id" => $user->get_id(), "name" => $user->username, "lang" => $user->language);
- }
- catch(Exception $e)
- {
- $ste->vars["login_failed"] = True;
- }
-
- if(isset($data["user"]))
- throw new Redirect(array("content", "write"));
- }
-
- echo $ste->exectemplate("/systemtemplates/backend_login.html");
- }),
- "logout" => url_action_simple(function($data)
- {
- unset($_SESSION["ratatoeskr_uid"]);
- unset($_SESSION["ratatoeskr_pwhash"]);
- load_language();
- throw new Redirect(array("login"));
- }),
- "content" => url_action_subactions(array(
- "write" => function(&$data, $url_now, &$url_next)
- {
- global $ste, $translation, $textprocessors, $ratatoeskr_settings, $languages, $articleeditor_plugins;
-
- list($article, $editlang) = array_slice($url_next, 0);
- if(!isset($editlang))
- $editlang = $data["user"]->language;
- if(isset($article))
- $ste->vars["article_editurl"] = urlencode($article) . "/" . urlencode($editlang);
- else
- $ste->vars["article_editurl"] = "";
-
- $url_next = array();
-
- $default_section = Section::by_id($ratatoeskr_settings["default_section"]);
-
- $ste->vars["section"] = "content";
- $ste->vars["submenu"] = isset($article) ? "articles" : "newarticle";
-
- $ste->vars["textprocessors"] = array();
- foreach($textprocessors as $txtproc => $properties)
- if($properties[1])
- $ste->vars["textprocessors"][] = $txtproc;
-
- $ste->vars["sections"] = array();
- foreach(Section::all() as $section)
- $ste->vars["sections"][] = $section->name;
- $ste->vars["article_section"] = $default_section->name;
-
- /* Check Form */
- $fail_reasons = array();
-
- if(isset($_POST["save_article"]))
- {
- if(!Article::test_urlname($_POST["urlname"]))
- $fail_reasons[] = $translation["invalid_urlname"];
- else
- $inputs["urlname"] = $_POST["urlname"];
- if(!Article::test_status(@$_POST["article_status"]))
- $fail_reasons[] = $translation["invalid_article_status"];
- else
- $inputs["article_status"] = (int) $_POST["article_status"];
- if(!isset($textprocessors[@$_POST["content_txtproc"]]))
- $fail_reasons[] = $translation["unknown_txtproc"];
- else
- $inputs["content_txtproc"] = $_POST["content_txtproc"];
- if(!isset($textprocessors[@$_POST["excerpt_txtproc"]]))
- $fail_reasons[] = $translation["unknown_txtproc"];
- else
- $inputs["excerpt_txtproc"] = $_POST["excerpt_txtproc"];
- if(!empty($_POST["date"]))
- {
- if(($time_tmp = @DateTime::createFromFormat("Y-m-d H:i:s", @$_POST["date"])) === False)
- $fail_reasons[] = $translation["invalid_date"];
- else
- $inputs["date"] = @$time_tmp->getTimestamp();
- }
- else
- $inputs["date"] = time();
- $inputs["allow_comments"] = !(empty($_POST["allow_comments"]) or ($_POST["allow_comments"] != "yes"));
-
- try
- {
- $inputs["article_section"] = Section::by_name($_POST["section"]);
- }
- catch(DoesNotExistError $e)
- {
- $fail_reasons[] = $translation["unknown_section"];
- }
-
- $inputs["title"] = $_POST["title"];
- $inputs["content"] = $_POST["content"];
- $inputs["excerpt"] = $_POST["excerpt"];
- $inputs["tags"] = array_filter(array_map("trim", explode(",", $_POST["tags"])), function($t) { return !empty($t); });
- 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->excerpt[$editlang] = new Translation($inputs["excerpt"], $inputs["excerpt_txtproc"]);
- $article->set_tags(maketags($inputs["tags"], $editlang));
- $article->set_section($inputs["article_section"]);
- $article->allow_comments = $inputs["allow_comments"];
- }
-
- if(empty($article))
- {
- /* New Article */
- $ste->vars["pagetitle"] = $translation["new_article"];
- if(empty($fail_reasons) and isset($_POST["save_article"]))
- {
- $article = Article::create($inputs["urlname"]);
- fill_article($article, $inputs, $editlang);
-
- /* Calling articleeditor plugins */
- $call_after_save = array();
- foreach($articleeditor_plugins as $plugin)
- {
- $result = call_user_func($plugin["fx"], $article, True);
- if(is_string($result))
- $fail_reasons[] = $result;
- elseif($result !== NULL)
- $call_after_save[] = $result;
- }
-
- if(empty($fail_reasons))
- {
- 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"];
- }
- }
- }
- }
- else
- {
- try
- {
- if(!($article instanceof Article))
- $article = Article::by_urlname($article);
- }
- catch(DoesNotExistError $e)
- {
- throw new NotFoundError();
- }
-
- if(empty($fail_reasons) and isset($_POST["save_article"]))
- {
- fill_article($article, $inputs, $editlang);
-
- /* Calling articleeditor plugins */
- $call_after_save = array();
- foreach($articleeditor_plugins as $plugin)
- {
- $result = call_user_func($plugin["fx"], $article, True);
- if(is_string($result))
- $fail_reasons[] = $result;
- elseif($result !== NULL)
- $call_after_save[] = $result;
- }
-
- if(empty($fail_reasons))
- {
- 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"];
- }
- }
- }
-
- if(!isset($article->title[$editlang]))
- {
- $langs_available = array();
- foreach($article->title as $lang => $_)
- $langs_available[] = $lang;
- $editlang = $langs_available[0];
- }
-
- foreach(array(
- "urlname" => "urlname",
- "status" => "article_status",
- "timestamp" => "date",
- "allow_comments" => "allow_comments"
- ) as $prop => $k_out)
- {
- if(!isset($inputs[$k_out]))
- $inputs[$k_out] = $article->$prop;
- }
- if(!isset($inputs["title"]))
- $inputs["title"] = $article->title[$editlang]->text;
- if(!isset($inputs["content"]))
- {
- $translation_obj = $article->text[$editlang];
- $inputs["content"] = $translation_obj->text;
- $inputs["content_txtproc"] = $translation_obj->texttype;
- }
- if(!isset($inputs["excerpt"]))
- {
- $translation_obj = $article->excerpt[$editlang];
- $inputs["excerpt"] = $translation_obj->text;
- $inputs["excerpt_txtproc"] = $translation_obj->texttype;
- }
- if(!isset($inputs["article_section"]))
- $inputs["article_section"] = $article->get_section();
- if(!isset($inputs["tags"]))
- $inputs["tags"] = array_map(function($tag) use ($editlang) { return $tag->name; }, $article->get_tags());
- $ste->vars["morelangs"] = array();
- $ste->vars["pagetitle"] = $article->title[$editlang]->text;
- foreach($article->title as $lang => $_)
- {
- if($lang != $editlang)
- $ste->vars["morelangs"][] = array("url" => urlencode($article->urlname) . "/$lang", "full" => "($lang) " . $languages[$lang]["language"]);
- }
- }
-
- if(!isset($inputs["date"]))
- $inputs["date"] = time();
- if(!isset($inputs["article_status"]))
- $inputs["article_status"] = ARTICLE_STATUS_LIVE;
-
- /* Push data back to template */
- if(isset($inputs["tags"]))
- $ste->vars["tags"] = implode(", ", $inputs["tags"]);
- if(isset($inputs["article_section"]))
- $ste->vars["article_section"] = $inputs["article_section"]->name;
- $ste->vars["editlang"] = $editlang;
- foreach(array(
- "urlname" => "urlname",
- "article_status" => "article_status",
- "title" => "title",
- "content_txtproc" => "content_txtproc",
- "content" => "content",
- "excerpt_txtproc" => "excerpt_txtproc",
- "excerpt" => "excerpt",
- "date" => "date",
- "allow_comments" => "allow_comments"
- ) as $k_in => $k_out)
- {
- if(isset($inputs[$k_in]))
- $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;
-
- echo $ste->exectemplate("/systemtemplates/content_write.html");
- },
- "tags" => function(&$data, $url_now, &$url_next)
- {
- global $translation, $languages, $ste, $rel_path_to_root;
-
- $url_next = array();
-
- $ste->vars["section"] = "content";
- $ste->vars["submenu"] = "tags";
- $ste->vars["pagetitle"] = $translation["tags_overview"];
-
- if(isset($_POST["delete"]) and ($_POST["really_delete"] == "yes"))
- {
- foreach($_POST["tag_multiselect"] as $tagid)
- {
- try
- {
- $tag = Tag::by_id($tagid);
- $tag->delete();
- }
- catch(DoesNotExistError $e)
- {
- continue;
- }
- }
-
- $ste->vars["success"] = $translation["tags_successfully_deleted"];
- }
-
- if(isset($_POST["save_changes"]))
- {
- $newlang = (!empty($_POST["new_language"])) ? $_POST["new_language"] : NULL;
- $newtag = NULL;
-
- if(!empty($_POST["newtagname"]))
- {
- if(!Tag::test_name(@$_POST["newtagname"]))
- $ste->vars["error"] = $translation["invalid_tag_name"];
- else
- $newtag = $_POST["newtagname"];
- }
-
- if(($newlang !== NULL) and (!isset($languages[$newlang])))
- $newlang = NULL;
- if($newtag !== NULL)
- {
- try
- {
- $newtag = Tag::create($newtag);
- }
- catch(AlreadyExistsError $e)
- {
- $newtag = NULL;
- }
- }
-
- $translations = array();
- foreach($_POST as $k => $v)
- {
- if(preg_match('/tagtrans_(NEW|[a-z]{2})_(.*)/', $k, $matches) == 1)
- {
- $lang = ($matches[1] == "NEW") ? $newlang : $matches[1];
- $tag = $matches[2];
- if($lang === NULL)
- continue;
- $translations[$tag][$lang] = $v;
- }
- }
-
- foreach($translations as $tag => $langmap)
- {
- if($tag == "NEW")
- {
- if($newtag === NULL)
- continue;
- $tag = $newtag;
- }
- else
- {
- try
- {
- $tag = Tag::by_id($tag);
- }
- catch(DoesNotExistError $e)
- {
- continue;
- }
- }
-
- foreach($langmap as $l => $text)
- {
- if(empty($text))
- unset($tag->title[$l]);
- else
- $tag->title[$l] = new Translation($text, "");
- }
-
- $tag->save();
- }
-
- $ste->vars["success"] = $translation["tags_successfully_edited"];
- }
-
- $ste->vars["alltags"] = array();
- $taglangs = array();
-
- $alltags = Tag::all();
- foreach($alltags as $tag)
- {
- $transls = array();
- foreach($tag->title as $l => $t)
- {
- if(!in_array($l, $taglangs))
- $taglangs[] = $l;
- $transls[$l] = $t->text;
- }
-
- $ste->vars["alltags"][] = array(
- "id" => $tag->get_id(),
- "name" => $tag->name,
- "translations" => $transls
- );
- }
-
- $unused_langs = array_diff(array_keys($languages), $taglangs);
-
- $ste->vars["all_tag_langs"] = array();
- foreach($taglangs as $l)
- $ste->vars["all_tag_langs"][$l] = $languages[$l]["language"];
- $ste->vars["unused_languages"] = array();
- foreach($unused_langs as $l)
- $ste->vars["unused_languages"][$l] = $languages[$l]["language"];
-
- echo $ste->exectemplate("/systemtemplates/tags_overview.html");
- },
- "articles" => function(&$data, $url_now, &$url_next)
- {
- global $ste, $translation, $languages, $rel_path_to_root;
-
- $url_next = array();
-
- $ste->vars["section"] = "content";
- $ste->vars["submenu"] = "articles";
- $ste->vars["pagetitle"] = $translation["menu_articles"];
-
- if(isset($_POST["delete"]) and ($_POST["really_delete"] == "yes"))
- {
- foreach($_POST["article_multiselect"] as $article_urlname)
- {
- try
- {
- $article = Article::by_urlname($article_urlname);
- $article->delete();
- }
- catch(DoesNotExistError $e)
- {
- continue;
- }
- }
-
- $ste->vars["success"] = $translation["articles_deleted"];
- }
-
- $articles = Article::all();
-
- /* Filtering */
- $filterquery = array();
- if(!empty($_GET["filter_urlname"]))
- {
- $searchfor = strtolower($_GET["filter_urlname"]);
- $articles = array_filter($articles, function($a) use ($searchfor) { return strpos(strtolower($a->urlname), $searchfor) !== False; });
- $filterquery[] = "filter_urlname=" . urlencode($_GET["filter_urlname"]);
- $ste->vars["filter_urlname"] = $_GET["filter_urlname"];
- }
- if(!empty($_GET["filter_tag"]))
- {
- $searchfor = $_GET["filter_tag"];
- $articles = array_filter($articles, function($a) use ($searchfor) { foreach($a->get_tags() as $t) { if($t->name==$searchfor) return True; } return False; });
- $filterquery[] = "filter_tag=" . urlencode($searchfor);
- $ste->vars["filter_tag"] = $searchfor;
- }
- if(!empty($_GET["filter_section"]))
- {
- $searchfor = $_GET["filter_section"];
- $articles = array_filter($articles, function($a) use ($searchfor) { return $a->get_section()->name == $searchfor; });
- $filterquery[] = "filter_section=" . urlencode($searchfor);
- $ste->vars["filter_section"] = $searchfor;
- }
- $ste->vars["filterquery"] = implode("&", $filterquery);
-
- /* Sorting */
- if(isset($_GET["sort_asc"]))
- {
- switch($_GET["sort_asc"])
- {
- case "date":
- $ste->vars["sortquery"] = "sort_asc=date";
- $ste->vars["sort_asc_date"] = True;
- $ste->vars["sorting"] = array("dir" => "asc", "by" => "date");
- usort($articles, function($a, $b) { return intcmp($a->timestamp, $b->timestamp); });
- break;
- case "section":
- $ste->vars["sortquery"] = "sort_asc=section";
- $ste->vars["sort_asc_section"] = True;
- $ste->vars["sorting"] = array("dir" => "asc", "by" => "section");
- usort($articles, function($a, $b) { return strcmp($a->get_section()->name, $b->get_section()->name); });
- break;
- case "urlname":
- $ste->vars["sortquery"] = "sort_asc=urlname";
- default:
- $ste->vars["sort_asc_urlname"] = True;
- $ste->vars["sorting"] = array("dir" => "asc", "by" => "urlname");
- usort($articles, function($a, $b) { return strcmp($a->urlname, $b->urlname); });
- break;
- }
- }
- elseif(isset($_GET["sort_desc"]))
- {
- switch($_GET["sort_desc"])
- {
- case "date":
- $ste->vars["sortquery"] = "sort_desc=date";
- $ste->vars["sort_desc_date"] = True;
- $ste->vars["sorting"] = array("dir" => "desc", "by" => "date");
- usort($articles, function($a, $b) { return intcmp($b->timestamp, $a->timestamp); });
- break;
- case "section":
- $ste->vars["sortquery"] = "sort_desc=section";
- $ste->vars["sort_desc_section"] = True;
- $ste->vars["sorting"] = array("dir" => "desc", "by" => "section");
- usort($articles, function($a, $b) { return strcmp($b->get_section()->name, $a->get_section()->name); });
- break;
- case "urlname":
- $ste->vars["sortquery"] = "sort_desc=urlname";
- $ste->vars["sort_desc_urlname"] = True;
- $ste->vars["sorting"] = array("dir" => "desc", "by" => "urlname");
- usort($articles, function($a, $b) { return strcmp($b->urlname, $a->urlname); });
- break;
- default:
- $ste->vars["sort_asc_urlname"] = True;
- $ste->vars["sorting"] = array("dir" => "asc", "by" => "urlname");
- usort($articles, function($a, $b) { return strcmp($a->urlname, $b->urlname); });
- break;
- }
- }
- else
- {
- $ste->vars["sort_asc_urlname"] = True;
- $ste->vars["sorting"] = array("dir" => "asc", "by" => "urlname");
- usort($articles, function($a, $b) { return strcmp($a->urlname, $b->urlname); });
- }
-
- $ste->vars["articles"] = array_map(function($article) {
- $avail_langs = array();
- foreach($article->title as $lang => $_)
- $avail_langs[] = $lang;
- sort($avail_langs);
- $a_section = $article->get_section();
- return array(
- "urlname" => $article->urlname,
- "languages" => $avail_langs,
- "date" => $article->timestamp,
- "tags" => array_map(function($tag) { return $tag->name; }, $article->get_tags()),
- "section" => array("id" => $a_section->get_id(), "name" => $a_section->name)
- );
- }, $articles);
-
- echo $ste->exectemplate("/systemtemplates/articles.html");
- },
- "images" => function(&$data, $url_now, &$url_next)
- {
- global $ste, $translation, $languages, $rel_path_to_root;
-
- list($imgid, $imageaction) = $url_next;
-
- $url_next = array();
-
- $ste->vars["section"] = "content";
- $ste->vars["submenu"] = "images";
- $ste->vars["pagetitle"] = $translation["menu_images"];
-
- if(!empty($imgid) and is_numeric($imgid))
- {
- try
- {
- $image = Image::by_id($imgid);
- }
- catch(DoesNotExistError $e)
- {
- throw new NotFoundError();
- }
-
- if(empty($imageaction))
- throw new NotFoundError();
- else
- {
- if(($imageaction == "markdown") or ($imageaction == "html") or ($imageaction == "ste"))
- {
- $ste->vars["pagetitle"] = $translation["generate_embed_code"];
- $ste->vars["image_id"] = $image->get_id();
- $ste->vars["markup_variant"] = $imageaction;
- if(isset($_POST["img_alt"]))
- {
- if($imageaction == "markdown")
- $ste->vars["embed_code"] = "![" . str_replace("]", "\\]", $_POST["img_alt"]) . "](%root%/images/" . str_replace(")", "\\)", urlencode($image->get_filename())) . ")";
- elseif($imageaction == "html")
- $ste->vars["embed_code"] = "<img src=\"%root%/images/" . htmlesc(urlencode($image->get_filename())) . "\" alt=\"" . htmlesc($_POST["img_alt"]) . "\" />";
- elseif($imageaction == "ste")
- $ste->vars["embed_code"] = "<img src=\"\$rel_path_to_root/images/" . htmlesc(urlencode($image->get_filename())) . "\" alt=\"" . htmlesc($_POST["img_alt"]) . "\" />";
- }
-
- echo $ste->exectemplate("/systemtemplates/image_embed.html");
- }
- else
- throw new NotFoundError();
- }
- return;
- }
-
- /* Upload Form */
- if(isset($_POST["upload"]))
- {
- try
- {
- $image = Image::create((!empty($_POST["upload_name"])) ? $_POST["upload_name"] : $_FILES["upload_img"]["name"], $_FILES["upload_img"]["tmp_name"]);
- $image->save();
- $ste->vars["success"] = $translation["upload_success"];
- }
- catch(IOError $e)
- {
- $ste->vars["error"] = $translation["upload_failed"];
- }
- catch(UnknownFileFormat $e)
- {
- $ste->vars["error"] = $translation["unknown_file_format"];
- }
- }
-
- /* Mass delete */
- if(isset($_POST["delete"]) and ($_POST["really_delete"] == "yes"))
- {
- foreach($_POST["image_multiselect"] as $image_id)
- {
- try
- {
- $image = Image::by_id($image_id);
- $image->delete();
- }
- catch(DoesNotExistError $e)
- {
- continue;
- }
- }
-
- $ste->vars["success"] = $translation["images_deleted"];
- }
-
- $images = Image::all();
-
- $ste->vars["images"] = array_map(function($img) { return array(
- "id" => $img->get_id(),
- "name" => $img->name,
- "file" => $img->get_filename()
- ); }, $images);
-
- echo $ste->exectemplate("/systemtemplates/image_list.html");
- },
- "comments" => function(&$data, $url_now, &$url_next)
- {
- global $ste, $translation, $languages, $rel_path_to_root;
-
- list($comment_id) = $url_next;
-
- $url_next = array();
-
- $ste->vars["section"] = "content";
- $ste->vars["submenu"] = "comments";
- $ste->vars["pagetitle"] = $translation["menu_comments"];
-
- /* Single comment? */
- if(!empty($comment_id))
- {
- try
- {
- $comment = Comment::by_id($comment_id);
- }
- catch(DoesNotExistError $e)
- {
- throw new NotFoundError();
- }
-
- if(!$comment->read_by_admin)
- {
- $comment->read_by_admin = True;
- $comment->save();
- }
-
- if(isset($_POST["action_on_comment"]))
- {
- switch($_POST["action_on_comment"])
- {
- case "delete":
- $comment->delete();
- $ste->vars["success"] = $translation["comment_successfully_deleted"];
- goto backend_content_comments_overview;
- break;
- case "make_visible":
- $comment->visible = True;
- $comment->save();
- $ste->vars["success"] = $translation["comment_successfully_made_visible"];
- break;
- case "make_invisible":
- $comment->visible = False;
- $comment->save();
- $ste->vars["success"] = $translation["comment_successfully_made_invisible"];
- break;
- }
- }
-
- $ste->vars["id"] = $comment->get_id();
- $ste->vars["visible"] = $comment->visible;
- $ste->vars["article"] = $comment->get_article()->urlname;
- $ste->vars["language"] = $comment->get_language();
- $ste->vars["date"] = $comment->get_timestamp();
- $ste->vars["author"] = "\"{$comment->author_name}\" <{$comment->author_mail}>";
- $ste->vars["comment_text"] = $comment->create_html();
- $ste->vars["comment_raw"] = $comment->text;
-
- echo $ste->exectemplate("/systemtemplates/single_comment.html");
- return;
- }
-
- backend_content_comments_overview:
-
- /* Perform an action on all selected comments */
- if(!empty($_POST["action_on_comments"]))
- {
- switch($_POST["action_on_comments"])
- {
- case "delete":
- $commentaction = function($c) { $c->delete(); };
- $ste->vars["success"] = $translation["comments_successfully_deleted"];
- break;
- case "mark_read":
- $commentaction = function($c) { $c->read_by_admin = True; $c->save(); };
- $ste->vars["success"] = $translation["comments_successfully_marked_read"];
- break;
- case "mark_unread":
- $commentaction = function($c) { $c->read_by_admin = False; $c->save(); };
- $ste->vars["success"] = $translation["comments_successfully_marked_unread"];
- break;
- case "make_visible":
- $commentaction = function($c) { $c->visible = True; $c->save(); };
- $ste->vars["success"] = $translation["comments_successfully_made_visible"];
- break;
- case "make_invisible":
- $commentaction = function($c) { $c->visible = False; $c->save(); };
- $ste->vars["success"] = $translation["comments_successfully_made_invisible"];
- break;
- default;
- $ste->vars["error"] = $translation["unknown_action"];
- break;
- }
- if(isset($commentaction))
- {
- foreach($_POST["comment_multiselect"] as $c_id)
- {
- try
- {
- $comment = Comment::by_id($c_id);
- $commentaction($comment);
- }
- catch(DoesNotExistError $e)
- {
- continue;
- }
- }
- }
- }
-
- $comments = Comment::all();
-
- /* Filtering */
- $filterquery = array();
- if(!empty($_GET["filter_article"]))
- {
- $searchfor = strtolower($_GET["filter_article"]);
- $comments = array_filter($comments, function($c) use ($searchfor) { return strpos(strtolower($c->get_article()->urlname), $searchfor) !== False; });
- $filterquery[] = "filter_article=" . urlencode($_GET["filter_article"]);
- $ste->vars["filter_article"] = $_GET["filter_article"];
- }
- $ste->vars["filterquery"] = implode("&", $filterquery);
-
- /* Sorting */
- if(isset($_GET["sort_asc"]))
- {
- $sort_dir = 1;
- $sort_by = $_GET["sort_asc"];
- }
- elseif(isset($_GET["sort_desc"]))
- {
- $sort_dir = -1;
- $sort_by = $_GET["sort_desc"];
- }
- else
- {
- $sort_dir = 1;
- $sort_by = "was_read";
- }
-
- switch($sort_by)
- {
- case "language":
- usort($comments, function($a, $b) use ($sort_dir) { return strcmp($a->get_language(), $b->get_language()) * $sort_dir; });
- break;
- case "date":
- usort($comments, function($a, $b) use ($sort_dir) { return intcmp($a->get_timestamp(), $b->get_timestamp()) * $sort_dir; });
- break;
- case "was_read":
- default:
- usort($comments, function($a, $b) use ($sort_dir) { return intcmp((int) $a->read_by_admin, (int) $b->read_by_admin) * $sort_dir; });
- $sort_by = "was_read";
- break;
- }
- $ste->vars["sortquery"] = "sort_" . ($sort_dir == 1 ? "asc" : "desc") . "=$sort_by";
- $ste->vars["sorting"] = array("dir" => ($sort_dir == 1 ? "asc" : "desc"), "by" => $sort_by);
- $ste->vars["sort_" . ($sort_dir == 1 ? "asc" : "desc") . "_$sort_by"] = True;
-
- $ste->vars["comments"] = array_map(function($c) { return array(
- "id" => $c->get_id(),
- "visible" => $c->visible,
- "read_by_admin" => $c->read_by_admin,
- "article" => $c->get_article()->urlname,
- "excerpt" => substr(str_replace(array("\r\n", "\n", "\r"), " ", $c->text), 0, 50),
- "language" => $c->get_language(),
- "date" => $c->get_timestamp(),
- "author" => "\"{$c->author_name}\" <{$c->author_mail}>"
- ); }, $comments);
-
- echo $ste->exectemplate("/systemtemplates/comments_list.html");
- }
- )),
- "design" => url_action_subactions(array(
- "templates" => function(&$data, $url_now, &$url_next)
- {
- global $ste, $translation, $languages, $rel_path_to_root;
-
- list($template) = $url_next;
-
- $url_next = array();
-
- $ste->vars["section"] = "design";
- $ste->vars["submenu"] = "templates";
- $ste->vars["pagetitle"] = $translation["menu_templates"];
-
- if(isset($template))
- {
- if(preg_match("/^[a-zA-Z0-9\\-_\\.]+$/", $template) == 0) /* Prevent a possible LFI attack. */
- throw new NotFoundError();
- if(!is_file(SITE_BASE_PATH . "/ratatoeskr/templates/src/usertemplates/$template"))
- throw new NotFoundError();
- $ste->vars["template_name"] = $template;
- $ste->vars["template_code"] = file_get_contents(SITE_BASE_PATH . "/ratatoeskr/templates/src/usertemplates/$template");
- }
-
- /* Was there a delete request? */
- if(isset($_POST["delete"]) and ($_POST["really_delete"] == "yes"))
- {
- foreach($_POST["templates_multiselect"] as $tplname)
- {
- if(preg_match("/^[a-zA-Z0-9\\-_\\.]+$/", $tplname) == 0) /* Prevent a possible LFI attack. */
- continue;
- if(is_file(SITE_BASE_PATH . "/ratatoeskr/templates/src/usertemplates/$tplname"))
- @unlink(SITE_BASE_PATH . "/ratatoeskr/templates/src/usertemplates/$tplname");
- }
- $ste->vars["success"] = $translation["templates_successfully_deleted"];
- }
-
- /* A write request? */
- if(isset($_POST["save_template"]))
- {
- if(preg_match("/^[a-zA-Z0-9\\-_\\.]+$/", $_POST["template_name"]) == 1)
- {
- $ste->vars["template_name"] = $_POST["template_name"];
- $ste->vars["template_code"] = $_POST["template_code"];
-
- try
- {
- \ste\transcompile(\ste\parse(\ste\precompile($_POST["template_code"]), $_POST["template_name"]));
- file_put_contents(SITE_BASE_PATH . "/ratatoeskr/templates/src/usertemplates/" . $_POST["template_name"], $_POST["template_code"]);
- $ste->vars["success"] = $translation["template_successfully_saved"];
- }
- catch(\ste\ParseCompileError $e)
- {
- $e->rewrite($_POST["template_code"]);
- $ste->vars["error"] = $translation["could_not_compile_template"] . $e->getMessage();
- }
- }
- else
- $ste->vars["error"] = $translation["invalid_template_name"];
- }
-
- /* Get all templates */
- $ste->vars["templates"] = array();
- $tpldir = new DirectoryIterator(SITE_BASE_PATH . "/ratatoeskr/templates/src/usertemplates");
- foreach($tpldir as $fo)
- {
- if($fo->isFile())
- $ste->vars["templates"][] = $fo->getFilename();
- }
- sort($ste->vars["templates"]);
-
- echo $ste->exectemplate("/systemtemplates/templates.html");
- },
- "styles" => function(&$data, $url_now, &$url_next)
- {
- global $ste, $translation, $languages, $rel_path_to_root;
-
- list($style) = $url_next;
-
- $url_next = array();
-
- $ste->vars["section"] = "design";
- $ste->vars["submenu"] = "styles";
- $ste->vars["pagetitle"] = $translation["menu_styles"];
-
- if(isset($style))
- {
- try
- {
- $style = Style::by_name($style);
- $ste->vars["style_name"] = $style->name;
- $ste->vars["style_code"] = $style->code;
- }
- catch(DoesNotExistError $e)
- {
- throw new NotFoundError();
- }
- }
-
- /* Was there a delete request? */
- if(isset($_POST["delete"]) and ($_POST["really_delete"] == "yes"))
- {
- foreach($_POST["styles_multiselect"] as $stylename)
- {
- try
- {
- $style = Style::by_name($stylename);
- $style->delete();
- }
- catch(DoesNotExistError $e)
- {
- continue;
- }
- }
- $ste->vars["success"] = $translation["styles_successfully_deleted"];
- }
-
- /* A write request? */
- if(isset($_POST["save_style"]))
- {
- if(Style::test_name($_POST["style_name"]))
- {
- $ste->vars["style_name"] = $_POST["style_name"];
- $ste->vars["style_code"] = $_POST["style_code"];
-
- try
- {
- $style = Style::by_name($_POST["style_name"]);
- }
- catch(DoesNotExistError $e)
- {
- $style = Style::create($_POST["style_name"]);
- }
-
- $style->code = $_POST["style_code"];
- $style->save();
-
- $ste->vars["success"] = $translation["style_successfully_saved"];
- }
- else
- $ste->vars["error"] = $translation["invalid_style_name"];
- }
-
- /* Get all styles */
- $ste->vars["styles"] = array_map(function($s) { return $s->name; }, Style::all());
- sort($ste->vars["styles"]);
-
- echo $ste->exectemplate("/systemtemplates/styles.html");
- },
- "sections" => function(&$data, $url_now, &$url_next)
- {
- global $ste, $translation, $languages, $rel_path_to_root, $ratatoeskr_settings;
-
- list($style) = $url_next;
-
- $url_next = array();
-
- $ste->vars["section"] = "design";
- $ste->vars["submenu"] = "sections";
- $ste->vars["pagetitle"] = $translation["menu_pagesections"];
-
- /* New section? */
- if(isset($_POST["new_section"]))
- {
- try
- {
- Section::by_name($_POST["section_name"]);
- $ste->vars["error"] = $translation["section_already_exists"];
- }
- catch(DoesNotExistError $e)
- {
- if((preg_match("/^[a-zA-Z0-9\\-_\\.]+$/", $_POST["template"]) == 0) or (!is_file(SITE_BASE_PATH . "/ratatoeskr/templates/src/usertemplates/{$_POST['template']}")))
- $ste->vars["error"] = $translation["unknown_template"];
- else if(!Section::test_name($_POST["section_name"]))
- $ste->vars["error"] = $translation["invalid_section_name"];
- else
- {
- $section = Section::create($_POST["section_name"]);
- $section->template = $_POST["template"];
- $section->title[$data["user"]->language] = new Translation($_POST["section_name"], "");
- $section->save();
- $ste->vars["success"] = $translation["section_created_successfully"];
- }
- }
- }
-
- /* Remove a style? */
- if(isset($_GET["rmstyle"]) and isset($_GET["rmfrom"]))
- {
- try
- {
- $section = Section::by_name($_GET["rmfrom"]);
- $style = Style::by_name($_GET["rmstyle"]);
- $section->remove_style($style);
- $section->save();
- $ste->vars["success"] = $translation["style_removed"];
- }
- catch(DoesNotExistError $e)
- {
- }
- }
-
- /* Delete a section? */
- if(isset($_POST["delete"]) and (@$_POST["really_delete"] == "yes") and isset($_POST["section_select"]))
- {
- try
- {
- $section = Section::by_name($_POST["section_select"]);
- if($section->get_id() == $ratatoeskr_settings["default_section"])
- $ste->vars["error"] = $translation["cannot_delete_default_section"];
- else
- {
- $default_section = Section::by_id($ratatoeskr_settings["default_section"]);
- foreach($section->get_articles() as $article)
- {
- $article->set_section($default_section);
- $article->save();
- }
- $section->delete();
- $ste->vars["success"] = $translation["section_successfully_deleted"];
- }
- }
- catch(DoesNotExistError $e)
- {
- }
- }
-
- /* Make section default? */
- if(isset($_POST["make_default"]) and isset($_POST["section_select"]))
- {
- try
- {
- $section = Section::by_name($_POST["section_select"]);
- $ratatoeskr_settings["default_section"] = $section->get_id();
- $ste->vars["success"] = $translation["default_section_changed_successfully"];
- }
- catch(DoesNotExistError $e)
- {
- }
- }
-
- /* Set template? */
- if(isset($_POST["set_template"]) and isset($_POST["section_select"]))
- {
- try
- {
- $section = Section::by_name($_POST["section_select"]);
- if((preg_match("/^[a-zA-Z0-9\\-_\\.]+$/", $_POST["set_template_to"]) == 0) or (!is_file(SITE_BASE_PATH . "/ratatoeskr/templates/src/usertemplates/{$_POST['set_template_to']}")))
- $ste->vars["error"] = $translation["unknown_template"];
- else
- {
- $section->template = $_POST["set_template_to"];
- $section->save();
- $ste->vars["success"] = $translation["successfully_set_template"];
- }
- }
- catch(DoesNotExistError $e)
- {
- }
- }
-
- /* Adding a style? */
- if(isset($_POST["add_style"]) and isset($_POST["section_select"]))
- {
- try
- {
- $section = Section::by_name($_POST["section_select"]);
- $style = Style::by_name($_POST["style_to_add"]);
- $section->add_style($style);
- $ste->vars["success"] = $translation["successfully_added_style"];
- }
- catch(DoesNotExistError $e)
- {
- }
- }
-
- /* Set/unset title? */
- if(isset($_POST["set_title"]) and isset($_POST["section_select"]))
- {
- if(!isset($languages[$_POST["set_title_lang"]]))
- $ste->vars["error"] = $translation["language_unknown"];
- else
- {
- try
- {
- $section = Section::by_name($_POST["section_select"]);
- if(!empty($_POST["set_title_text"]))
- $section->title[$_POST["set_title_lang"]] = new Translation($_POST["set_title_text"], "");
- else if(isset($section->title[$_POST["set_title_lang"]]))
- unset($section->title[$_POST["set_title_lang"]]);
- $section->save();
- $ste->vars["success"] = $translation["successfully_set_section_title"];
- }
- catch(DoesNotExistError $e)
- {
- }
- }
- }
-
- /* Get all templates */
- $ste->vars["templates"] = array();
- $tpldir = new DirectoryIterator(SITE_BASE_PATH . "/ratatoeskr/templates/src/usertemplates");
- foreach($tpldir as $fo)
- {
- if($fo->isFile())
- $ste->vars["templates"][] = $fo->getFilename();
- }
- sort($ste->vars["templates"]);
-
- /* Get all styles */
- $ste->vars["styles"] = array_map(function($s) { return $s->name; }, Style::all());
- sort($ste->vars["styles"]);
-
- /* Get all sections */
- $sections = Section::all();
- $ste->vars["sections"] = array_map(function($section) use ($ratatoeskr_settings) {
- $titles = array();
- foreach($section->title as $l => $t)
- $titles[$l] = $t->text;
- return array(
- "name" => $section->name,
- "title" => $titles,
- "template" => $section->template,
- "styles" => array_map(function($style) { return $style->name; }, $section->get_styles()),
- "default" => ($section->get_id() == $ratatoeskr_settings["default_section"])
- );
- }, $sections);
-
- echo $ste->exectemplate("/systemtemplates/sections.html");
- }
- )),
- "admin" => url_action_subactions(array(
- "settings" => function(&$data, $url_now, &$url_next)
- {
- global $ste, $translation, $languages, $rel_path_to_root, $ratatoeskr_settings, $textprocessors;
-
- $url_next = array();
-
- $ste->vars["section"] = "admin";
- $ste->vars["submenu"] = "settings";
- $ste->vars["pagetitle"] = $translation["menu_settings"];
-
- $ste->vars["textprocessors"] = array();
- foreach($textprocessors as $txtproc => $properties)
- if($properties[1])
- $ste->vars["textprocessors"][] = $txtproc;
-
- /* Toggle debugmode value? */
- if(isset($_POST["toggle_debugmode"]))
- {
- if(isset($ratatoeskr_settings["debugmode"]) and $ratatoeskr_settings["debugmode"])
- {
- $ratatoeskr_settings["debugmode"] = False;
- $ste->vars["success"] = $translation["debugmode_now_disabled"];
- }
- else
- {
- $ratatoeskr_settings["debugmode"] = True;
- $ste->vars["success"] = $translation["debugmode_now_enabled"];
- }
- }
-
- /* Save comment settings? */
- if(isset($_POST["save_comment_settings"]))
- {
- if(!in_array(@$_POST["comment_textprocessor"], $ste->vars["textprocessors"]))
- $ste->vars["error"] = $translation["unknown_txtproc"];
- else
- {
- $ratatoeskr_settings["comment_textprocessor"] = $_POST["comment_textprocessor"];
- $ratatoeskr_settings["comment_visible_default"] = (isset($_POST["comment_auto_visible"]) and ($_POST["comment_auto_visible"] == "yes"));
- $ste->vars["success"] = $translation["comment_settings_successfully_saved"];
- }
- }
-
- /* Delete language? */
- if(isset($_POST["delete"]) and ($_POST["really_delete"] == "yes") and isset($_POST["language_select"]))
- {
- if($ratatoeskr_settings["default_language"] == $_POST["language_select"])
- $ste->vars["error"] = $translation["cannot_delete_default_language"];
- else
- {
- $ratatoeskr_settings["languages"] = array_filter($ratatoeskr_settings["languages"], function($l) { return $l != $_POST["language_select"]; });
- $ste->vars["success"] = $translation["language_successfully_deleted"];
- }
- }
-
- /* Set default language */
- if(isset($_POST["make_default"]) and isset($_POST["language_select"]))
- {
- if(in_array($_POST["language_select"], $ratatoeskr_settings["languages"]))
- {
- $ratatoeskr_settings["default_language"] = $_POST["language_select"];
- $ste->vars["success"] = $translation["successfully_set_default_language"];
- }
- }
-
- /* Add a language */
- if(isset($_POST["add_language"]))
- {
- if(!isset($languages[$_POST["language_to_add"]]))
- $ste->vars["error"] = $translation["language_unknown"];
- else
- {
- if(!in_array($_POST["language_to_add"], $ratatoeskr_settings["languages"]))
- {
- $ls = $ratatoeskr_settings["languages"];
- $ls[] = $_POST["language_to_add"];
- $ratatoeskr_settings["languages"] = $ls;
- }
- $ste->vars["success"] = $translation["language_successfully_added"];
- }
- }
-
- $ste->vars["debugmode_enabled"] = (isset($ratatoeskr_settings["debugmode"]) and $ratatoeskr_settings["debugmode"]);
- $ste->vars["comment_auto_visible"] = $ratatoeskr_settings["comment_visible_default"];
- $ste->vars["comment_textprocessor"] = $ratatoeskr_settings["comment_textprocessor"];
- $ste->vars["used_langs"] = array_map(function ($l) use ($ratatoeskr_settings, $languages) { return array(
- "code" => $l,
- "name" => $languages[$l]["language"],
- "default" => ($l == $ratatoeskr_settings["default_language"])
- );}, $ratatoeskr_settings["languages"]);
-
- echo $ste->exectemplate("/systemtemplates/settings.html");
- },
- "users" => url_action_subactions(array(
- "_index" => function(&$data, $url_now, &$url_next)
- {
- global $ste, $translation, $languages, $rel_path_to_root, $ratatoeskr_settings, $textprocessors;
-
- $url_next = array();
-
- $ste->vars["section"] = "admin";
- $ste->vars["submenu"] = "users";
- $ste->vars["pagetitle"] = $translation["menu_users_groups"];
-
- /* Add a new group? */
- if(isset($_POST["new_group"]))
- {
- if(empty($_POST["group_name"]))
- $ste->vars["error"] = $translation["empty_group_name"];
- else
- {
- try
- {
- Group::by_name($_POST["group_name"]);
- $ste->vars["error"] = $translation["group_already_exists"];
- }
- catch(DoesNotExistError $e)
- {
- $group = Group::create($_POST["group_name"]);
- $ste->vars["success"] = $translation["successfully_created_group"];
- }
- }
- }
-
- /* Add a new user? */
- if(isset($_POST["new_user"]))
- {
- if(empty($_POST["username"]))
- $ste->vars["error"] = $translation["empty_username"];
- else
- {
- try
- {
- User::by_name($_POST["username"]);
- $ste->vars["error"] = $translation["user_already_exists"];
- }
- catch(DoesNotExistError $e)
- {
- $group = User::create($_POST["username"], PasswordHash::create($_POST["initial_password"]));
- $ste->vars["success"] = $translation["successfully_created_user"];
- }
- }
- }
-
- /* Delete groups? */
- if(isset($_POST["delete_groups"]) and ($_POST["really_delete"] == "yes") and (!empty($_POST["groups_multiselect"])))
- {
- $deleted = 0;
- foreach($_POST["groups_multiselect"] as $gid)
- {
- try
- {
- $group = Group::by_id($gid);
- if($group->name == "admins")
- {
- $ste->vars["error"] = $translation["cannot_delete_admin_group"];
- }
- else
- {
- $group->delete();
- ++$deleted;
- }
- }
- catch(DoesNotExistError $e)
- {
- continue;
- }
- }
- if($deleted > 0)
- $ste->vars["success"] = $translation["successfully_deleted_groups"];
- }
-
- /* Delete users? */
- if(isset($_POST["delete_users"]) and ($_POST["really_delete"] == "yes") and (!empty($_POST["users_multiselect"])))
- {
- $deleted = 0;
- foreach($_POST["users_multiselect"] as $uid)
- {
- if($uid == $data["user"]->get_id())
- $ste->vars["error"] = $translation["cannot_delete_yourself"];
- else
- {
- try
- {
- $user = User::by_id($uid);
- $user->delete();
- ++$deleted;
- }
- catch(DoesNotExistError $e)
- {
- continue;
- }
- }
- }
- if($deleted > 0)
- $ste->vars["success"] = $translation["successfully_deleted_users"];
- }
-
- /* Get all groups */
- $ste->vars["groups"] = array_map(function($g) { return array(
- "id" => $g->get_id(),
- "name" => $g->name
- ); }, Group::all());
-
- /* Get all users */
- $ste->vars["users"] = array_map(function($u) { return array(
- "id" => $u->get_id(),
- "name" => $u->username,
- "memberof" => array_map(function($g) { return $g->name; }, $u->get_groups()),
- "fullname" => $u->fullname,
- "mail" => $u->mail
- ); }, User::all());
-
- echo $ste->exectemplate("/systemtemplates/users.html");
- },
- "u" => function(&$data, $url_now, &$url_next)
- {
- global $ste, $translation, $languages, $rel_path_to_root, $admin_grp;
-
- try
- {
- $user = User::by_id($url_next[0]);
- }
- catch(DoesNotExistError $e)
- {
- throw new NotFoundError();
- }
-
- $url_next = array();
-
- $ste->vars["section"] = "admin";
- $ste->vars["submenu"] = "users";
- $ste->vars["pagetitle"] = $user->username;
-
- /* Modify data? */
- if(isset($_POST["change_data"]))
- {
- $user->fullname = $_POST["fullname"];
- $user->mail = $_POST["mail"];
- $user->language = $_POST["lang"];
-
- $current_groups = array_map(function($g) { return $g->get_id(); }, $user->get_groups());
- $new_groups = empty($_POST[groups_multiselect]) ? array() : $_POST["groups_multiselect"];
- $groups_exclude = array_diff($current_groups, $new_groups);
- $groups_include = array_diff($new_groups, $current_groups);
-
- foreach($groups_exclude as $gid)
- {
- try
- {
- $g = Group::by_id($gid);
- $g->exclude_user($user);
- }
- catch(DoesNotExistError $e)
- {
- continue;
- }
- }
-
- foreach($groups_include as $gid)
- {
- try
- {
- $g = Group::by_id($gid);
- $g->include_user($user);
- }
- catch(DoesNotExistError $e)
- {
- continue;
- }
- }
-
- $user->save();
-
- $ste->vars["success"] = $translation["successfully_modified_user"];
- }
-
- /* New Password? */
- if(isset($_POST["new_password"]))
- {
- $pwhash = PasswordHash::create($_POST["password"]);
- $user->pwhash = $pwhash;
- if($user->get_id() == $data["user"]->get_id())
- $_SESSION["ratatoeskr_pwhash"] = $pwhash;
- $user->save();
-
- $ste->vars["success"] = $translation["successfully_set_new_password"];
- }
-
- /* Put data to STE */
- $ste->vars["u"] = array(
- "id" => $user->get_id(),
- "name" => $user->username,
- "fullname" => $user->fullname,
- "mail" => $user->mail,
- "lang" => $user->language
- );
- $ste->vars["groups"] = array_map(function($g) use ($user) { return array(
- "id" => $g->get_id(),
- "name" => $g->name,
- "member" => $user->member_of($g)
- ); }, Group::all());
-
- 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"];
-
- /* Add a repo? */
- if(isset($_POST["add_repo"]))
- {
- try
- {
- $repo = Repository::create($_POST["repo_baseurl"]);
- $ste->vars["success"] = $translation["successfully_added_repo"];
- }
- catch(RepositoryUnreachableOrInvalid $e)
- {
- $ste->vars["error"] = $translation["repository_unreachable_or_invalid"];
- }
- }
-
- /* Delete repos? */
- if(isset($_POST["delete_repos"]) and ($_POST["really_delete"] == "yes"))
- {
- foreach($_POST["repos_multiselect"] as $repo_id)
- {
- try
- {
- $repo = Repository::by_id($repo_id);
- $repo->delete();
- }
- catch(DoesNotExistError $e)
- {
- continue;
- }
- }
- $ste->vars["success"] = $translation["repos_deleted"];
- }
-
- /* Force refresh? */
- if(isset($_POST["force_repo_refresh"]))
- {
- $failed = array();
- foreach($_POST["repos_multiselect"] as $repo_id)
- {
- try
- {
- $repo = Repository::by_id($repo_id);
- $repo->refresh(True);
- }
- catch(DoesNotExistError $e)
- {
- continue;
- }
- catch(RepositoryUnreachableOrInvalid $e)
- {
- $failed[] = $repo->get_name();
- }
- }
- $ste->vars["success"] = $translation["successfully_refreshed_repos"];
- if(!empty($failed))
- $ste->vars["error"] = str_replace("[[REPOS]]", implode(", ", $failed), $translation["repo_refresh_failed_on"]);
- }
-
- /* Fill data */
- $all_repos = Repository::all();
- $ste->vars["repos"] = array_map(
- function($r)
- {
- try
- {
- $r->refresh();
- }
- catch(RepositoryUnreachableOrInvalid $e){}
- return array(
- "id" => $r->get_id(),
- "name" => $r->get_name(),
- "description" => $r->get_description(),
- "baseurl" => $r->get_baseurl()
- );
- }, $all_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, $api_compat;
-
- $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") or ($_POST["really_delete"] == "force")) and (!empty($_POST["plugins_multiselect"])))
- {
- foreach($_POST["plugins_multiselect"] as $pid)
- {
- try
- {
- $plugin = Plugin::by_id($pid);
- if($_POST["really_delete"] != "force")
- {
- 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"])))
- {
- $api_incompat = array();
- $newstatus = isset($_POST["activate"]);
- foreach($_POST["plugins_multiselect"] as $pid)
- {
- try
- {
- $plugin = Plugin::by_id($pid);
- if(!$plugin->installed)
- continue;
- if($newstatus and (!in_array($plugin->api, $api_compat)))
- {
- $api_incompat[] = $plugin->name . ("(ID: " . $plugin->get_id() . ")");
- 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"];
-
- if(!empty($api_incompat))
- $ste->vars["error"] = htmlesc(str_replace("[[PLUGINS]]", implode(", ", $api_incompat), $translation["could_not_activate_plugin_api_incompat"]));
- }
-
- $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"]+0) > ($plugin->versioncount+0)))
- {
- $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();
- $api_incompat = array();
- foreach($all_plugins as $p)
- {
- if(!$p->installed)
- continue;
-
- if(!in_array($p->api, $api_compat))
- $api_incompat[] = $p->name . ("(ID: " . $p->get_id() . ")");
-
- $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)
- );
- }
-
- if(!empty($api_incompat))
- $ste->vars["notice"] = htmlesc(str_replace("[[PLUGINS]]", implode(", ", $api_incompat), $translation["plugins_incompat"]));
-
- 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"];
-
- $all_repos = Repository::all();
- foreach($all_repos as $repo)
- {
- try
- {
- $repo->refresh();
- }
- catch(RepositoryUnreachableOrInvalid $e)
- {
- continue;
- }
- }
-
- 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"];
- }
-
- if(isset($_POST["search_in_repos"]))
- {
- $ste->vars["searchresults"] = array();
- $repos_to_scan = ($_POST["searchin"] == "*") ? $all_repos : Repository::by_id($_POST["searchin"]);
- $searchfor = strtolower($_POST["searchfor"]);
- foreach($repos_to_scan as $repo)
- {
- foreach($repo->packages as $pkg)
- {
- if(empty($searchfor) or (strpos(strtolower($pkg[0]), $searchfor) !== False) or (strpos(strtolower($pkg[2]), $searchfor) !== False))
- $ste->vars["searchresults"][] = array(
- "name" => $pkg[0],
- "description" => $pkg[2],
- "reponame" => $repo->get_name(),
- "repoid" => $repo->get_id()
- );
- }
- }
- }
-
- $ste->vars["repos"] = array_map(function($r) { return array(
- "id" => $r->get_id(),
- "name" => $r->get_name()
- ); }, $all_repos);
-
- echo $ste->exectemplate("/systemtemplates/plugininstall.html");
- },
- "repoinstall" => function(&$data, $url_now, &$url_next)
- {
- global $ste, $translation, $rel_path_to_root;
-
- $stream_ctx = stream_context_create(array("http" => array("timeout" => 5)));
-
- try
- {
- $repo = Repository::by_id($_GET["repo"]);
- $pkg = $repo->download_package($_GET["pkg"]);
- $plugin = Plugin::create();
- $plugin->fill_from_pluginpackage($pkg);
- $plugin->installed = False;
- $plugin->active = False;
- $plugin->save();
- $url_next = array("confirminstall", (string) $plugin->get_id());
- }
- catch(DoesNotExistError $e)
- {
- $ste->vars["error"] = $translation["package_or_repo_not_found"];
- $url_next = array("install");
- }
- catch(InvalidPackage $e)
- {
- $ste->vars["error"] = $translation["invalid_package"];
- $url_next = array("install");
- }
- },
- "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)
+ "_index" => url_action_alias(array("login")),
+ "index" => url_action_alias(array("login")),
+ /* _prelude guarantees that the user is logged in properly, so we do not have to care about that later, and sets some STE vars. */
+ "_prelude" => function(&$data, $url_now, &$url_next)
+ {
+ global $ratatoeskr_settings, $admin_grp, $ste, $languages;
+
+ if($admin_grp === NULL)
+ $admin_grp = Group::by_name("admins");
+
+ $ste->vars["all_languages"] = array();
+ $ste->vars["all_langcodes"] = array();
+ foreach($languages as $code => $data)
+ {
+ $ste->vars["all_languages"][$code] = $data["language"];
+ $ste->vars["all_langcodes"][] = $code;
+ }
+ ksort($ste->vars["all_languages"]);
+ sort($ste->vars["all_langcodes"]);
+
+
+ /* Check authentification */
+ if(isset($_SESSION["ratatoeskr_uid"]))
+ {
+ try
+ {
+ $user = User::by_id($_SESSION["ratatoeskr_uid"]);
+ if(($user->pwhash == $_SESSION["ratatoeskr_pwhash"]) and $user->member_of($admin_grp))
+ {
+ if(empty($user->language))
+ {
+ $user->language = $ratatoeskr_settings["default_language"];
+ $user->save();
+ }
+ load_language($user->language);
+
+ if($url_next[0] == "login")
+ $url_next = array("content", "write");
+ $data["user"] = $user;
+ $ste->vars["user"] = array("id" => $user->get_id(), "name" => $user->username, "lang" => $user->language);
+
+ return; /* Authentification successful, continue */
+ }
+ else
+ unset($_SESSION["ratatoeskr_uid"]);
+ }
+ catch(DoesNotExistError $e)
+ {
+ unset($_SESSION["ratatoeskr_uid"]);
+ }
+ }
+ load_language();
+
+ /* If we are here, user is not logged in... */
+ $url_next = array("login");
+ },
+ "login" => url_action_simple(function($data)
+ {
+ global $ste, $admin_grp;
+ if(!empty($_POST["user"]))
+ {
+ try
+ {
+ $user = User::by_name($_POST["user"]);
+ if(!PasswordHash::validate($_POST["password"], $user->pwhash))
+ throw new Exception();
+ if(!$user->member_of($admin_grp))
+ throw new Exception();
+
+ /* Login successful. */
+ $_SESSION["ratatoeskr_uid"] = $user->get_id();
+ $_SESSION["ratatoeskr_pwhash"] = $user->pwhash;
+ load_language($user->language);
+ $data["user"] = $user;
+ $ste->vars["user"] = array("id" => $user->get_id(), "name" => $user->username, "lang" => $user->language);
+ }
+ catch(Exception $e)
+ {
+ $ste->vars["login_failed"] = True;
+ }
+
+ if(isset($data["user"]))
+ throw new Redirect(array("content", "write"));
+ }
+
+ echo $ste->exectemplate("/systemtemplates/backend_login.html");
+ }),
+ "logout" => url_action_simple(function($data)
+ {
+ unset($_SESSION["ratatoeskr_uid"]);
+ unset($_SESSION["ratatoeskr_pwhash"]);
+ load_language();
+ throw new Redirect(array("login"));
+ }),
+ "content" => url_action_subactions(array(
+ "write" => function(&$data, $url_now, &$url_next)
+ {
+ global $ste, $translation, $textprocessors, $ratatoeskr_settings, $languages, $articleeditor_plugins;
+
+ list($article, $editlang) = array_slice($url_next, 0);
+ if(!isset($editlang))
+ $editlang = $data["user"]->language;
+ if(isset($article))
+ $ste->vars["article_editurl"] = urlencode($article) . "/" . urlencode($editlang);
+ else
+ $ste->vars["article_editurl"] = "";
+
+ $url_next = array();
+
+ $default_section = Section::by_id($ratatoeskr_settings["default_section"]);
+
+ $ste->vars["section"] = "content";
+ $ste->vars["submenu"] = isset($article) ? "articles" : "newarticle";
+
+ $ste->vars["textprocessors"] = array();
+ foreach($textprocessors as $txtproc => $properties)
+ if($properties[1])
+ $ste->vars["textprocessors"][] = $txtproc;
+
+ $ste->vars["sections"] = array();
+ foreach(Section::all() as $section)
+ $ste->vars["sections"][] = $section->name;
+ $ste->vars["article_section"] = $default_section->name;
+
+ /* Check Form */
+ $fail_reasons = array();
+
+ if(isset($_POST["save_article"]))
+ {
+ if(!Article::test_urlname($_POST["urlname"]))
+ $fail_reasons[] = $translation["invalid_urlname"];
+ else
+ $inputs["urlname"] = $_POST["urlname"];
+ if(!Article::test_status(@$_POST["article_status"]))
+ $fail_reasons[] = $translation["invalid_article_status"];
+ else
+ $inputs["article_status"] = (int) $_POST["article_status"];
+ if(!isset($textprocessors[@$_POST["content_txtproc"]]))
+ $fail_reasons[] = $translation["unknown_txtproc"];
+ else
+ $inputs["content_txtproc"] = $_POST["content_txtproc"];
+ if(!isset($textprocessors[@$_POST["excerpt_txtproc"]]))
+ $fail_reasons[] = $translation["unknown_txtproc"];
+ else
+ $inputs["excerpt_txtproc"] = $_POST["excerpt_txtproc"];
+ if(!empty($_POST["date"]))
+ {
+ if(($time_tmp = @DateTime::createFromFormat("Y-m-d H:i:s", @$_POST["date"])) === False)
+ $fail_reasons[] = $translation["invalid_date"];
+ else
+ $inputs["date"] = @$time_tmp->getTimestamp();
+ }
+ else
+ $inputs["date"] = time();
+ $inputs["allow_comments"] = !(empty($_POST["allow_comments"]) or ($_POST["allow_comments"] != "yes"));
+
+ try
+ {
+ $inputs["article_section"] = Section::by_name($_POST["section"]);
+ }
+ catch(DoesNotExistError $e)
+ {
+ $fail_reasons[] = $translation["unknown_section"];
+ }
+
+ $inputs["title"] = $_POST["title"];
+ $inputs["content"] = $_POST["content"];
+ $inputs["excerpt"] = $_POST["excerpt"];
+ $inputs["tags"] = array_filter(array_map("trim", explode(",", $_POST["tags"])), function($t) { return !empty($t); });
+ 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->excerpt[$editlang] = new Translation($inputs["excerpt"], $inputs["excerpt_txtproc"]);
+ $article->set_tags(maketags($inputs["tags"], $editlang));
+ $article->set_section($inputs["article_section"]);
+ $article->allow_comments = $inputs["allow_comments"];
+ }
+
+ if(empty($article))
+ {
+ /* New Article */
+ $ste->vars["pagetitle"] = $translation["new_article"];
+ if(empty($fail_reasons) and isset($_POST["save_article"]))
+ {
+ $article = Article::create($inputs["urlname"]);
+ fill_article($article, $inputs, $editlang);
+
+ /* Calling articleeditor plugins */
+ $call_after_save = array();
+ foreach($articleeditor_plugins as $plugin)
+ {
+ $result = call_user_func($plugin["fx"], $article, True);
+ if(is_string($result))
+ $fail_reasons[] = $result;
+ elseif($result !== NULL)
+ $call_after_save[] = $result;
+ }
+
+ if(empty($fail_reasons))
+ {
+ 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"];
+ }
+ }
+ }
+ }
+ else
+ {
+ try
+ {
+ if(!($article instanceof Article))
+ $article = Article::by_urlname($article);
+ }
+ catch(DoesNotExistError $e)
+ {
+ throw new NotFoundError();
+ }
+
+ if(empty($fail_reasons) and isset($_POST["save_article"]))
+ {
+ fill_article($article, $inputs, $editlang);
+
+ /* Calling articleeditor plugins */
+ $call_after_save = array();
+ foreach($articleeditor_plugins as $plugin)
+ {
+ $result = call_user_func($plugin["fx"], $article, True);
+ if(is_string($result))
+ $fail_reasons[] = $result;
+ elseif($result !== NULL)
+ $call_after_save[] = $result;
+ }
+
+ if(empty($fail_reasons))
+ {
+ 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"];
+ }
+ }
+ }
+
+ if(!isset($article->title[$editlang]))
+ {
+ $langs_available = array();
+ foreach($article->title as $lang => $_)
+ $langs_available[] = $lang;
+ $editlang = $langs_available[0];
+ }
+
+ foreach(array(
+ "urlname" => "urlname",
+ "status" => "article_status",
+ "timestamp" => "date",
+ "allow_comments" => "allow_comments"
+ ) as $prop => $k_out)
+ {
+ if(!isset($inputs[$k_out]))
+ $inputs[$k_out] = $article->$prop;
+ }
+ if(!isset($inputs["title"]))
+ $inputs["title"] = $article->title[$editlang]->text;
+ if(!isset($inputs["content"]))
+ {
+ $translation_obj = $article->text[$editlang];
+ $inputs["content"] = $translation_obj->text;
+ $inputs["content_txtproc"] = $translation_obj->texttype;
+ }
+ if(!isset($inputs["excerpt"]))
+ {
+ $translation_obj = $article->excerpt[$editlang];
+ $inputs["excerpt"] = $translation_obj->text;
+ $inputs["excerpt_txtproc"] = $translation_obj->texttype;
+ }
+ if(!isset($inputs["article_section"]))
+ $inputs["article_section"] = $article->get_section();
+ if(!isset($inputs["tags"]))
+ $inputs["tags"] = array_map(function($tag) use ($editlang) { return $tag->name; }, $article->get_tags());
+ $ste->vars["morelangs"] = array();
+ $ste->vars["pagetitle"] = $article->title[$editlang]->text;
+ foreach($article->title as $lang => $_)
+ {
+ if($lang != $editlang)
+ $ste->vars["morelangs"][] = array("url" => urlencode($article->urlname) . "/$lang", "full" => "($lang) " . $languages[$lang]["language"]);
+ }
+ }
+
+ if(!isset($inputs["date"]))
+ $inputs["date"] = time();
+ if(!isset($inputs["article_status"]))
+ $inputs["article_status"] = ARTICLE_STATUS_LIVE;
+
+ /* Push data back to template */
+ if(isset($inputs["tags"]))
+ $ste->vars["tags"] = implode(", ", $inputs["tags"]);
+ if(isset($inputs["article_section"]))
+ $ste->vars["article_section"] = $inputs["article_section"]->name;
+ $ste->vars["editlang"] = $editlang;
+ foreach(array(
+ "urlname" => "urlname",
+ "article_status" => "article_status",
+ "title" => "title",
+ "content_txtproc" => "content_txtproc",
+ "content" => "content",
+ "excerpt_txtproc" => "excerpt_txtproc",
+ "excerpt" => "excerpt",
+ "date" => "date",
+ "allow_comments" => "allow_comments"
+ ) as $k_in => $k_out)
+ {
+ if(isset($inputs[$k_in]))
+ $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;
+
+ echo $ste->exectemplate("/systemtemplates/content_write.html");
+ },
+ "tags" => function(&$data, $url_now, &$url_next)
+ {
+ global $translation, $languages, $ste, $rel_path_to_root;
+
+ $url_next = array();
+
+ $ste->vars["section"] = "content";
+ $ste->vars["submenu"] = "tags";
+ $ste->vars["pagetitle"] = $translation["tags_overview"];
+
+ if(isset($_POST["delete"]) and ($_POST["really_delete"] == "yes"))
+ {
+ foreach($_POST["tag_multiselect"] as $tagid)
+ {
+ try
+ {
+ $tag = Tag::by_id($tagid);
+ $tag->delete();
+ }
+ catch(DoesNotExistError $e)
+ {
+ continue;
+ }
+ }
+
+ $ste->vars["success"] = $translation["tags_successfully_deleted"];
+ }
+
+ if(isset($_POST["save_changes"]))
+ {
+ $newlang = (!empty($_POST["new_language"])) ? $_POST["new_language"] : NULL;
+ $newtag = NULL;
+
+ if(!empty($_POST["newtagname"]))
+ {
+ if(!Tag::test_name(@$_POST["newtagname"]))
+ $ste->vars["error"] = $translation["invalid_tag_name"];
+ else
+ $newtag = $_POST["newtagname"];
+ }
+
+ if(($newlang !== NULL) and (!isset($languages[$newlang])))
+ $newlang = NULL;
+ if($newtag !== NULL)
+ {
+ try
+ {
+ $newtag = Tag::create($newtag);
+ }
+ catch(AlreadyExistsError $e)
+ {
+ $newtag = NULL;
+ }
+ }
+
+ $translations = array();
+ foreach($_POST as $k => $v)
+ {
+ if(preg_match('/tagtrans_(NEW|[a-z]{2})_(.*)/', $k, $matches) == 1)
+ {
+ $lang = ($matches[1] == "NEW") ? $newlang : $matches[1];
+ $tag = $matches[2];
+ if($lang === NULL)
+ continue;
+ $translations[$tag][$lang] = $v;
+ }
+ }
+
+ foreach($translations as $tag => $langmap)
+ {
+ if($tag == "NEW")
+ {
+ if($newtag === NULL)
+ continue;
+ $tag = $newtag;
+ }
+ else
+ {
+ try
+ {
+ $tag = Tag::by_id($tag);
+ }
+ catch(DoesNotExistError $e)
+ {
+ continue;
+ }
+ }
+
+ foreach($langmap as $l => $text)
+ {
+ if(empty($text))
+ unset($tag->title[$l]);
+ else
+ $tag->title[$l] = new Translation($text, "");
+ }
+
+ $tag->save();
+ }
+
+ $ste->vars["success"] = $translation["tags_successfully_edited"];
+ }
+
+ $ste->vars["alltags"] = array();
+ $taglangs = array();
+
+ $alltags = Tag::all();
+ foreach($alltags as $tag)
+ {
+ $transls = array();
+ foreach($tag->title as $l => $t)
+ {
+ if(!in_array($l, $taglangs))
+ $taglangs[] = $l;
+ $transls[$l] = $t->text;
+ }
+
+ $ste->vars["alltags"][] = array(
+ "id" => $tag->get_id(),
+ "name" => $tag->name,
+ "translations" => $transls
+ );
+ }
+
+ $unused_langs = array_diff(array_keys($languages), $taglangs);
+
+ $ste->vars["all_tag_langs"] = array();
+ foreach($taglangs as $l)
+ $ste->vars["all_tag_langs"][$l] = $languages[$l]["language"];
+ $ste->vars["unused_languages"] = array();
+ foreach($unused_langs as $l)
+ $ste->vars["unused_languages"][$l] = $languages[$l]["language"];
+
+ echo $ste->exectemplate("/systemtemplates/tags_overview.html");
+ },
+ "articles" => function(&$data, $url_now, &$url_next)
+ {
+ global $ste, $translation, $languages, $rel_path_to_root;
+
+ $url_next = array();
+
+ $ste->vars["section"] = "content";
+ $ste->vars["submenu"] = "articles";
+ $ste->vars["pagetitle"] = $translation["menu_articles"];
+
+ if(isset($_POST["delete"]) and ($_POST["really_delete"] == "yes"))
+ {
+ foreach($_POST["article_multiselect"] as $article_urlname)
+ {
+ try
+ {
+ $article = Article::by_urlname($article_urlname);
+ $article->delete();
+ }
+ catch(DoesNotExistError $e)
+ {
+ continue;
+ }
+ }
+
+ $ste->vars["success"] = $translation["articles_deleted"];
+ }
+
+ $articles = Article::all();
+
+ /* Filtering */
+ $filterquery = array();
+ if(!empty($_GET["filter_urlname"]))
+ {
+ $searchfor = strtolower($_GET["filter_urlname"]);
+ $articles = array_filter($articles, function($a) use ($searchfor) { return strpos(strtolower($a->urlname), $searchfor) !== False; });
+ $filterquery[] = "filter_urlname=" . urlencode($_GET["filter_urlname"]);
+ $ste->vars["filter_urlname"] = $_GET["filter_urlname"];
+ }
+ if(!empty($_GET["filter_tag"]))
+ {
+ $searchfor = $_GET["filter_tag"];
+ $articles = array_filter($articles, function($a) use ($searchfor) { foreach($a->get_tags() as $t) { if($t->name==$searchfor) return True; } return False; });
+ $filterquery[] = "filter_tag=" . urlencode($searchfor);
+ $ste->vars["filter_tag"] = $searchfor;
+ }
+ if(!empty($_GET["filter_section"]))
+ {
+ $searchfor = $_GET["filter_section"];
+ $articles = array_filter($articles, function($a) use ($searchfor) { return $a->get_section()->name == $searchfor; });
+ $filterquery[] = "filter_section=" . urlencode($searchfor);
+ $ste->vars["filter_section"] = $searchfor;
+ }
+ $ste->vars["filterquery"] = implode("&", $filterquery);
+
+ /* Sorting */
+ if(isset($_GET["sort_asc"]))
+ {
+ switch($_GET["sort_asc"])
+ {
+ case "date":
+ $ste->vars["sortquery"] = "sort_asc=date";
+ $ste->vars["sort_asc_date"] = True;
+ $ste->vars["sorting"] = array("dir" => "asc", "by" => "date");
+ usort($articles, function($a, $b) { return intcmp($a->timestamp, $b->timestamp); });
+ break;
+ case "section":
+ $ste->vars["sortquery"] = "sort_asc=section";
+ $ste->vars["sort_asc_section"] = True;
+ $ste->vars["sorting"] = array("dir" => "asc", "by" => "section");
+ usort($articles, function($a, $b) { return strcmp($a->get_section()->name, $b->get_section()->name); });
+ break;
+ case "urlname":
+ $ste->vars["sortquery"] = "sort_asc=urlname";
+ default:
+ $ste->vars["sort_asc_urlname"] = True;
+ $ste->vars["sorting"] = array("dir" => "asc", "by" => "urlname");
+ usort($articles, function($a, $b) { return strcmp($a->urlname, $b->urlname); });
+ break;
+ }
+ }
+ elseif(isset($_GET["sort_desc"]))
+ {
+ switch($_GET["sort_desc"])
+ {
+ case "date":
+ $ste->vars["sortquery"] = "sort_desc=date";
+ $ste->vars["sort_desc_date"] = True;
+ $ste->vars["sorting"] = array("dir" => "desc", "by" => "date");
+ usort($articles, function($a, $b) { return intcmp($b->timestamp, $a->timestamp); });
+ break;
+ case "section":
+ $ste->vars["sortquery"] = "sort_desc=section";
+ $ste->vars["sort_desc_section"] = True;
+ $ste->vars["sorting"] = array("dir" => "desc", "by" => "section");
+ usort($articles, function($a, $b) { return strcmp($b->get_section()->name, $a->get_section()->name); });
+ break;
+ case "urlname":
+ $ste->vars["sortquery"] = "sort_desc=urlname";
+ $ste->vars["sort_desc_urlname"] = True;
+ $ste->vars["sorting"] = array("dir" => "desc", "by" => "urlname");
+ usort($articles, function($a, $b) { return strcmp($b->urlname, $a->urlname); });
+ break;
+ default:
+ $ste->vars["sort_asc_urlname"] = True;
+ $ste->vars["sorting"] = array("dir" => "asc", "by" => "urlname");
+ usort($articles, function($a, $b) { return strcmp($a->urlname, $b->urlname); });
+ break;
+ }
+ }
+ else
+ {
+ $ste->vars["sort_asc_urlname"] = True;
+ $ste->vars["sorting"] = array("dir" => "asc", "by" => "urlname");
+ usort($articles, function($a, $b) { return strcmp($a->urlname, $b->urlname); });
+ }
+
+ $ste->vars["articles"] = array_map(function($article) {
+ $avail_langs = array();
+ foreach($article->title as $lang => $_)
+ $avail_langs[] = $lang;
+ sort($avail_langs);
+ $a_section = $article->get_section();
+ return array(
+ "urlname" => $article->urlname,
+ "languages" => $avail_langs,
+ "date" => $article->timestamp,
+ "tags" => array_map(function($tag) { return $tag->name; }, $article->get_tags()),
+ "section" => array("id" => $a_section->get_id(), "name" => $a_section->name)
+ );
+ }, $articles);
+
+ echo $ste->exectemplate("/systemtemplates/articles.html");
+ },
+ "images" => function(&$data, $url_now, &$url_next)
+ {
+ global $ste, $translation, $languages, $rel_path_to_root;
+
+ list($imgid, $imageaction) = $url_next;
+
+ $url_next = array();
+
+ $ste->vars["section"] = "content";
+ $ste->vars["submenu"] = "images";
+ $ste->vars["pagetitle"] = $translation["menu_images"];
+
+ if(!empty($imgid) and is_numeric($imgid))
+ {
+ try
+ {
+ $image = Image::by_id($imgid);
+ }
+ catch(DoesNotExistError $e)
+ {
+ throw new NotFoundError();
+ }
+
+ if(empty($imageaction))
+ throw new NotFoundError();
+ else
+ {
+ if(($imageaction == "markdown") or ($imageaction == "html") or ($imageaction == "ste"))
+ {
+ $ste->vars["pagetitle"] = $translation["generate_embed_code"];
+ $ste->vars["image_id"] = $image->get_id();
+ $ste->vars["markup_variant"] = $imageaction;
+ if(isset($_POST["img_alt"]))
+ {
+ if($imageaction == "markdown")
+ $ste->vars["embed_code"] = "![" . str_replace("]", "\\]", $_POST["img_alt"]) . "](%root%/images/" . str_replace(")", "\\)", urlencode($image->get_filename())) . ")";
+ elseif($imageaction == "html")
+ $ste->vars["embed_code"] = "<img src=\"%root%/images/" . htmlesc(urlencode($image->get_filename())) . "\" alt=\"" . htmlesc($_POST["img_alt"]) . "\" />";
+ elseif($imageaction == "ste")
+ $ste->vars["embed_code"] = "<img src=\"\$rel_path_to_root/images/" . htmlesc(urlencode($image->get_filename())) . "\" alt=\"" . htmlesc($_POST["img_alt"]) . "\" />";
+ }
+
+ echo $ste->exectemplate("/systemtemplates/image_embed.html");
+ }
+ else
+ throw new NotFoundError();
+ }
+ return;
+ }
+
+ /* Upload Form */
+ if(isset($_POST["upload"]))
+ {
+ try
+ {
+ $image = Image::create((!empty($_POST["upload_name"])) ? $_POST["upload_name"] : $_FILES["upload_img"]["name"], $_FILES["upload_img"]["tmp_name"]);
+ $image->save();
+ $ste->vars["success"] = $translation["upload_success"];
+ }
+ catch(IOError $e)
+ {
+ $ste->vars["error"] = $translation["upload_failed"];
+ }
+ catch(UnknownFileFormat $e)
+ {
+ $ste->vars["error"] = $translation["unknown_file_format"];
+ }
+ }
+
+ /* Mass delete */
+ if(isset($_POST["delete"]) and ($_POST["really_delete"] == "yes"))
+ {
+ foreach($_POST["image_multiselect"] as $image_id)
+ {
+ try
+ {
+ $image = Image::by_id($image_id);
+ $image->delete();
+ }
+ catch(DoesNotExistError $e)
+ {
+ continue;
+ }
+ }
+
+ $ste->vars["success"] = $translation["images_deleted"];
+ }
+
+ $images = Image::all();
+
+ $ste->vars["images"] = array_map(function($img) { return array(
+ "id" => $img->get_id(),
+ "name" => $img->name,
+ "file" => $img->get_filename()
+ ); }, $images);
+
+ echo $ste->exectemplate("/systemtemplates/image_list.html");
+ },
+ "comments" => function(&$data, $url_now, &$url_next)
+ {
+ global $ste, $translation, $languages, $rel_path_to_root;
+
+ list($comment_id) = $url_next;
+
+ $url_next = array();
+
+ $ste->vars["section"] = "content";
+ $ste->vars["submenu"] = "comments";
+ $ste->vars["pagetitle"] = $translation["menu_comments"];
+
+ /* Single comment? */
+ if(!empty($comment_id))
+ {
+ try
+ {
+ $comment = Comment::by_id($comment_id);
+ }
+ catch(DoesNotExistError $e)
+ {
+ throw new NotFoundError();
+ }
+
+ if(!$comment->read_by_admin)
+ {
+ $comment->read_by_admin = True;
+ $comment->save();
+ }
+
+ if(isset($_POST["action_on_comment"]))
+ {
+ switch($_POST["action_on_comment"])
+ {
+ case "delete":
+ $comment->delete();
+ $ste->vars["success"] = $translation["comment_successfully_deleted"];
+ goto backend_content_comments_overview;
+ break;
+ case "make_visible":
+ $comment->visible = True;
+ $comment->save();
+ $ste->vars["success"] = $translation["comment_successfully_made_visible"];
+ break;
+ case "make_invisible":
+ $comment->visible = False;
+ $comment->save();
+ $ste->vars["success"] = $translation["comment_successfully_made_invisible"];
+ break;
+ }
+ }
+
+ $ste->vars["id"] = $comment->get_id();
+ $ste->vars["visible"] = $comment->visible;
+ $ste->vars["article"] = $comment->get_article()->urlname;
+ $ste->vars["language"] = $comment->get_language();
+ $ste->vars["date"] = $comment->get_timestamp();
+ $ste->vars["author"] = "\"{$comment->author_name}\" <{$comment->author_mail}>";
+ $ste->vars["comment_text"] = $comment->create_html();
+ $ste->vars["comment_raw"] = $comment->text;
+
+ echo $ste->exectemplate("/systemtemplates/single_comment.html");
+ return;
+ }
+
+ backend_content_comments_overview:
+
+ /* Perform an action on all selected comments */
+ if(!empty($_POST["action_on_comments"]))
+ {
+ switch($_POST["action_on_comments"])
+ {
+ case "delete":
+ $commentaction = function($c) { $c->delete(); };
+ $ste->vars["success"] = $translation["comments_successfully_deleted"];
+ break;
+ case "mark_read":
+ $commentaction = function($c) { $c->read_by_admin = True; $c->save(); };
+ $ste->vars["success"] = $translation["comments_successfully_marked_read"];
+ break;
+ case "mark_unread":
+ $commentaction = function($c) { $c->read_by_admin = False; $c->save(); };
+ $ste->vars["success"] = $translation["comments_successfully_marked_unread"];
+ break;
+ case "make_visible":
+ $commentaction = function($c) { $c->visible = True; $c->save(); };
+ $ste->vars["success"] = $translation["comments_successfully_made_visible"];
+ break;
+ case "make_invisible":
+ $commentaction = function($c) { $c->visible = False; $c->save(); };
+ $ste->vars["success"] = $translation["comments_successfully_made_invisible"];
+ break;
+ default;
+ $ste->vars["error"] = $translation["unknown_action"];
+ break;
+ }
+ if(isset($commentaction))
+ {
+ foreach($_POST["comment_multiselect"] as $c_id)
+ {
+ try
+ {
+ $comment = Comment::by_id($c_id);
+ $commentaction($comment);
+ }
+ catch(DoesNotExistError $e)
+ {
+ continue;
+ }
+ }
+ }
+ }
+
+ $comments = Comment::all();
+
+ /* Filtering */
+ $filterquery = array();
+ if(!empty($_GET["filter_article"]))
+ {
+ $searchfor = strtolower($_GET["filter_article"]);
+ $comments = array_filter($comments, function($c) use ($searchfor) { return strpos(strtolower($c->get_article()->urlname), $searchfor) !== False; });
+ $filterquery[] = "filter_article=" . urlencode($_GET["filter_article"]);
+ $ste->vars["filter_article"] = $_GET["filter_article"];
+ }
+ $ste->vars["filterquery"] = implode("&", $filterquery);
+
+ /* Sorting */
+ if(isset($_GET["sort_asc"]))
+ {
+ $sort_dir = 1;
+ $sort_by = $_GET["sort_asc"];
+ }
+ elseif(isset($_GET["sort_desc"]))
+ {
+ $sort_dir = -1;
+ $sort_by = $_GET["sort_desc"];
+ }
+ else
+ {
+ $sort_dir = 1;
+ $sort_by = "was_read";
+ }
+
+ switch($sort_by)
+ {
+ case "language":
+ usort($comments, function($a, $b) use ($sort_dir) { return strcmp($a->get_language(), $b->get_language()) * $sort_dir; });
+ break;
+ case "date":
+ usort($comments, function($a, $b) use ($sort_dir) { return intcmp($a->get_timestamp(), $b->get_timestamp()) * $sort_dir; });
+ break;
+ case "was_read":
+ default:
+ usort($comments, function($a, $b) use ($sort_dir) { return intcmp((int) $a->read_by_admin, (int) $b->read_by_admin) * $sort_dir; });
+ $sort_by = "was_read";
+ break;
+ }
+ $ste->vars["sortquery"] = "sort_" . ($sort_dir == 1 ? "asc" : "desc") . "=$sort_by";
+ $ste->vars["sorting"] = array("dir" => ($sort_dir == 1 ? "asc" : "desc"), "by" => $sort_by);
+ $ste->vars["sort_" . ($sort_dir == 1 ? "asc" : "desc") . "_$sort_by"] = True;
+
+ $ste->vars["comments"] = array_map(function($c) { return array(
+ "id" => $c->get_id(),
+ "visible" => $c->visible,
+ "read_by_admin" => $c->read_by_admin,
+ "article" => $c->get_article()->urlname,
+ "excerpt" => substr(str_replace(array("\r\n", "\n", "\r"), " ", $c->text), 0, 50),
+ "language" => $c->get_language(),
+ "date" => $c->get_timestamp(),
+ "author" => "\"{$c->author_name}\" <{$c->author_mail}>"
+ ); }, $comments);
+
+ echo $ste->exectemplate("/systemtemplates/comments_list.html");
+ }
+ )),
+ "design" => url_action_subactions(array(
+ "templates" => function(&$data, $url_now, &$url_next)
+ {
+ global $ste, $translation, $languages, $rel_path_to_root;
+
+ list($template) = $url_next;
+
+ $url_next = array();
+
+ $ste->vars["section"] = "design";
+ $ste->vars["submenu"] = "templates";
+ $ste->vars["pagetitle"] = $translation["menu_templates"];
+
+ if(isset($template))
+ {
+ if(preg_match("/^[a-zA-Z0-9\\-_\\.]+$/", $template) == 0) /* Prevent a possible LFI attack. */
+ throw new NotFoundError();
+ if(!is_file(SITE_BASE_PATH . "/ratatoeskr/templates/src/usertemplates/$template"))
+ throw new NotFoundError();
+ $ste->vars["template_name"] = $template;
+ $ste->vars["template_code"] = file_get_contents(SITE_BASE_PATH . "/ratatoeskr/templates/src/usertemplates/$template");
+ }
+
+ /* Was there a delete request? */
+ if(isset($_POST["delete"]) and ($_POST["really_delete"] == "yes"))
+ {
+ foreach($_POST["templates_multiselect"] as $tplname)
+ {
+ if(preg_match("/^[a-zA-Z0-9\\-_\\.]+$/", $tplname) == 0) /* Prevent a possible LFI attack. */
+ continue;
+ if(is_file(SITE_BASE_PATH . "/ratatoeskr/templates/src/usertemplates/$tplname"))
+ @unlink(SITE_BASE_PATH . "/ratatoeskr/templates/src/usertemplates/$tplname");
+ }
+ $ste->vars["success"] = $translation["templates_successfully_deleted"];
+ }
+
+ /* A write request? */
+ if(isset($_POST["save_template"]))
+ {
+ if(preg_match("/^[a-zA-Z0-9\\-_\\.]+$/", $_POST["template_name"]) == 1)
+ {
+ $ste->vars["template_name"] = $_POST["template_name"];
+ $ste->vars["template_code"] = $_POST["template_code"];
+
+ try
+ {
+ \ste\transcompile(\ste\parse(\ste\precompile($_POST["template_code"]), $_POST["template_name"]));
+ file_put_contents(SITE_BASE_PATH . "/ratatoeskr/templates/src/usertemplates/" . $_POST["template_name"], $_POST["template_code"]);
+ $ste->vars["success"] = $translation["template_successfully_saved"];
+ }
+ catch(\ste\ParseCompileError $e)
+ {
+ $e->rewrite($_POST["template_code"]);
+ $ste->vars["error"] = $translation["could_not_compile_template"] . $e->getMessage();
+ }
+ }
+ else
+ $ste->vars["error"] = $translation["invalid_template_name"];
+ }
+
+ /* Get all templates */
+ $ste->vars["templates"] = array();
+ $tpldir = new DirectoryIterator(SITE_BASE_PATH . "/ratatoeskr/templates/src/usertemplates");
+ foreach($tpldir as $fo)
+ {
+ if($fo->isFile())
+ $ste->vars["templates"][] = $fo->getFilename();
+ }
+ sort($ste->vars["templates"]);
+
+ echo $ste->exectemplate("/systemtemplates/templates.html");
+ },
+ "styles" => function(&$data, $url_now, &$url_next)
+ {
+ global $ste, $translation, $languages, $rel_path_to_root;
+
+ list($style) = $url_next;
+
+ $url_next = array();
+
+ $ste->vars["section"] = "design";
+ $ste->vars["submenu"] = "styles";
+ $ste->vars["pagetitle"] = $translation["menu_styles"];
+
+ if(isset($style))
+ {
+ try
+ {
+ $style = Style::by_name($style);
+ $ste->vars["style_name"] = $style->name;
+ $ste->vars["style_code"] = $style->code;
+ }
+ catch(DoesNotExistError $e)
+ {
+ throw new NotFoundError();
+ }
+ }
+
+ /* Was there a delete request? */
+ if(isset($_POST["delete"]) and ($_POST["really_delete"] == "yes"))
+ {
+ foreach($_POST["styles_multiselect"] as $stylename)
+ {
+ try
+ {
+ $style = Style::by_name($stylename);
+ $style->delete();
+ }
+ catch(DoesNotExistError $e)
+ {
+ continue;
+ }
+ }
+ $ste->vars["success"] = $translation["styles_successfully_deleted"];
+ }
+
+ /* A write request? */
+ if(isset($_POST["save_style"]))
+ {
+ if(Style::test_name($_POST["style_name"]))
+ {
+ $ste->vars["style_name"] = $_POST["style_name"];
+ $ste->vars["style_code"] = $_POST["style_code"];
+
+ try
+ {
+ $style = Style::by_name($_POST["style_name"]);
+ }
+ catch(DoesNotExistError $e)
+ {
+ $style = Style::create($_POST["style_name"]);
+ }
+
+ $style->code = $_POST["style_code"];
+ $style->save();
+
+ $ste->vars["success"] = $translation["style_successfully_saved"];
+ }
+ else
+ $ste->vars["error"] = $translation["invalid_style_name"];
+ }
+
+ /* Get all styles */
+ $ste->vars["styles"] = array_map(function($s) { return $s->name; }, Style::all());
+ sort($ste->vars["styles"]);
+
+ echo $ste->exectemplate("/systemtemplates/styles.html");
+ },
+ "sections" => function(&$data, $url_now, &$url_next)
+ {
+ global $ste, $translation, $languages, $rel_path_to_root, $ratatoeskr_settings;
+
+ list($style) = $url_next;
+
+ $url_next = array();
+
+ $ste->vars["section"] = "design";
+ $ste->vars["submenu"] = "sections";
+ $ste->vars["pagetitle"] = $translation["menu_pagesections"];
+
+ /* New section? */
+ if(isset($_POST["new_section"]))
+ {
+ try
+ {
+ Section::by_name($_POST["section_name"]);
+ $ste->vars["error"] = $translation["section_already_exists"];
+ }
+ catch(DoesNotExistError $e)
+ {
+ if((preg_match("/^[a-zA-Z0-9\\-_\\.]+$/", $_POST["template"]) == 0) or (!is_file(SITE_BASE_PATH . "/ratatoeskr/templates/src/usertemplates/{$_POST['template']}")))
+ $ste->vars["error"] = $translation["unknown_template"];
+ else if(!Section::test_name($_POST["section_name"]))
+ $ste->vars["error"] = $translation["invalid_section_name"];
+ else
+ {
+ $section = Section::create($_POST["section_name"]);
+ $section->template = $_POST["template"];
+ $section->title[$data["user"]->language] = new Translation($_POST["section_name"], "");
+ $section->save();
+ $ste->vars["success"] = $translation["section_created_successfully"];
+ }
+ }
+ }
+
+ /* Remove a style? */
+ if(isset($_GET["rmstyle"]) and isset($_GET["rmfrom"]))
+ {
+ try
+ {
+ $section = Section::by_name($_GET["rmfrom"]);
+ $style = Style::by_name($_GET["rmstyle"]);
+ $section->remove_style($style);
+ $section->save();
+ $ste->vars["success"] = $translation["style_removed"];
+ }
+ catch(DoesNotExistError $e)
+ {
+ }
+ }
+
+ /* Delete a section? */
+ if(isset($_POST["delete"]) and (@$_POST["really_delete"] == "yes") and isset($_POST["section_select"]))
+ {
+ try
+ {
+ $section = Section::by_name($_POST["section_select"]);
+ if($section->get_id() == $ratatoeskr_settings["default_section"])
+ $ste->vars["error"] = $translation["cannot_delete_default_section"];
+ else
+ {
+ $default_section = Section::by_id($ratatoeskr_settings["default_section"]);
+ foreach($section->get_articles() as $article)
+ {
+ $article->set_section($default_section);
+ $article->save();
+ }
+ $section->delete();
+ $ste->vars["success"] = $translation["section_successfully_deleted"];
+ }
+ }
+ catch(DoesNotExistError $e)
+ {
+ }
+ }
+
+ /* Make section default? */
+ if(isset($_POST["make_default"]) and isset($_POST["section_select"]))
+ {
+ try
+ {
+ $section = Section::by_name($_POST["section_select"]);
+ $ratatoeskr_settings["default_section"] = $section->get_id();
+ $ste->vars["success"] = $translation["default_section_changed_successfully"];
+ }
+ catch(DoesNotExistError $e)
+ {
+ }
+ }
+
+ /* Set template? */
+ if(isset($_POST["set_template"]) and isset($_POST["section_select"]))
+ {
+ try
+ {
+ $section = Section::by_name($_POST["section_select"]);
+ if((preg_match("/^[a-zA-Z0-9\\-_\\.]+$/", $_POST["set_template_to"]) == 0) or (!is_file(SITE_BASE_PATH . "/ratatoeskr/templates/src/usertemplates/{$_POST['set_template_to']}")))
+ $ste->vars["error"] = $translation["unknown_template"];
+ else
+ {
+ $section->template = $_POST["set_template_to"];
+ $section->save();
+ $ste->vars["success"] = $translation["successfully_set_template"];
+ }
+ }
+ catch(DoesNotExistError $e)
+ {
+ }
+ }
+
+ /* Adding a style? */
+ if(isset($_POST["add_style"]) and isset($_POST["section_select"]))
+ {
+ try
+ {
+ $section = Section::by_name($_POST["section_select"]);
+ $style = Style::by_name($_POST["style_to_add"]);
+ $section->add_style($style);
+ $ste->vars["success"] = $translation["successfully_added_style"];
+ }
+ catch(DoesNotExistError $e)
+ {
+ }
+ }
+
+ /* Set/unset title? */
+ if(isset($_POST["set_title"]) and isset($_POST["section_select"]))
+ {
+ if(!isset($languages[$_POST["set_title_lang"]]))
+ $ste->vars["error"] = $translation["language_unknown"];
+ else
+ {
+ try
+ {
+ $section = Section::by_name($_POST["section_select"]);
+ if(!empty($_POST["set_title_text"]))
+ $section->title[$_POST["set_title_lang"]] = new Translation($_POST["set_title_text"], "");
+ else if(isset($section->title[$_POST["set_title_lang"]]))
+ unset($section->title[$_POST["set_title_lang"]]);
+ $section->save();
+ $ste->vars["success"] = $translation["successfully_set_section_title"];
+ }
+ catch(DoesNotExistError $e)
+ {
+ }
+ }
+ }
+
+ /* Get all templates */
+ $ste->vars["templates"] = array();
+ $tpldir = new DirectoryIterator(SITE_BASE_PATH . "/ratatoeskr/templates/src/usertemplates");
+ foreach($tpldir as $fo)
+ {
+ if($fo->isFile())
+ $ste->vars["templates"][] = $fo->getFilename();
+ }
+ sort($ste->vars["templates"]);
+
+ /* Get all styles */
+ $ste->vars["styles"] = array_map(function($s) { return $s->name; }, Style::all());
+ sort($ste->vars["styles"]);
+
+ /* Get all sections */
+ $sections = Section::all();
+ $ste->vars["sections"] = array_map(function($section) use ($ratatoeskr_settings) {
+ $titles = array();
+ foreach($section->title as $l => $t)
+ $titles[$l] = $t->text;
+ return array(
+ "name" => $section->name,
+ "title" => $titles,
+ "template" => $section->template,
+ "styles" => array_map(function($style) { return $style->name; }, $section->get_styles()),
+ "default" => ($section->get_id() == $ratatoeskr_settings["default_section"])
+ );
+ }, $sections);
+
+ echo $ste->exectemplate("/systemtemplates/sections.html");
+ }
+ )),
+ "admin" => url_action_subactions(array(
+ "settings" => function(&$data, $url_now, &$url_next)
+ {
+ global $ste, $translation, $languages, $rel_path_to_root, $ratatoeskr_settings, $textprocessors;
+
+ $url_next = array();
+
+ $ste->vars["section"] = "admin";
+ $ste->vars["submenu"] = "settings";
+ $ste->vars["pagetitle"] = $translation["menu_settings"];
+
+ $ste->vars["textprocessors"] = array();
+ foreach($textprocessors as $txtproc => $properties)
+ if($properties[1])
+ $ste->vars["textprocessors"][] = $txtproc;
+
+ /* Toggle debugmode value? */
+ if(isset($_POST["toggle_debugmode"]))
+ {
+ if(isset($ratatoeskr_settings["debugmode"]) and $ratatoeskr_settings["debugmode"])
+ {
+ $ratatoeskr_settings["debugmode"] = False;
+ $ste->vars["success"] = $translation["debugmode_now_disabled"];
+ }
+ else
+ {
+ $ratatoeskr_settings["debugmode"] = True;
+ $ste->vars["success"] = $translation["debugmode_now_enabled"];
+ }
+ }
+
+ /* Save comment settings? */
+ if(isset($_POST["save_comment_settings"]))
+ {
+ if(!in_array(@$_POST["comment_textprocessor"], $ste->vars["textprocessors"]))
+ $ste->vars["error"] = $translation["unknown_txtproc"];
+ else
+ {
+ $ratatoeskr_settings["comment_textprocessor"] = $_POST["comment_textprocessor"];
+ $ratatoeskr_settings["comment_visible_default"] = (isset($_POST["comment_auto_visible"]) and ($_POST["comment_auto_visible"] == "yes"));
+ $ste->vars["success"] = $translation["comment_settings_successfully_saved"];
+ }
+ }
+
+ /* Delete language? */
+ if(isset($_POST["delete"]) and ($_POST["really_delete"] == "yes") and isset($_POST["language_select"]))
+ {
+ if($ratatoeskr_settings["default_language"] == $_POST["language_select"])
+ $ste->vars["error"] = $translation["cannot_delete_default_language"];
+ else
+ {
+ $ratatoeskr_settings["languages"] = array_filter($ratatoeskr_settings["languages"], function($l) { return $l != $_POST["language_select"]; });
+ $ste->vars["success"] = $translation["language_successfully_deleted"];
+ }
+ }
+
+ /* Set default language */
+ if(isset($_POST["make_default"]) and isset($_POST["language_select"]))
+ {
+ if(in_array($_POST["language_select"], $ratatoeskr_settings["languages"]))
+ {
+ $ratatoeskr_settings["default_language"] = $_POST["language_select"];
+ $ste->vars["success"] = $translation["successfully_set_default_language"];
+ }
+ }
+
+ /* Add a language */
+ if(isset($_POST["add_language"]))
+ {
+ if(!isset($languages[$_POST["language_to_add"]]))
+ $ste->vars["error"] = $translation["language_unknown"];
+ else
+ {
+ if(!in_array($_POST["language_to_add"], $ratatoeskr_settings["languages"]))
+ {
+ $ls = $ratatoeskr_settings["languages"];
+ $ls[] = $_POST["language_to_add"];
+ $ratatoeskr_settings["languages"] = $ls;
+ }
+ $ste->vars["success"] = $translation["language_successfully_added"];
+ }
+ }
+
+ $ste->vars["debugmode_enabled"] = (isset($ratatoeskr_settings["debugmode"]) and $ratatoeskr_settings["debugmode"]);
+ $ste->vars["comment_auto_visible"] = $ratatoeskr_settings["comment_visible_default"];
+ $ste->vars["comment_textprocessor"] = $ratatoeskr_settings["comment_textprocessor"];
+ $ste->vars["used_langs"] = array_map(function ($l) use ($ratatoeskr_settings, $languages) { return array(
+ "code" => $l,
+ "name" => $languages[$l]["language"],
+ "default" => ($l == $ratatoeskr_settings["default_language"])
+ );}, $ratatoeskr_settings["languages"]);
+
+ echo $ste->exectemplate("/systemtemplates/settings.html");
+ },
+ "users" => url_action_subactions(array(
+ "_index" => function(&$data, $url_now, &$url_next)
+ {
+ global $ste, $translation, $languages, $rel_path_to_root, $ratatoeskr_settings, $textprocessors;
+
+ $url_next = array();
+
+ $ste->vars["section"] = "admin";
+ $ste->vars["submenu"] = "users";
+ $ste->vars["pagetitle"] = $translation["menu_users_groups"];
+
+ /* Add a new group? */
+ if(isset($_POST["new_group"]))
+ {
+ if(empty($_POST["group_name"]))
+ $ste->vars["error"] = $translation["empty_group_name"];
+ else
+ {
+ try
+ {
+ Group::by_name($_POST["group_name"]);
+ $ste->vars["error"] = $translation["group_already_exists"];
+ }
+ catch(DoesNotExistError $e)
+ {
+ $group = Group::create($_POST["group_name"]);
+ $ste->vars["success"] = $translation["successfully_created_group"];
+ }
+ }
+ }
+
+ /* Add a new user? */
+ if(isset($_POST["new_user"]))
+ {
+ if(empty($_POST["username"]))
+ $ste->vars["error"] = $translation["empty_username"];
+ else
+ {
+ try
+ {
+ User::by_name($_POST["username"]);
+ $ste->vars["error"] = $translation["user_already_exists"];
+ }
+ catch(DoesNotExistError $e)
+ {
+ $group = User::create($_POST["username"], PasswordHash::create($_POST["initial_password"]));
+ $ste->vars["success"] = $translation["successfully_created_user"];
+ }
+ }
+ }
+
+ /* Delete groups? */
+ if(isset($_POST["delete_groups"]) and ($_POST["really_delete"] == "yes") and (!empty($_POST["groups_multiselect"])))
+ {
+ $deleted = 0;
+ foreach($_POST["groups_multiselect"] as $gid)
+ {
+ try
+ {
+ $group = Group::by_id($gid);
+ if($group->name == "admins")
+ {
+ $ste->vars["error"] = $translation["cannot_delete_admin_group"];
+ }
+ else
+ {
+ $group->delete();
+ ++$deleted;
+ }
+ }
+ catch(DoesNotExistError $e)
+ {
+ continue;
+ }
+ }
+ if($deleted > 0)
+ $ste->vars["success"] = $translation["successfully_deleted_groups"];
+ }
+
+ /* Delete users? */
+ if(isset($_POST["delete_users"]) and ($_POST["really_delete"] == "yes") and (!empty($_POST["users_multiselect"])))
+ {
+ $deleted = 0;
+ foreach($_POST["users_multiselect"] as $uid)
+ {
+ if($uid == $data["user"]->get_id())
+ $ste->vars["error"] = $translation["cannot_delete_yourself"];
+ else
+ {
+ try
+ {
+ $user = User::by_id($uid);
+ $user->delete();
+ ++$deleted;
+ }
+ catch(DoesNotExistError $e)
+ {
+ continue;
+ }
+ }
+ }
+ if($deleted > 0)
+ $ste->vars["success"] = $translation["successfully_deleted_users"];
+ }
+
+ /* Get all groups */
+ $ste->vars["groups"] = array_map(function($g) { return array(
+ "id" => $g->get_id(),
+ "name" => $g->name
+ ); }, Group::all());
+
+ /* Get all users */
+ $ste->vars["users"] = array_map(function($u) { return array(
+ "id" => $u->get_id(),
+ "name" => $u->username,
+ "memberof" => array_map(function($g) { return $g->name; }, $u->get_groups()),
+ "fullname" => $u->fullname,
+ "mail" => $u->mail
+ ); }, User::all());
+
+ echo $ste->exectemplate("/systemtemplates/users.html");
+ },
+ "u" => function(&$data, $url_now, &$url_next)
+ {
+ global $ste, $translation, $languages, $rel_path_to_root, $admin_grp;
+
+ try
+ {
+ $user = User::by_id($url_next[0]);
+ }
+ catch(DoesNotExistError $e)
+ {
+ throw new NotFoundError();
+ }
+
+ $url_next = array();
+
+ $ste->vars["section"] = "admin";
+ $ste->vars["submenu"] = "users";
+ $ste->vars["pagetitle"] = $user->username;
+
+ /* Modify data? */
+ if(isset($_POST["change_data"]))
+ {
+ $user->fullname = $_POST["fullname"];
+ $user->mail = $_POST["mail"];
+ $user->language = $_POST["lang"];
+
+ $current_groups = array_map(function($g) { return $g->get_id(); }, $user->get_groups());
+ $new_groups = empty($_POST[groups_multiselect]) ? array() : $_POST["groups_multiselect"];
+ $groups_exclude = array_diff($current_groups, $new_groups);
+ $groups_include = array_diff($new_groups, $current_groups);
+
+ foreach($groups_exclude as $gid)
+ {
+ try
+ {
+ $g = Group::by_id($gid);
+ $g->exclude_user($user);
+ }
+ catch(DoesNotExistError $e)
+ {
+ continue;
+ }
+ }
+
+ foreach($groups_include as $gid)
+ {
+ try
+ {
+ $g = Group::by_id($gid);
+ $g->include_user($user);
+ }
+ catch(DoesNotExistError $e)
+ {
+ continue;
+ }
+ }
+
+ $user->save();
+
+ $ste->vars["success"] = $translation["successfully_modified_user"];
+ }
+
+ /* New Password? */
+ if(isset($_POST["new_password"]))
+ {
+ $pwhash = PasswordHash::create($_POST["password"]);
+ $user->pwhash = $pwhash;
+ if($user->get_id() == $data["user"]->get_id())
+ $_SESSION["ratatoeskr_pwhash"] = $pwhash;
+ $user->save();
+
+ $ste->vars["success"] = $translation["successfully_set_new_password"];
+ }
+
+ /* Put data to STE */
+ $ste->vars["u"] = array(
+ "id" => $user->get_id(),
+ "name" => $user->username,
+ "fullname" => $user->fullname,
+ "mail" => $user->mail,
+ "lang" => $user->language
+ );
+ $ste->vars["groups"] = array_map(function($g) use ($user) { return array(
+ "id" => $g->get_id(),
+ "name" => $g->name,
+ "member" => $user->member_of($g)
+ ); }, Group::all());
+
+ 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"];
+
+ /* Add a repo? */
+ if(isset($_POST["add_repo"]))
+ {
+ try
+ {
+ $repo = Repository::create($_POST["repo_baseurl"]);
+ $ste->vars["success"] = $translation["successfully_added_repo"];
+ }
+ catch(RepositoryUnreachableOrInvalid $e)
+ {
+ $ste->vars["error"] = $translation["repository_unreachable_or_invalid"];
+ }
+ }
+
+ /* Delete repos? */
+ if(isset($_POST["delete_repos"]) and ($_POST["really_delete"] == "yes"))
+ {
+ foreach($_POST["repos_multiselect"] as $repo_id)
+ {
+ try
+ {
+ $repo = Repository::by_id($repo_id);
+ $repo->delete();
+ }
+ catch(DoesNotExistError $e)
+ {
+ continue;
+ }
+ }
+ $ste->vars["success"] = $translation["repos_deleted"];
+ }
+
+ /* Force refresh? */
+ if(isset($_POST["force_repo_refresh"]))
+ {
+ $failed = array();
+ foreach($_POST["repos_multiselect"] as $repo_id)
+ {
+ try
+ {
+ $repo = Repository::by_id($repo_id);
+ $repo->refresh(True);
+ }
+ catch(DoesNotExistError $e)
+ {
+ continue;
+ }
+ catch(RepositoryUnreachableOrInvalid $e)
+ {
+ $failed[] = $repo->get_name();
+ }
+ }
+ $ste->vars["success"] = $translation["successfully_refreshed_repos"];
+ if(!empty($failed))
+ $ste->vars["error"] = str_replace("[[REPOS]]", implode(", ", $failed), $translation["repo_refresh_failed_on"]);
+ }
+
+ /* Fill data */
+ $all_repos = Repository::all();
+ $ste->vars["repos"] = array_map(
+ function($r)
+ {
+ try
+ {
+ $r->refresh();
+ }
+ catch(RepositoryUnreachableOrInvalid $e){}
+ return array(
+ "id" => $r->get_id(),
+ "name" => $r->get_name(),
+ "description" => $r->get_description(),
+ "baseurl" => $r->get_baseurl()
+ );
+ }, $all_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, $api_compat;
+
+ $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") or ($_POST["really_delete"] == "force")) and (!empty($_POST["plugins_multiselect"])))
+ {
+ foreach($_POST["plugins_multiselect"] as $pid)
+ {
+ try
+ {
+ $plugin = Plugin::by_id($pid);
+ if($_POST["really_delete"] != "force")
+ {
+ 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"])))
+ {
+ $api_incompat = array();
+ $newstatus = isset($_POST["activate"]);
+ foreach($_POST["plugins_multiselect"] as $pid)
+ {
+ try
+ {
+ $plugin = Plugin::by_id($pid);
+ if(!$plugin->installed)
+ continue;
+ if($newstatus and (!in_array($plugin->api, $api_compat)))
+ {
+ $api_incompat[] = $plugin->name . ("(ID: " . $plugin->get_id() . ")");
+ 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"];
+
+ if(!empty($api_incompat))
+ $ste->vars["error"] = htmlesc(str_replace("[[PLUGINS]]", implode(", ", $api_incompat), $translation["could_not_activate_plugin_api_incompat"]));
+ }
+
+ $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"]+0) > ($plugin->versioncount+0)))
+ {
+ $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();
+ $api_incompat = array();
+ foreach($all_plugins as $p)
+ {
+ if(!$p->installed)
+ continue;
+
+ if(!in_array($p->api, $api_compat))
+ $api_incompat[] = $p->name . ("(ID: " . $p->get_id() . ")");
+
+ $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)
+ );
+ }
+
+ if(!empty($api_incompat))
+ $ste->vars["notice"] = htmlesc(str_replace("[[PLUGINS]]", implode(", ", $api_incompat), $translation["plugins_incompat"]));
+
+ 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"];
+
+ $all_repos = Repository::all();
+ foreach($all_repos as $repo)
+ {
+ try
+ {
+ $repo->refresh();
+ }
+ catch(RepositoryUnreachableOrInvalid $e)
+ {
+ continue;
+ }
+ }
+
+ 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"];
+ }
+
+ if(isset($_POST["search_in_repos"]))
+ {
+ $ste->vars["searchresults"] = array();
+ $repos_to_scan = ($_POST["searchin"] == "*") ? $all_repos : Repository::by_id($_POST["searchin"]);
+ $searchfor = strtolower($_POST["searchfor"]);
+ foreach($repos_to_scan as $repo)
+ {
+ foreach($repo->packages as $pkg)
+ {
+ if(empty($searchfor) or (strpos(strtolower($pkg[0]), $searchfor) !== False) or (strpos(strtolower($pkg[2]), $searchfor) !== False))
+ $ste->vars["searchresults"][] = array(
+ "name" => $pkg[0],
+ "description" => $pkg[2],
+ "reponame" => $repo->get_name(),
+ "repoid" => $repo->get_id()
+ );
+ }
+ }
+ }
+
+ $ste->vars["repos"] = array_map(function($r) { return array(
+ "id" => $r->get_id(),
+ "name" => $r->get_name()
+ ); }, $all_repos);
+
+ echo $ste->exectemplate("/systemtemplates/plugininstall.html");
+ },
+ "repoinstall" => function(&$data, $url_now, &$url_next)
+ {
+ global $ste, $translation, $rel_path_to_root;
+
+ $stream_ctx = stream_context_create(array("http" => array("timeout" => 5)));
+
+ try
+ {
+ $repo = Repository::by_id($_GET["repo"]);
+ $pkg = $repo->download_package($_GET["pkg"]);
+ $plugin = Plugin::create();
+ $plugin->fill_from_pluginpackage($pkg);
+ $plugin->installed = False;
+ $plugin->active = False;
+ $plugin->save();
+ $url_next = array("confirminstall", (string) $plugin->get_id());
+ }
+ catch(DoesNotExistError $e)
+ {
+ $ste->vars["error"] = $translation["package_or_repo_not_found"];
+ $url_next = array("install");
+ }
+ catch(InvalidPackage $e)
+ {
+ $ste->vars["error"] = $translation["invalid_package"];
+ $url_next = array("install");
+ }
+ },
+ "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)
));
}