From 04e942a3b2c43d097903e5bd9d2dd952c25653cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zden=C4=9Bk=20Borovec?= Date: Tue, 23 Jul 2024 23:18:32 +0200 Subject: [PATCH] implement static site generation --- .gitignore | 1 + docs/www/blog/blogpost.php | 80 ++++++++ docs/www/blog/blogpostcomment.php | 150 +++++++++++++++ docs/www/blog/generatearticle.php | 294 ++++++++++++++++++++++++++++++ 4 files changed, 525 insertions(+) create mode 100644 docs/www/blog/blogpost.php create mode 100644 docs/www/blog/blogpostcomment.php create mode 100644 docs/www/blog/generatearticle.php diff --git a/.gitignore b/.gitignore index 16610a6..c43ecd3 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ /docs/common/config.php /assets/upload/** /docs/www/blog/feed.atom +/docs/www/blog/article/** diff --git a/docs/www/blog/blogpost.php b/docs/www/blog/blogpost.php new file mode 100644 index 0000000..7d48ced --- /dev/null +++ b/docs/www/blog/blogpost.php @@ -0,0 +1,80 @@ +"; + $body .= sprintf(" + +
+

%s

Published on: %s
", $this->title, + date("Y-m-d", strtotime($this->date_posted))); + + // Display tags + for($i = 0; $i < count($this->tags); $i++) { + $tag = $this->tags[$i]; + $body .= sprintf(" + + %s + ", $tag["color"], $tag["name"]); + } + + // Display publish date and end metadata div + $body .= sprintf(" + Last edited on: %s
", + date("Y-m-d", strtotime($this->date_edited))); + + // Display hrule, article content and end the article + $body .= sprintf("
%s
", $this->content); + return $body; + } + + /** + * Display the comments for this post and their children. + */ + public function display_comments(){ + $body = "
"; + for($i = 0; $i < count($this->comments); $i++){ + $body .= $this->comments[$i]->display_comment(); + } + return $body."
"; + } + + /** + * Constructor for the blogpost. + * $blogpost_id GUID of the blogpost in the database. + * $address Readable address of the blogpost. + * $title Title of the blogpost. + * $content Content of the blogpost article. + * $date_posted Timestamp at publishing of article. + * $date_edited Timestamp at whioch the article was last edited. + * $tags Array of the tags this article has. + * $comments Array of Blogpostcomment objects, + * the comments of this article. + */ + public function __construct($blogpost_id, $address, $title, + $content, $date_posted, $date_edited, $tags, $comments){ + $this->blogpost_id = $blogpost_id; + $this->address = $address; + $this->title = $title; + $this->content = $content; + $this->date_posted = $date_posted; + $this->date_edited = $date_edited; + $this->tags = $tags; + $this->comments = $comments; + } +} +?> diff --git a/docs/www/blog/blogpostcomment.php b/docs/www/blog/blogpostcomment.php new file mode 100644 index 0000000..b28303e --- /dev/null +++ b/docs/www/blog/blogpostcomment.php @@ -0,0 +1,150 @@ + +
+ By: %s + On: %s + + +
+
+ %s +
+
+
+ + + + +
+ +
+ +
+
+
+
+ ", + $this->comment_id, + $this->poster_name, + date("Y-m-d H:i", strtotime($this->timestamp)), + $this->comment_id, + $this->comment_id, + $this->content, + htmlspecialchars($_SERVER["PHP_SELF"]), + $this->blogpost_id, + $this->blogpost_addr, + $this->comment_id); + + if($this->children != null) { + for($i = 0; $i < count($this->children); $i++) + { + $child = $this->children[$i]; + $body .= $child->display_comment(); + } + } + return $body."
"; + } + + /** + * Load the child comments to this comment, and recursively their children. + */ + public function load_children($conn) { + // Prepare new statement for selecting all the child comments. + $stmt = $conn->prepare("SELECT comment_id, poster_id, timestamp, + content FROM blogpost_comments WHERE blogpost_id = :blogpost_id AND + parent_id = :comment_id ORDER BY timestamp ASC;"); + + // Bind and execute the comment select + $stmt->bindParam(":blogpost_id", $this->blogpost_id); + $stmt->bindParam(":comment_id", $this->comment_id); + $stmt->execute(); + + // Fetch the comments + $results_arr = $stmt->fetchall(PDO::FETCH_ASSOC); + $comments_arr = []; + + // Prepare comment author selection statement + $stmt = $conn->prepare("SELECT username FROM users WHERE + user_id = :user_id;"); + + // Recursively fetch all the child comments + for($i = 0; $i < count($results_arr); $i++) { + $com = $results_arr[$i]; + + // If comment has a registered author, fetch their name + if($com["poster_id"]) { + $stmt->bindParam(":user_id", $com["poster_id"]); + + $stmt->execute(); + + $result = $stmt->fetch(PDO::FETCH_ASSOC); + + // If user was erased from database, set name to [Deleted] + if(!$result) { + $username = "[Deleted]"; + } + else { + $username = $result["username"]; + } + } + else { + $username = "[Guest]"; + } + + $commentObj = new BlogpostComment($com["comment_id"], + $com["poster_id"], $username, $this->blogpost_id, + $this->blogpost_addr, $com["timestamp"], $com["content"], + $this->comment_id); + $comments_arr[] = $commentObj; + $commentObj->load_children($conn); + } + + $this->children = $comments_arr; + } + + /** + * Constructor for the BlogpostComment object. + * $comment_id GUID of the comment. + * $poster_id GUID of the comment author. + * $poster_name Name of the comment author. + * $blogpost_id GUID of the blogpost this comment is under. + * $blogpost_addr Human-readable address of the blogpost this + comment is under. + * $timestamp Timestamp at comment creation. + * $content Content of the comment. + * $parent_id GUID of the comment this is a reply to (or NULL). + */ + public function __construct($comment_id, $poster_id, $poster_name, + $blogpost_id, $blogpost_address, $timestamp, $content, $parent_id) { + $this->comment_id = $comment_id; + $this->blogpost_id = $blogpost_id; + $this->blogpost_addr = $blogpost_address; + $this->poster_id = $poster_id; + $this->poster_name = $poster_name; + $this->timestamp = $timestamp; + $this->content = $content; + $this->parent_id = $parent_id; + } +} +?> diff --git a/docs/www/blog/generatearticle.php b/docs/www/blog/generatearticle.php new file mode 100644 index 0000000..294aaaf --- /dev/null +++ b/docs/www/blog/generatearticle.php @@ -0,0 +1,294 @@ +prepare("SELECT UUID()"); + $stmt->execute(); + $result = $stmt->fetch(PDO::FETCH_ASSOC); + $uuid = $result["UUID()"]; + + // Prepare the statemtnt + $stmt = $conn->prepare("INSERT INTO blogpost_comments + ( comment_id, parent_id, blogpost_id, poster_id, content) VALUES + (:comment_id, :parent_id, :blogpost_id, :poster_id, :content);"); + + // Bind all the parameters + $stmt->bindValue(":comment_id", $uuid, PDO::PARAM_STR); + $stmt->bindValue(":parent_id", $parentId == "NULL" + ? NULL : $parentId, PDO::PARAM_STR); + $stmt->bindValue(":blogpost_id", $blogId, PDO::PARAM_STR); + $stmt->bindValue(":poster_id", $posterId == "NULL" + ? NULL : $posterId, PDO::PARAM_STR); + $stmt->bindValue(":content", $content, PDO::PARAM_STR); + + // Execute the statement + $stmt->execute(); + + return $uuid; +} + +/** + * Load comments under a given blog. + * Returns array of BlogpostComment objects. + */ +function load_comments($conn, $blogId, $blogAddress) { + // Prepare new statement for selecting all the child comments. + $stmt = $conn->prepare("SELECT comment_id, poster_id, timestamp, + content FROM blogpost_comments WHERE blogpost_id = :blogpost_id + AND parent_id IS NULL ORDER BY timestamp ASC;"); + + // Bind and execute the comment select + $stmt->bindParam(":blogpost_id", $blogId); + $stmt->execute(); + + // Fetch the comments + $results_arr = $stmt->fetchall(PDO::FETCH_ASSOC); + $comments_arr = []; + + // Prepare comment author selection statement + $stmt = $conn->prepare("SELECT username FROM users WHERE + user_id = :user_id;"); + + // Recursively fetch all the child comments + for($i = 0; $i < count($results_arr); $i++) { + $com = $results_arr[$i]; + + // If comment has a registered author, fetch their name + if($com["poster_id"]) { + $stmt->bindParam(":user_id", $com["poster_id"]); + + $stmt->execute(); + + $result = $stmt->fetch(PDO::FETCH_ASSOC); + + // If user was erased from database, set name to [Deleted] + if(!$result) { + $username = "[Deleted]"; + } + else { + $username = $result["username"]; + } + } + else { + $username = "[Guest]"; + } + + $commentObj = new BlogpostComment($com["comment_id"], $com["poster_id"], + $username, $blogId, $blogAddress, $com["timestamp"], + $com["content"], NULL); + $commentObj->load_children($conn); + $comments_arr[] = $commentObj; + } + + return $comments_arr; +} + +/** + * Load info about the blog with a given guid and return corresponding + * Blogpost object. NULL if blog couldn't be loaded. + */ +function load_blog($conn, $blogId){ + // Prepare and bind statement for gathering blogpost info + $stmt = $conn->prepare("SELECT readable_address, title, content, + date_posted, date_edited FROM blogposts WHERE + blogpost_id = :blogpost_id;"); + $stmt->bindParam(":blogpost_id", $blogId); + + // Execute the statement + $stmt->execute(); + + // Fetch the blogpost + $result = $stmt->fetch(PDO::FETCH_ASSOC); + + // If no post with given guid was found, + // there is no information to gather, return. + if(!$result){ + return null; + } + + // Prepare new statement for selecting the tags for a given blogpost + $stmt = $conn->prepare("SELECT name, color FROM + blogpost_tags INNER JOIN blogpost_has_tag ON + blogpost_tags.tag_id = blogpost_has_tag.tag_id WHERE + blogpost_id = :blogpost_id;"); + + // Bind and execute the tag select + $stmt->bindParam(":blogpost_id", $blogId); + $stmt->execute(); + + // Fetch the tags + $tags_arr = $stmt->fetchall(PDO::FETCH_ASSOC); + + // Set the variables + $blogTitle = $result["title"]; + $blogAddress = $result["readable_address"]; + $blogContent = $result["content"]; + $datePosted = $result["date_posted"]; + $dateEdited = $result["date_edited"]; + $tags = $tags_arr; + $comments = load_comments($conn, $blogId, $blogAddress); + + return new Blogpost($blogId, $blogAddress, $blogTitle, $blogContent, + $datePosted, $dateEdited, $tags, $comments); +} + +// Check DB connection +if($conn == null){ + header($_SERVER["SERVER_PROTOCOL"]." 503 Service Unavailable", true, 503); + include_once($_SERVER["DOCUMENT_ROOT"]."/errors/503.php"); + die(); +} + +// If a human-readable address was provided, extract appropriate id. +if(isset($_POST["address"])) { + $blogAddr = sanitize_input($_POST["address"]); + + // Prepare and bind statement for gathering blogpost address + $stmt = $conn->prepare("SELECT blogpost_id + FROM blogposts WHERE readable_address = :readable_address;"); + $stmt->bindParam(":readable_address", $blogAddr); + + // Execute the statement + $stmt->execute(); + + // Fetch the blogpost + $result = $stmt->fetch(PDO::FETCH_ASSOC); + + // If post with given address was found, set the $blogId var. + if($result){ + $blogId = sanitize_input($result["blogpost_id"]); + } +} + +// Attempt to load the blogpost +$blogPost = load_blog($conn, $blogId); + +// If blogpost could not be retieved, display warning and die. +if(!$blogPost) { + header($_SERVER["SERVER_PROTOCOL"]." 404 Not Foud", true, 404); + //include_once($_SERVER["DOCUMENT_ROOT"]."/errors/404.php"); + //include_once($COMMONS."/footer.php"); + die(); +} + +// Try to open the file to which to render the blogpost. +if (!($fp = fopen("article/".$blogPost->address.".php", 'w'))) { + header($_SERVER["SERVER_PROTOCOL"]." 500 Could not open file for writing", + true, 505); + echo "fail"; + die(); +} + +fprintf($fp, +" +
+
+

Comments:

+
+ + + +
+ +
+ +
+
+ +", + $COMMONS."/header.php", + $blogPost->title, + addslashes($blogPost->display_article()), + "SEND_COMMAND_ACTION", + $blogPost->blogId, + $blogPost->address, + addslashes($blogPost->display_comments()), + $COMMONS."/footer.php"); + +/* +// Display the header with title being the blog name +display_header($blogPost->title); + +// Display the blog +$blogPost->display_article(); +printf("
"); + +// Display post comment form. +if(is_null($blogPost->address)) +{ + printf(" +
+

Comments:

+
+ + +
+ +
+ +
+
+ ", + htmlspecialchars($_SERVER["PHP_SELF"]), $blogId, + isset($_SESSION["current_user"]) ? + $_SESSION["current_user"]->user_name : "Guest"); +} +else +{ + printf(" +
+

Comments:

+
+ + + +
+ +
+ +
+
+ ", + htmlspecialchars($_SERVER["PHP_SELF"]), $blogId, $blogPost->address, + isset($_SESSION["current_user"]) ? + $_SESSION["current_user"]->user_name : "Guest"); +} +// Display the blog comments +$blogPost->display_comments(); +*/ +?>