permissions & 128)) { header($_SERVER["SERVER_PROTOCOL"]." 403 Forbidden", true, 403); include_once($_SERVER["DOCUMENT_ROOT"]."/errors/403.php"); include_once($COMMONS."/footer.php"); die(); } /** * Generate a feed.atom file for use by atom/rss readers. */ function generate_atom_feed($conn) { if (!($fp = fopen('feed.atom', 'w'))) { return; } // Prepare statement for selecting all the blogposts $stmt = $conn->prepare("SELECT blogpost_id, readable_address, title, abstract, content, date_posted, date_edited FROM blogposts ORDER BY date_posted DESC LIMIT 15;"); // Execute the statement $stmt->execute(); // Prepare new statement for selecting the tags for a given blogpost $blogposts_arr = $stmt->fetchall(PDO::FETCH_ASSOC); fprintf($fp, " Zdenek Borovec blog %s Zdenek Borovec https://www.zenekborovec.cz/blog/ ", date("Y-m-d\TH:i:s\Z")); // Prepare new statement for selecting the tags for a given blogpost $stmt = $conn->prepare("SELECT name FROM blogpost_tags INNER JOIN blogpost_has_tag ON blogpost_tags.tag_id = blogpost_has_tag.tag_id WHERE blogpost_id = :blogpost_id;"); // Go through all the blogposts, fetch their tags and display them for($i=0; $i < count($blogposts_arr); $i++) { // Get info for the current blog $blog = $blogposts_arr[$i]; // Bind and execute the tag select $stmt->bindParam(":blogpost_id", $blog["blogpost_id"]); $stmt->execute(); // Fetch the tags $tags_arr = $stmt->fetchall(PDO::FETCH_ASSOC); $categoryStr = ""; for($j=0; $j < count($tags_arr); $j++) { $tag = $tags_arr[$j]; $categoryStr = $categoryStr.""; } if(is_null($blog["readable_address"])) { fprintf($fp, " %s %s urn:uuid:%s %s %s %s %s ", $blog["title"], $categoryStr, $blog["blogpost_id"], $blog["blogpost_id"], date("Y-m-d\TH:i:s\Z", strtotime($blog["date_posted"])), date("Y-m-d\TH:i:s\Z", strtotime($blog["date_edited"])), $blog["abstract"], sanitize_input($blog["content"])); } else { fprintf($fp, " %s %s urn:uuid:%s %s %s %s %s ", $blog["title"], $categoryStr, $blog["readable_address"], $blog["blogpost_id"], date("Y-m-d\TH:i:s\Z", strtotime($blog["date_posted"])), date("Y-m-d\TH:i:s\Z", strtotime($blog["date_edited"])), $blog["abstract"], sanitize_input($blog["content"])); } } fprintf($fp, ""); } /** * Explode the tag string into separate tags, if they exist, * attach them to the article. */ function add_tags_to_blogpost($conn, $blogpost_id, $tagStr) { // Get array of all the tags. $tagArr = explode(" ", $tagStr); // Prepare array for storing tag ids $tagIdArr = []; // Prepare statement to select id of a tag with given name $stmt = $conn->prepare("SELECT tag_id FROM blogpost_tags WHERE name = :name"); // Go through all the tag names and get their ids foreach ($tagArr as $tagName) { // Bind, execute and fetch the command $stmt->bindParam(":name", $tagName); $stmt->execute(); $result = $stmt->fetch(PDO::FETCH_ASSOC); // If we got a result, add it to the found ids. if($result) { $tagIdArr[] = $result["tag_id"]; } } // Prepare the statement to add tag to blogpost and bind blogpost_id $stmt = $conn->prepare("INSERT INTO blogpost_has_tag (blogpost_id, tag_id) VALUES (:blogpost_id, :tag_id)"); $stmt->bindParam(":blogpost_id", $blogpost_id); // Go through the found ids and insert them foreach ($tagIdArr as $tagId) { $stmt->bindParam(":tag_id", $tagId); $stmt->execute(); } } /** * Delete all blogpost-tag relations involving the given blogpost. * @param $conn Active Mysql connection. * @param $blogpost_id GUID of the edited blogpost. */ function remove_blogpost_tags($conn, $blogpost_id) { // Prepare, bind and execute the delete statement $stmt = $conn->prepare("DELETE FROM blogpost_has_tag WHERE blogpost_id = :blogpost_id;"); $stmt->bindParam(":blogpost_id", $blogpost_id); $stmt->execute(); } /** * Publish a new blogpost and add the specified tags to it.. * @param $conn Active Mysql connection. * @param $blogpost_addr Human-readable address of the edited blogpost. * @param $title Title for the blogpost. * @param $tagStr String with all the tags for the blogpost * (space-separated). * @param $abstract Abstract for the article. * @param $content Content of the article. * @returns The guid of the newly generated blogpost. */ function publish_blogpost($conn, $blogpost_addr, $title, $tagStr, $abstract, $content) { // Get an ID for the blogpost $stmt = $conn->prepare("SELECT UUID()"); $stmt->execute(); $result = $stmt->fetch(PDO::FETCH_ASSOC); $blogpost_id = $result["UUID()"]; // Prepare, bind and execute the insert statement $stmt = $conn->prepare("INSERT INTO blogposts (blogpost_id, readable_address, title, abstract, content) VALUES (:blogpost_id, :address, :title, :abstract, :content);"); $stmt->bindParam(":blogpost_id", $blogpost_id); $stmt->bindParam(":address", $blogpost_addr); $stmt->bindParam(":title", $title); $stmt->bindParam(":abstract", $abstract); $stmt->bindParam(":content", $content); $stmt->execute(); // Add the new tags to the blogpost add_tags_to_blogpost($conn, $blogpost_id, $tagStr); // Return the newly generated blogposts id. return $blogpost_id; } /** * Update the blogpost content, title, abstract and date edited. * Then update the tags. * @param $conn Active Mysql connection. * @param $blogpost_id GUID of the edited blogpost. * @param $blogpost_addr Human-readable address of the edited blogpost. * @param $title Title for the blogpost. * @param $tagStr String with all the tags for the blogpost * (space-separated). * @param $abstract Abstract for the article. * @param $content Content of the article. */ function update_blogpost($conn, $blogpost_id, $blogpost_addr, $title, $tagStr, $abstract, $content) { // Prepare, bind and execute the update statement $stmt = $conn->prepare("UPDATE blogposts SET readable_address = :address, title = :title, abstract = :abstract, content = :content, date_edited = DEFAULT WHERE blogpost_id = :blogpost_id;"); $stmt->bindParam(":address", $blogpost_addr); $stmt->bindParam(":title", $title); $stmt->bindParam(":abstract", $abstract); $stmt->bindParam(":content", $content); $stmt->bindParam(":blogpost_id", $blogpost_id); $stmt->execute(); // Remove old tags from this blogpost remove_blogpost_tags($conn, $blogpost_id); // Add the new tags to the blogpost add_tags_to_blogpost($conn, $blogpost_id, $tagStr); } // Check DB connection if($conn == null){ header($_SERVER["SERVER_PROTOCOL"]." 503 Service Unavailable", true, 503); include_once($_SERVER["DOCUMENT_ROOT"]."/errors/503.php"); include_once($COMMONS."/footer.php"); die(); } display_header("Write article."); if(isset($_POST["submit"])) { // Input will not be sanitized, as it is desirable to allow full control // over the content here and only trusted users should have access // to this section $title = $_POST["blogpost_title"]; $address = $_POST["blogpost_address"]; $tagsStr = $_POST["blogpost_tags"]; $abstract = $_POST["article_abstract"]; $content = $_POST["article_content"]; // If adress is empty, repopulate the prefills and show error if(strcmp($address, "") == 0) { // Set prefill values for the form $blogId_prefill = isset($_POST["blogpost_id"]) ? sanitize_input($_POST["blogpost_id"]) : ""; $title_prefill = $title; $address_prefill = $address; $abstract_prefill = $abstract; $content_prefill = $content; $tagStr_prefill = $tagsStr; $addrErr = "Cannot be empty!"; } // Otherwise update/create the blogpost else { if($_POST["blogpost_id"]) { $blogpostId = sanitize_input($_POST["blogpost_id"]); update_blogpost($conn, $blogpostId, $address, $title, $tagsStr, $abstract, $content); } else { $blogpostId = publish_blogpost($conn, $address, $title, $tagsStr, $abstract, $content); } generate_atom_feed($conn); // Show button to generate the article printf("
", $blogpostId, $address); include_once($COMMONS."/footer.php"); die; } } else if(isset($_GET["guid"])) { $blogId = sanitize_input($_GET["guid"]); // select article title, abstract and content from the database $stmt = $conn->prepare("SELECT readable_address, title, abstract, content FROM blogposts WHERE blogpost_id = :blogpost_id"); $stmt->bindParam(":blogpost_id", $blogId); $stmt->execute(); $result = $stmt->fetch(PDO::FETCH_ASSOC); // Set prefill values for the form $blogId_prefill = $blogId; $title_prefill = $result["title"]; $address_prefill = $result["readable_address"]; $abstract_prefill = $result["abstract"]; $content_prefill = sanitize_input($result["content"]); // select the tags for this article from the database $stmt = $conn->prepare("SELECT blogpost_tags.name FROM (blogpost_tags INNER JOIN blogpost_has_tag ON blogpost_tags.tag_id = blogpost_has_tag.tag_id) WHERE blogpost_id = :blogpost_id;"); $stmt->bindParam(":blogpost_id", $blogId); $stmt->execute(); $results = $stmt->fetchAll(PDO::FETCH_ASSOC); // Construct the string of all blogpost tags to prefill. $tagStr_prefill = ""; foreach($results as $row) { $tagStr_prefill .= $row["name"]." "; } } printf("
%s
Tags should be separated by spaces, use dash-case, use the tageditor page to add new tags.
", $blogId_prefill, $title_prefill, $address_prefill, $addrErr, $tagStr_prefill, $abstract_prefill, $content_prefill); include_once($COMMONS."/footer.php"); ?>