From 37ae61fe6d76f72e4bd5567256ee4dd494649dab Mon Sep 17 00:00:00 2001 From: Kevin Chabowski Date: Wed, 9 Nov 2011 23:31:45 +0100 Subject: Hooray! First backend function implemented (content/write)! And it only took over a month. That's what I call efficiency.... NOT! --- ratatoeskr/backend/main.php | 240 ++++++++++++++++++++- ratatoeskr/cms_style/layout.css | 32 ++- .../src/systemtemplates/content_write.html | 159 +++++++++++++- ratatoeskr/translations/en.php | 12 +- 4 files changed, 423 insertions(+), 20 deletions(-) diff --git a/ratatoeskr/backend/main.php b/ratatoeskr/backend/main.php index 9767cb4..737ffab 100644 --- a/ratatoeskr/backend/main.php +++ b/ratatoeskr/backend/main.php @@ -11,16 +11,44 @@ require_once(dirname(__FILE__) . "/../sys/models.php"); require_once(dirname(__FILE__) . "/../sys/pwhash.php"); +require_once(dirname(__FILE__) . "/../sys/textprocessors.php"); +require_once(dirname(__FILE__) . "/../languages.php"); $admin_grp = Group::by_name("admins"); +/* 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; +} + $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. */ + /* _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; + global $ratatoeskr_settings, $admin_grp, $ste, $languages; + + $ste->vars["all_languages"] = array(); + foreach($languages as $code => $data) + $ste->vars["all_languages"][$code] = $data["language"]; /* Check authentification */ if(isset($_SESSION["ratatoeskr_uid"])) @@ -40,7 +68,8 @@ $backend_subactions = url_action_subactions(array( if($url_next[0] == "login") $url_next = array("content", "write"); $data["user"] = $user; - $ste->vars["user"] = array("name" => $user->username); + $ste->vars["user"] = array("name" => $user->username, "lang" => $user->language); + return; /* Authentification successful, continue */ } else @@ -67,18 +96,20 @@ $backend_subactions = url_action_subactions(array( 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; + $data["user"] = $user; + $ste->vars["user"] = array("name" => $user->username, "lang" => $user->language); } catch(Exception $e) { $ste->vars["login_failed"] = True; } - /* Login successful. */ - $data["user"] = $user; - $ste->vars["user"] = array("name" => $user->username); - throw new Redirect(array("content", "write")); + if(isset($data["user"])) + throw new Redirect(array("content", "write")); } echo $ste->exectemplate("systemtemplates/backend_login.html"); @@ -93,21 +124,212 @@ $backend_subactions = url_action_subactions(array( "content" => url_action_subactions(array( "write" => function(&$data, $url_now, &$url_next) { - global $ste, $translation; + global $ste, $translation, $textprocessors, $ratatoeskr_settings, $languages; + + 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"] = ""; - $article = array_slice($url_next, 0); $url_next = array(); + $default_section = Section::by_id($ratatoeskr_settings["default_section"]); + $ste->vars["section"] = "content"; $ste->vars["submenu"] = "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(); + + $inputs = array( + "date" => time(), + "article_status" => ARTICLE_STATUS_LIVE + ); + + if(isset($_POST["save_article"])) + { + if(!preg_match('/^[a-zA-Z0-9-_]+$/', @$_POST["urlname"])) + $fail_reasons[] = $translation["invalid_urlname"]; + else + $inputs["urlname"] = $_POST["urlname"]; + if((@$_POST["article_status"] < 0) or (@$_POST["article_status"] > 3)) + $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 = strptime(@$_POST["date"], "%Y-%m-%d %H:%M:%S")) === False) + $fail_reasons[] = $translation["invalid_date"]; + else + $inputs["date"] = @mktime($time_tmp["tm_sec"], $time_tmp["tm_min"], $time_tmp["tm_hour"], $time_tmp["tm_mon"] + 1, $time_tmp["tm_mday"], $time_tmp["tm_year"] + 1900); + } + else + $inputs["date"] = time(); + $inputs["allow_comments"] = !(empty($_POST["allow_comments"]) or $_POST["allow_comments"] != "yes"); + + try + { + $inputs["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"]; + } + + function fill_article(&$article, $inputs, $editlang) + { + $article->urlname = $inputs["urlname"]; + $article->status = $inputs["article_status"]; + $article->timestamp = $inputs["date"]; + $article->section = $inputs["section"]; + $article->tags = maketags($inputs["tags"], $editlang); + $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"]); + } + 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); + try + { + $article->save(); + $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 + { + $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); + try + { + $article->save(); + $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"]; + } + } + + foreach(array( + "urlname" => "urlname", + "section" => "article_section", + "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["tags"])) + $inputs["tags"] = array_map(function($tag) use ($editlang) { return $tag->name; }, $article->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"]); + } + } + + /* Push data back to template */ + if(isset($inputs["tags"])) + $ste->vars["tags"] = implode(", ", $inputs["tags"]); + if(isset($inputs["article_section"])) + $ste->section["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]; } + if(!empty($fail_reasons)) + $ste->vars["failed"] = $fail_reasons; + echo $ste->exectemplate("systemtemplates/content_write.html"); + }, + "tags" => function(&$data, $url_now, &$url_next) + { + } )) )); diff --git a/ratatoeskr/cms_style/layout.css b/ratatoeskr/cms_style/layout.css index 42ea1bc..f206da6 100644 --- a/ratatoeskr/cms_style/layout.css +++ b/ratatoeskr/cms_style/layout.css @@ -111,7 +111,7 @@ h1 { min-width: 300px; } -code, code pre { +code, code pre, code * { font-family: monospace; background: #eee; } @@ -150,7 +150,33 @@ h2 { clear: both; } -form.fullwidthinputs input[type="text"], form.fullwidthinputs input[type="password"], form.fullwidthinputs select, form.fullwidthinputs textarea { +.fullwidth { width: 100%; - margin:0mm; +} + +div.error { + border: 1px solid #f00; + background: #fcc; + color: #f00; + padding: 1em; + margin: 3mm 0mm 3mm; + text-align: center; +} + +div.notice { + border: 1px solid #33f; + background: #ccf; + color: #33f; + padding: 1em; + margin: 3mm 0mm 3mm; + text-align: center; +} + +div.success { + border: 1px solid #0a0; + background: #cfc; + color: #0a0; + padding: 1em; + margin: 3mm 0mm 3mm; + text-align: center; } diff --git a/ratatoeskr/templates/src/systemtemplates/content_write.html b/ratatoeskr/templates/src/systemtemplates/content_write.html index 962f116..81a4d9b 100644 --- a/ratatoeskr/templates/src/systemtemplates/content_write.html +++ b/ratatoeskr/templates/src/systemtemplates/content_write.html @@ -1,20 +1,165 @@ +Create textprocessor options. The default will be tags content. + + + + + + -
+ + $failed + +
+

+
    +
  • $v
  • +
+
+
+
+ $success + +
$success
+
+

Markdown Cheat Sheet

+ +

Emphasis / Strong

+

+ *emphasis*
+ _emphasis_
+ **strong**
+ __strong__ +

+ +

Paragraphs and manual line breaks.

+

+ First Paragraph
+
+Second Paragraph with
+long
+text
+
+To enforce a line break  
+end a line with two whitespaces.
+

+ +

Headers

+

+ Header 1
+========
+
+Header 2
+--------
+
+# Header 1
+
+## Header 2
+
+...
+
+###### Header 6
+

+ +

Linking

+

+ [Linktext](http://url/to/resource "Optional title") +

+

+ [Linktext][id]. Somewhere else:

+ [id]: http://url/to/resource "Optional title"
+

+ +

Images

+

+ ![alt text](/path/to/image "Optional title") +

+ +

Ordered / Unordered Lists

+

+ * Item A
+* Item B
+  
+  With a second paragraph.

+* Item C
+  * Item C1
+  * Item C2
+

+

+ 1. First element
+2. Second Element +
+

+ +

Learn More

+

+ Complete Syntax
+ Test Markdown +

+
-

Settings / Metadata

+

-

Unique URL Title:

-

+

:

+

+ : + +

+

:

+

:
(YYYY-MM-DD HH:MM:SS)

+

+ : + ?{$article_status|$article_status|1} + +

+

:

+
-

:

-

:

-

:

+ $morelangs + +

+

+ + ?{~{$i|eq|0}|| - }$lang[full] + +

+
+

+ : + +

+

+ : + +

+

+ : + +

+

+ :
+ +

diff --git a/ratatoeskr/translations/en.php b/ratatoeskr/translations/en.php index c80e92d..31d0944 100644 --- a/ratatoeskr/translations/en.php +++ b/ratatoeskr/translations/en.php @@ -50,7 +50,17 @@ $translation = array( "article_status" => "Article Status", "article_status_hidden" => "Hidden", "article_status_live" => "Live", - "article_status_sticky" => "Sticky" + "article_status_sticky" => "Sticky", + "article_section" => "Section", + "invalid_urlname" => "Invalid URL name (Can contain a-z A-Z 0-9 - and _)", + "invalid_article_status" => "Invalid article status", + "unknown_txtproc" => "Unknown Textprocessor", + "invalid_date" => "Invalid date", + "article_edit_error" => "Could not edit article.", + "unknown_section" => "Unknown section", + "allow_comments" => "Allow comments?", + "article_name_already_in_use" => "Article name is already in use.", + "article_save_success" => "Article successfully saved." ); ?> -- cgit v1.2.3-54-g00ecf