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->comment_id); if($this->children != null) { for($i = 0; $i < count($this->children); $i++) { $child = $this->children[$i]; $child->display_comment(); } } printf("
"); } /** * 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, $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. * $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, $timestamp, $content, $parent_id) { $this->comment_id = $comment_id; $this->blogpost_id = $blogpost_id; $this->poster_id = $poster_id; $this->poster_name = $poster_name; $this->timestamp = $timestamp; $this->content = $content; $this->parent_id = $parent_id; } } class Blogpost { public $blogpost_id; public $title; public $content; public $date_posted; public $tags; public $comments; /** * Display the article, or a warning message. */ public function display_article(){ // If a blog with given ID was not found display warning message. if(!$this->title){ printf("

Article not found


I am sorry, but I couldn't find an article with this ID.

"); return; } // Begin the article printf("
"); // Display the blogpost name printf("

%s

", $this->title); // Display the blog metadata printf("
"); // Display tags for($i = 0; $i < count($this->tags); $i++) { $tag = $this->tags[$i]; printf(" %s ", $tag["color"], $tag["name"]); } // Display publish date and end metadata div printf("Published on: %s
", date("Y-m-d", strtotime($this->date_posted))); // Display hrule, article content and end the article printf("

%s
", $this->content); } /** * Display the comments for this post and their children. */ public function display_comments(){ printf("
"); for($i = 0; $i < count($this->comments); $i++){ $this->comments[$i]->display_comment(); } printf("
"); } /** * Constructor for the blogpost. * $blogpost_id GUID of the blogpost in the database. * $title Title of the blogpost. * $content Content of the blogpost article. * $date_posted Timestamp at publishing of article. * $tags Array of the tags this article has. * $comments Array of Blogpostcomment objects, * the comments of this article. */ public function __construct($blogpost_id, $title, $content, $date_posted, $tags, $comments){ $this->blogpost_id = $blogpost_id; $this->title = $title; $this->content = $content; $this->date_posted = $date_posted; $this->tags = $tags; $this->comments = $comments; } } /** * Send a comment to the database. * If the poster is not signed in, send "NULL" (as a string) as the $posterID * The same goes for $parentId (that is the parent comment, * if this one is a response) * Returns: GUID PK of the newly added comment. */ function send_comment($conn, $blogId, $posterId, $content, $parentId) { // If content is empty, do not post if(empty($content)) { return ""; } // Get a uuid for the comment $stmt = $conn->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) { // 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, $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 title, content, date_posted 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"]; $blogContent = $result["content"]; $datePosted = $result["date_posted"]; $tags = $tags_arr; $comments = load_comments($conn, $blogId); return new Blogpost($blogId, $blogTitle, $blogContent, $datePosted, $tags, $comments); } // Check DB connection if($conn == null){ include($_SERVER["DOCUMENT_ROOT"]."/errors/503.php"); include($_SERVER["DOCUMENT_ROOT"]."/../common/footer.php"); die(); } // If the method is post (user submitted a comment), try to post it, // Refill the appropriate comment sumbmission form and display // error message on error. if(isset($_POST["submit"])) { // Sanitise the user-submitted data $blogId = sanitize_input($_POST["blogpost_id"]); $commentContent = sanitize_input($_POST["comment_entry"]); $parentId = isset($_POST["comment_id"]) ? $_POST["comment_id"] : "NULL"; $posterId = isset($_SESSION["current_user"]) ? $_SESSION["current_user"]->user_id : "NULL"; // Try to send the comment $commentId = send_comment($conn, $blogId, $posterId, $commentContent, $parentId); // Redirect to this page with GET header("Location: http://www.zdenekborovec-dev.cz/blog/article?guid=". $blogId."#comment-".$commentId); } // Get the blog id. $blogId = sanitize_input($_GET["guid"]); // If no ID was entered, display warning and die. if(!$blogId) { display_header("No article requested."); include($_SERVER["DOCUMENT_ROOT"]."/errors/404.php"); include($_SERVER["DOCUMENT_ROOT"]."/../common/footer.php"); die(); } $blogPost = load_blog($conn, $blogId); // If no ID was entered, display warning and die. if(!$blogPost) { display_header("Article not found"); include($_SERVER["DOCUMENT_ROOT"]."/errors/404.php"); include($_SERVER["DOCUMENT_ROOT"]."/../common/footer.php"); die(); } // Display the header with title being the blog name display_header($blogPost->title); // Display the blog $blogPost->display_article(); printf("
"); // Display post comment form. printf("

Comments:

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