diff --git a/ext/forum/main.php b/ext/forum/main.php index 4bba0398..060735a7 100644 --- a/ext/forum/main.php +++ b/ext/forum/main.php @@ -111,10 +111,10 @@ class Forum extends Extension case "view": $threadID = int_escape($event->get_arg(1)); // $pageNumber = int_escape($event->get_arg(2)); - list($errors) = $this->sanity_check_viewed_thread($threadID); + $errors = $this->sanity_check_viewed_thread($threadID); - if ($errors != null) { - $this->theme->display_error(500, "Error", $errors); + if (count($errors) > 0) { + $this->theme->display_error(500, "Error", implode("
", $errors)); break; } @@ -133,10 +133,10 @@ class Forum extends Extension case "create": $redirectTo = "forum/index"; if (!$user->is_anonymous()) { - list($errors) = $this->sanity_check_new_thread(); + $errors = $this->sanity_check_new_thread(); - if ($errors != null) { - $this->theme->display_error(500, "Error", $errors); + if (count($errors) > 0) { + $this->theme->display_error(500, "Error", implode("
", $errors)); break; } @@ -174,10 +174,10 @@ class Forum extends Extension $threadID = int_escape($_POST["threadID"]); $total_pages = $this->get_total_pages_for_thread($threadID); if (!$user->is_anonymous()) { - list($errors) = $this->sanity_check_new_post(); + $errors = $this->sanity_check_new_post(); - if ($errors != null) { - $this->theme->display_error(500, "Error", $errors); + if (count($errors) > 0) { + $this->theme->display_error(500, "Error", implode("
", $errors)); break; } $this->save_new_post($threadID, $user); @@ -197,63 +197,69 @@ class Forum extends Extension private function get_total_pages_for_thread(int $threadID): int { global $database, $config; - $result = $database->get_row("SELECT COUNT(1) AS count FROM forum_posts WHERE thread_id = :thread_id", ['thread_id' => $threadID]); + $result = $database->get_row(" + SELECT COUNT(1) AS count + FROM forum_posts + WHERE thread_id = :thread_id + ", ['thread_id' => $threadID]); return (int)ceil($result["count"] / $config->get_int("forumPostsPerPage")); } private function sanity_check_new_thread(): array { - $errors = null; + $errors = []; if (!array_key_exists("title", $_POST)) { - $errors .= "
No title supplied.
"; + $errors[] = "No title supplied."; } elseif (strlen($_POST["title"]) == 0) { - $errors .= "
You cannot have an empty title.
"; - } elseif (strlen(html_escape($_POST["title"])) > 255) { - $errors .= "
Your title is too long.
"; + $errors[] = "You cannot have an empty title."; + } elseif (strlen($_POST["title"]) > 255) { + $errors[] = "Your title is too long."; } if (!array_key_exists("message", $_POST)) { - $errors .= "
No message supplied.
"; + $errors[] = "No message supplied."; } elseif (strlen($_POST["message"]) == 0) { - $errors .= "
You cannot have an empty message.
"; + $errors[] = "You cannot have an empty message."; } - return [$errors]; + return $errors; } private function sanity_check_new_post(): array { - $errors = null; + $errors = []; if (!array_key_exists("threadID", $_POST)) { - $errors = "
No thread ID supplied.
"; + $errors[] = "No thread ID supplied."; } elseif (strlen($_POST["threadID"]) == 0) { - $errors = "
No thread ID supplied.
"; + $errors[] = "No thread ID supplied."; } elseif (is_numeric($_POST["threadID"])) { if (!array_key_exists("message", $_POST)) { - $errors .= "
No message supplied.
"; + $errors[] = "No message supplied."; } elseif (strlen($_POST["message"]) == 0) { - $errors .= "
You cannot have an empty message.
"; + $errors[] = "You cannot have an empty message."; } } - return [$errors]; + return $errors; } + /** + * @return string[] + */ private function sanity_check_viewed_thread(int $threadID): array { - $errors = null; + $errors = []; if (!$this->threadExists($threadID)) { - $errors = "
Inexistent thread.
"; + $errors[] = "Inexistent thread."; } - return [$errors]; + return $errors; } private function get_thread_title(int $threadID): string { global $database; - $result = $database->get_row("SELECT t.title FROM forum_threads AS t WHERE t.id = :id ", ['id' => $threadID]); - return $result["title"]; + return $database->get_one("SELECT t.title FROM forum_threads AS t WHERE t.id = :id ", ['id' => $threadID]); } private function show_last_threads(Page $page, PageRequestEvent $event, bool $showAdminOptions = false): void @@ -312,7 +318,7 @@ class Forum extends Extension private function save_new_thread(User $user): int { - $title = html_escape($_POST["title"]); + $title = $_POST["title"]; $sticky = !empty($_POST["sticky"]); global $database; @@ -336,7 +342,7 @@ class Forum extends Extension { global $config; $userID = $user->id; - $message = html_escape($_POST["message"]); + $message = $_POST["message"]; $max_characters = $config->get_int('forumMaxCharsPerPost'); $message = substr($message, 0, $max_characters); diff --git a/ext/forum/theme.php b/ext/forum/theme.php index 93def477..2d49021d 100644 --- a/ext/forum/theme.php +++ b/ext/forum/theme.php @@ -4,6 +4,10 @@ declare(strict_types=1); namespace Shimmie2; +use MicroHTML\HTMLElement; + +use function MicroHTML\{INPUT, LABEL, SMALL, TEXTAREA, TR, TD, TABLE, TH, TBODY, THEAD, DIV, A, BR, emptyHTML, SUP, rawHTML}; + class ForumTheme extends Themelet { public function display_thread_list(Page $page, $threads, $showAdminOptions, $pageNumber, $totalPages) @@ -27,29 +31,41 @@ class ForumTheme extends Themelet { global $config, $user; $max_characters = $config->get_int('forumMaxCharsPerPost'); - $html = make_form(make_link("forum/create")); - - if (!is_null($threadTitle)) { - $threadTitle = html_escape($threadTitle); - } - - if (!is_null($threadText)) { - $threadText = html_escape($threadText); - } - - $html .= " - - - - "; - if ($user->can(Permissions::FORUM_ADMIN)) { - $html .= ""; - } - $html .= " -
Title:
Message:
Max characters alowed: $max_characters.
- - "; + $html = SHM_SIMPLE_FORM( + "forum/create", + TABLE( + ["style" => "width: 500px;"], + TR( + TD("Title:"), + TD(INPUT(["type" => "text", "name" => "title", "value" => $threadTitle])) + ), + TR( + TD("Message:"), + TD(TEXTAREA( + ["id" => "message", "name" => "message"], + $threadText + )) + ), + TR( + TD(), + TD(SMALL("Max characters allowed: $max_characters.")) + ), + $user->can(Permissions::FORUM_ADMIN) ? TR( + TD(), + TD( + LABEL(["for" => "sticky"], "Sticky:"), + INPUT(["name" => "sticky", "id" => "sticky", "type" => "checkbox", "value" => "Y"]) + ) + ) : null, + TR( + TD( + ["colspan" => 2], + INPUT(["type" => "submit", "value" => "Submit"]) + ) + ) + ) + ); $blockTitle = "Write a new thread"; $page->set_title(html_escape($blockTitle)); @@ -65,20 +81,27 @@ class ForumTheme extends Themelet $max_characters = $config->get_int('forumMaxCharsPerPost'); - $html = make_form(make_link("forum/answer")); - - $html .= ''; - - $html .= " - - - "; - - $html .= " -
Message: -
Max characters alowed: $max_characters.
- - "; + $html = SHM_SIMPLE_FORM( + "forum/answer", + INPUT(["type" => "hidden", "name" => "threadID", "value" => $threadID]), + TABLE( + ["style" => "width: 500px;"], + TR( + TD("Message:"), + TD(TEXTAREA(["id" => "message", "name" => "message"])) + ), + TR( + TD(), + TD(SMALL("Max characters allowed: $max_characters.")) + ), + TR( + TD( + ["colspan" => 2], + INPUT(["type" => "submit", "value" => "Submit"]) + ) + ) + ) + ); $blockTitle = "Answer to this thread"; $page->add_block(new Block($blockTitle, $html, "main", 130)); @@ -94,68 +117,70 @@ class ForumTheme extends Themelet $current_post = 0; - $html = - "

". - "". - "". - "". - "". - ""; - + $tbody = TBODY(); foreach ($posts as $post) { $current_post++; - $message = $post["message"]; - - $message = send_event(new TextFormattingEvent($message))->formatted; - $message = str_replace('\n\r', '
', $message); - $message = str_replace('\r\n', '
', $message); - $message = str_replace('\n', '
', $message); - $message = str_replace('\r', '
', $message); - - $message = stripslashes($message); - - $userLink = "".$post["user_name"].""; - - $poster = User::by_name($post["user_name"]); - $gravatar = $poster->get_avatar_html(); - - $rank = "{$post["user_class"]}"; - - $postID = $post['id']; - - //if($user->can(Permissions::FORUM_ADMIN)){ - //$delete_link = "Delete"; - //} else { - //$delete_link = ""; - //} - - if ($showAdminOptions) { - $delete_link = "Delete"; - } else { - $delete_link = ""; - } $post_number = (($pageNumber - 1) * $posts_per_page) + $current_post; - $html .= " - - - - - - - - - - - - "; + $tbody->appendChild( + emptyHTML( + TR( + ["class" => "postHead"], + TD(["class" => "forumSupuser"]), + TD( + ["class" => "forumSupmessage"], + DIV( + ["class" => "deleteLink"], + $showAdminOptions ? A(["href" => make_link("forum/delete/".$threadID."/".$post['id'])], "Delete") : null + ) + ) + ), + TR( + ["class" => "posBody"], + TD( + ["class" => "forumUser"], + A(["href" => make_link("user/".$post["user_name"])], $post["user_name"]), + BR(), + SUP(["class" => "user_rank"], $post["user_class"]), + BR(), + rawHTML(User::by_name($post["user_name"])->get_avatar_html()), + BR() + ), + TD( + ["class" => "forumMessage"], + DIV(["class" => "postDate"], SMALL(rawHTML(autodate($post['date'])))), + DIV(["class" => "postNumber"], " #".$post_number), + BR(), + DIV(["class" => "postMessage"], rawHTML(send_event(new TextFormattingEvent($post["message"]))->formatted)) + ) + ), + TR( + ["class" => "postFoot"], + TD(["class" => "forumSubuser"]), + TD(["class" => "forumSubmessage"]) + ) + ) + ); } - $html .= "
UserMessage
".$userLink."
".$rank."
".$gravatar."
- -
#".$post_number."
-
-
".$message."
"; + $html = emptyHTML( + DIV( + ["id" => "returnLink"], + A(["href" => make_link("forum/index/")], "Return") + ), + BR(), + BR(), + TABLE( + ["id" => "threadPosts", "class" => "zebra"], + THEAD( + TR( + TH(["id" => "threadHeadUser"], "User"), + TH("Message") + ) + ), + $tbody + ) + ); $this->display_paginator($page, "forum/view/".$threadID, null, $pageNumber, $totalPages); @@ -164,37 +189,32 @@ class ForumTheme extends Themelet $page->add_block(new Block($threadTitle, $html, "main", 20)); } - - public function add_actions_block(Page $page, $threadID) { - $html = 'Delete this thread and its posts.'; - + $html = A(["href" => make_link("forum/nuke/".$threadID)], "Delete this thread and its posts."); $page->add_block(new Block("Admin Actions", $html, "main", 140)); } - - - private function make_thread_list($threads, $showAdminOptions): string + private function make_thread_list($threads, $showAdminOptions): HTMLElement { - $html = "". - "". - "". - "". - "". - ""; + global $config; - if ($showAdminOptions) { - $html .= ""; - } + $tbody = TBODY(); + $html = TABLE( + ["id" => "threadList", "class" => "zebra"], + THEAD( + TR( + TH("Title"), + TH("Author"), + TH("Updated"), + TH("Responses"), + $showAdminOptions ? TH("Actions") : null + ) + ), + $tbody + ); - $html .= ""; - - $current_post = 0; foreach ($threads as $thread) { - $oe = ($current_post++ % 2 == 0) ? "even" : "odd"; - - global $config; $titleSubString = $config->get_int('forumTitleSubString'); if ($titleSubString < strlen($thread["title"])) { @@ -204,27 +224,23 @@ class ForumTheme extends Themelet $title = $thread["title"]; } - if (bool_escape($thread["sticky"])) { - $sticky = "Sticky: "; - } else { - $sticky = ""; - } - - $html .= "". - '". - '". - "". - ""; - - if ($showAdminOptions) { - $html .= ''; - } - - $html .= ""; + $tbody->appendChild( + TR( + TD( + ["class" => "left"], + bool_escape($thread["sticky"]) ? "Sticky: " : "", + A(["href" => make_link("forum/view/".$thread["id"])], $title) + ), + TD( + A(["href" => make_link("user/".$thread["user_name"])], $thread["user_name"]) + ), + TD(rawHTML(autodate($thread["uptodate"]))), + TD($thread["response_count"]), + $showAdminOptions ? TD(A(["href" => make_link("forum/nuke/".$thread["id"])], "Delete")) : null + ) + ); } - $html .= "
TitleAuthorUpdatedResponsesActions
'.$sticky.''.$title."'.$thread["user_name"]."".autodate($thread["uptodate"])."".$thread["response_count"]."Delete
"; - return $html; } }