From d3970c3116c321a5b9e68b3f890f3d9c0fc3f8c9 Mon Sep 17 00:00:00 2001 From: Pijus Kamandulis Date: Thu, 14 Sep 2023 23:33:31 +0300 Subject: [PATCH] Refactor pastes to use repository --- src/cronjob.php | 15 +- src/delete.php | 34 +--- src/includes/config.php | 2 + src/includes/highlight.php | 94 +++++------ src/post.php | 155 +++++------------ src/repositories/paste-repository.php | 228 ++++++++++++++++++++++++++ src/views/_layout.php | 18 +- src/views/_navbar.php | 16 +- src/views/_new-paste.php | 12 +- src/views/_recent-pastes.php | 14 +- src/views/edit.php | 33 ++-- src/views/my-pastes.php | 86 +++++----- src/views/user.php | 61 ++++--- src/views/view-paste.php | 64 +++++--- 14 files changed, 495 insertions(+), 337 deletions(-) create mode 100644 src/repositories/paste-repository.php diff --git a/src/cronjob.php b/src/cronjob.php index 2de2765..a51de91 100644 --- a/src/cronjob.php +++ b/src/cronjob.php @@ -1,18 +1,11 @@ prepare("DELETE from `pastes` where `expire`<:time and `expire`>0"); - $stmt->bindValue(':time', $time); - $stmt->execute(); - $conn = null; //close connection to database - echo 'OK! 200'; -} + if (isset($_GET["key"])) { if ($_GET["key"] == $CRON_ExpireKey) { //Delete expired pastes - RemoveExpiredPastes(); + include_once "repositories/paste-repository.php"; + $pasteRepo = new PasteRepository(); + echo $pasteRepo->removeExpiredPastes(); } } //Cron job example: */5 * * * * curl --silent http://127.0.0.1/paste/cronjob.php?key=fgd45fb5fb15gb > /dev/null diff --git a/src/delete.php b/src/delete.php index 53d84b5..9ea81f5 100644 --- a/src/delete.php +++ b/src/delete.php @@ -6,35 +6,19 @@ include_once "includes/user.php"; $uid = GetUsersIDBySession($_COOKIE["pp_sid"], $_COOKIE["pp_skey"]); $paste = $_GET['id']; - //connect to db and get paste info - $conn = GetConnectionToDB(); - $stmt = $conn->prepare('SELECT * FROM pastes WHERE uid=:uid'); - $stmt->bindParam(':uid', $paste); - $stmt->execute(); - if ($stmt->rowCount() > 0) { - while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { - if ($row['owner'] === $uid) { - $stmt2 = $conn->prepare("DELETE FROM pastes WHERE id=:id"); - $stmt2->bindParam(':id', $row['id']); - $stmt2->execute(); - $conn = null; - echo '

Paste ' . $row["uid"] . ' has been deleted!

'; - echo ''; - die(); - } else { - $conn = null; - echo '

You are not the owner of the paste ' . $row["uid"] . '

'; - echo ''; - die(); - } - } + + include_once "repositories/paste-repository.php"; + $pasteRepo = new PasteRepository(); + $result = $pasteRepo->deletePasteByUID($paste, $uid); + if ($result === 'OK! 200') { + echo '

Paste ' . $paste . ' has been deleted!

'; + echo ''; + die(); } else { - $conn = null; - echo '

The paste ' . $row["uid"] . ' does not exist

'; + echo '

' . $result . '

'; echo ''; die(); } - $conn = null; } ?> diff --git a/src/includes/config.php b/src/includes/config.php index 6a0b873..8c308bd 100644 --- a/src/includes/config.php +++ b/src/includes/config.php @@ -11,3 +11,5 @@ function GetConnectionToDB() { } //========CRON_JOBS=========// $CRON_ExpireKey = getenv('CRON_EXPIREKEY') ?: "b1g51bf6g"; +//=========GENERAL==========// +$BASE_DIR = "/"; diff --git a/src/includes/highlight.php b/src/includes/highlight.php index 3e5839f..81de8d4 100644 --- a/src/includes/highlight.php +++ b/src/includes/highlight.php @@ -1,49 +1,51 @@ '; - // - include_once "includes/config.php"; - $conn = GetConnectionToDB(); - $stmt = $conn->query('SELECT highlight FROM pastes WHERE uid="'.$uid.'"'); - if($result = $stmt->fetch(PDO::FETCH_ASSOC)){ - $conn = null; - $_HL = $result["highlight"]; - if($_HL == "")$_HL = "plain"; - echo ''; - } - $conn = null; - // - echo ' - '; +include_once "includes/config.php"; + +$_HL = "plain"; +if (isset($_GET["page"])) { + if ($_GET["page"] == "create" || $_GET["page"] == "mypastes" || $_GET["page"] == "login" || $_GET["page"] == "logout" || $_GET["page"] == "signup"); + else { + + $uid = $_GET["page"]; + echo ''; + + include_once "repositories/paste-repository.php"; + $pasteRepo = new PasteRepository(); + $_HL = $pasteRepo->getSyntaxHighlightByUID($uid); + + if ($_HL === "") { + $_HL = "plain"; } + + $highlightToBrushFileMap = [ + "python" => 'shBrushPython.js', + "applescript" => 'shBrushAppleScript.js', + "as3" => 'shBrushAS3.js', + "bash" => 'shBrushBash.js', + "cf" => 'shBrushColdFusion.js', + "csharp" => 'shBrushCSharp.js', + "css" => 'shBrushCss.js', + "delphi" => 'shBrushDelphi.js', + "diff" => 'shBrushDiff.js', + "erlang" => 'shBrushErlang.js', + "groovy" => 'shBrushGroovy.js', + "java" => 'shBrushJava.js', + "javafx" => 'shBrushJavaFX.js', + "jscript" => 'shBrushJScript.js', + "perl" => 'shBrushPerl.js', + "php" => 'shBrushPhp.js', + "powershell" => 'shBrushPowerShell.js', + "ruby" => 'shBrushRuby.js', + "sass" => 'shBrushSass.js', + "scala" => 'shBrushScala.js', + "sql" => 'shBrushSql.js', + "vb" => 'shBrushVb.js', + "xml" => 'shBrushXml.js', + ]; + + $brushFile = $highlightToBrushFileMap[$_HL] ?? 'shBrushPlain.js'; + echo ''; + echo ' + '; } +} diff --git a/src/post.php b/src/post.php index a47f52c..bfc4a99 100644 --- a/src/post.php +++ b/src/post.php @@ -1,126 +1,51 @@ prepare('SELECT COUNT(uid) FROM pastes WHERE uid = (:name)'); - $q->bindValue(':name', $name, PDO::PARAM_STR); - $q->execute(); - $result = $q->fetchColumn(); - // If it does, generate a new uid - } while($result > 0); - $conn = null; - return $name; -} +include_once "repositories/paste-repository.php"; +$pasteRepo = new PasteRepository(); -if(isset($_POST["type"])){ - //===New_Paste===// - if($_POST["type"]=="paste" && isset($_POST["text"])){ - /* Set paste details */ - $title = "Untitled"; - $text = $_POST["text"]; - $exposure = 0; - if(isset($_POST["title"]) && $_POST["title"]!="") - $title = $_POST["title"]; - if(isset($_POST["exposure"]) && is_numeric($_POST["exposure"])) - $exposure = $_POST["exposure"]; - $uid = generate_uid(); - $created = time(); - $expire = 0; - if(isset($_POST["expire"]) && is_numeric($_POST["expire"])) - $expire = $created + $_POST["expire"]; +if (isset($_POST["type"]) && isset($_POST["text"])) { + // Set paste details + $title = isset($_POST["title"]) && !empty($_POST["title"]) ? $_POST["title"] : "Untitled"; + $text = $_POST["text"]; + $exposure = isset($_POST["exposure"]) && is_numeric($_POST["exposure"]) ? $_POST["exposure"] : 0; + + // Common details for both create and edit + $uid = isset($_POST["uid"]) ? $_POST["uid"] : $pasteRepo->generateUniqueUID(); + $created = time(); + $expire = isset($_POST["expire"]) && is_numeric($_POST["expire"]) ? ($created + $_POST["expire"]) : 0; + + $owner = 0; + $syntax = isset($_POST["syntax"]) ? $_POST["syntax"] : "plain"; + + if (isset($_POST["asguest"]) && $_POST["asguest"] == "on") { $owner = 0; - $syntax = "plain"; - if(isset($_POST["syntax"])) - $syntax=$_POST["syntax"]; - if(isset($_POST["asguest"]) && $_POST["asguest"]=="on") - $owner = 0; - else if(isset($_COOKIE["pp_sid"]) && isset($_COOKIE["pp_skey"])){ - include "includes/user.php"; - $owner = GetUsersIDBySession($_COOKIE["pp_sid"],$_COOKIE["pp_skey"]); - } - /* Add paste to database */ - $conn = GetConnectionToDB(); - $QuerySTR = "INSERT INTO pastes (uid,title,text,created,expire,exposure,owner,highlight) - VALUES (:uid, :tit, :txt, :cre, :exp, :exposure, :own, :hl)"; - $stmt = $conn->prepare($QuerySTR); - $stmt->bindParam(':exp', $expire); - $stmt->bindParam(':uid', $uid); - $stmt->bindParam(':tit', $title); - $stmt->bindParam(':txt', $text); - $stmt->bindParam(':cre', $created); - $stmt->bindParam(':exposure', $exposure); - $stmt->bindParam(':own', $owner); - $stmt->bindParam(':hl', $syntax); - $stmt->execute(); - $conn = null; //close connection to database - header("Location: ".$uid); - die(); - } else if($_POST["type"]=="edit_paste" && isset($_POST["text"])){ - /* Set paste details */ - $title = "Untitled"; - $text = $_POST["text"]; - $exposure = 0; - if(isset($_POST["title"])) - $title = $_POST["title"]; - if(isset($_POST["exposure"]) && is_numeric($_POST["exposure"])) - $exposure = $_POST["exposure"]; - $uid = $_POST["uid"]; - $created = time(); - $expire = 0; - if(isset($_POST["expire"]) && is_numeric($_POST["expire"])) - $expire = $created + $_POST["expire"]; - $owner = 0; - $syntax = "plain"; - if(isset($_POST["syntax"])) - $syntax=$_POST["syntax"]; - if(isset($_POST["asguest"]) && $_POST["asguest"]=="on") - $owner = 0; - else if(isset($_COOKIE["pp_sid"]) && isset($_COOKIE["pp_skey"])){ - include "includes/user.php"; - $owner = GetUsersIDBySession($_COOKIE["pp_sid"],$_COOKIE["pp_skey"]); - } - /* Get the owner of the paste */ - $paste_owner = 0; - $conn = GetConnectionToDB(); - $stmt = $conn->query('SELECT owner FROM pastes WHERE uid="'.$uid.'"'); - if($result = $stmt->fetch(PDO::FETCH_ASSOC)){ - $paste_owner = $result['owner']; - } - /* Edit paste in database */ - if($owner === $paste_owner && $owner !== 0){ - $QuerySTR = " UPDATE pastes SET title=:tit,text=:txt,created=:cre,expire=:exp,exposure=:exposure,owner=:own,highlight=:hl - WHERE uid=:uid"; - $stmt = $conn->prepare($QuerySTR); - $stmt->bindParam(':exp', $expire); - $stmt->bindParam(':uid', $uid); - $stmt->bindParam(':tit', $title); - $stmt->bindParam(':txt', $text); - $stmt->bindParam(':cre', $created); - $stmt->bindParam(':exposure', $exposure); - $stmt->bindParam(':own', $owner); - $stmt->bindParam(':hl', $syntax); - $stmt->execute(); - $conn = null; //close connection to database - header("Location: ".$uid); - die(); + } elseif (isset($_COOKIE["pp_sid"]) && isset($_COOKIE["pp_skey"])) { + include "includes/user.php"; + $owner = GetUsersIDBySession($_COOKIE["pp_sid"], $_COOKIE["pp_skey"]); + } + + if ($_POST["type"] == "paste") { + // Add paste to the database using the repository + $result = $pasteRepo->create($uid, $title, $text, $created, $expire, $exposure, $owner, $syntax); + } elseif ($_POST["type"] == "edit_paste" && isset($_POST["uid"])) { + // Get the owner of the paste from the database + $existingPaste = $pasteRepo->readByUid($uid); + + // Edit paste in the database using the repository + if ($owner === $existingPaste["owner"] && $owner !== 0) { + $result = $pasteRepo->update($existingPaste["id"], $uid, $title, $text, $created, $expire, $exposure, $owner, $syntax); } else { - $conn = null; //close connection to database echo "

This paste does not belong to you!

"; die(); } } + + if ($result) { + header("Location: " . $uid); + die(); + } else { + echo "

Error processing the paste!

"; + die(); + } } diff --git a/src/repositories/paste-repository.php b/src/repositories/paste-repository.php new file mode 100644 index 0000000..03b5ac6 --- /dev/null +++ b/src/repositories/paste-repository.php @@ -0,0 +1,228 @@ +conn = GetConnectionToDB(); + } + + function __destruct() + { + $this->conn = null; + } + + // Create a new paste + public function create($uid, $title, $text, $created, $expire, $exposure, $owner, $highlight) + { + $query = "INSERT INTO " . $this->table_name . " + (uid, title, text, created, expire, exposure, owner, highlight) + VALUES (:uid, :title, :text, :created, :expire, :exposure, :owner, :highlight)"; + + $stmt = $this->conn->prepare($query); + + $stmt->bindParam(":uid", $uid); + $stmt->bindParam(":title", $title); + $stmt->bindParam(":text", $text); + $stmt->bindParam(":created", $created); + $stmt->bindParam(":expire", $expire); + $stmt->bindParam(":exposure", $exposure); + $stmt->bindParam(":owner", $owner); + $stmt->bindParam(":highlight", $highlight); + + if ($stmt->execute()) { + return true; + } else { + return false; + } + } + + // Read a paste by ID + public function read($id) + { + $query = "SELECT * FROM " . $this->table_name . " WHERE id = :id"; + $stmt = $this->conn->prepare($query); + $stmt->bindParam(":id", $id); + $stmt->execute(); + + return $stmt->fetch(PDO::FETCH_ASSOC); + } + + // Read a paste by UID + public function readByUid($uid) + { + $query = "SELECT * FROM " . $this->table_name . " WHERE uid = :uid"; + $stmt = $this->conn->prepare($query); + $stmt->bindParam(":uid", $uid); + $stmt->execute(); + + return $stmt->fetch(PDO::FETCH_ASSOC); + } + + // Update a paste + public function update($id, $uid, $title, $text, $created, $expire, $exposure, $owner, $highlight) + { + $query = "UPDATE " . $this->table_name . " SET + uid = :uid, + title = :title, + text = :text, + created = :created, + expire = :expire, + exposure = :exposure, + owner = :owner, + highlight = :highlight + WHERE id = :id"; + + $stmt = $this->conn->prepare($query); + + $stmt->bindParam(":id", $id); + $stmt->bindParam(":uid", $uid); + $stmt->bindParam(":title", $title); + $stmt->bindParam(":text", $text); + $stmt->bindParam(":created", $created); + $stmt->bindParam(":expire", $expire); + $stmt->bindParam(":exposure", $exposure); + $stmt->bindParam(":owner", $owner); + $stmt->bindParam(":highlight", $highlight); + + if ($stmt->execute()) { + return true; + } else { + return false; + } + } + + // Delete a paste by ID + public function delete($id) + { + $query = "DELETE FROM " . $this->table_name . " WHERE id = :id"; + $stmt = $this->conn->prepare($query); + $stmt->bindParam(":id", $id); + + if ($stmt->execute()) { + return true; + } else { + return false; + } + } + + // Get pastes with a specific exposure value and limit + public function getPastesWithExposure($exposureValue, $limit) + { + $query = "SELECT * FROM " . $this->table_name . " WHERE exposure = :exposureValue ORDER BY id DESC LIMIT :limit"; + $stmt = $this->conn->prepare($query); + $stmt->bindParam(":exposureValue", $exposureValue, PDO::PARAM_INT); + $stmt->bindParam(":limit", $limit, PDO::PARAM_INT); + $stmt->execute(); + + return $stmt->fetchAll(PDO::FETCH_ASSOC); + } + + // Remove expired pastes + public function removeExpiredPastes() + { + $time = time(); + $query = "DELETE FROM " . $this->table_name . " WHERE `expire` < :time AND `expire` > 0"; + $stmt = $this->conn->prepare($query); + $stmt->bindParam(':time', $time, PDO::PARAM_INT); + + if ($stmt->execute()) { + return 'OK! 200'; + } else { + return 'Error!'; + } + } + + // Delete a paste by UID and owner + public function deletePasteByUID($uid, $owner) + { + $query = "SELECT * FROM " . $this->table_name . " WHERE uid = :uid"; + $stmt = $this->conn->prepare($query); + $stmt->bindParam(':uid', $uid); + $stmt->execute(); + + if ($stmt->rowCount() > 0) { + while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { + if ($row['owner'] === $owner) { + $deleteQuery = "DELETE FROM " . $this->table_name . " WHERE id = :id"; + $deleteStmt = $this->conn->prepare($deleteQuery); + $deleteStmt->bindParam(':id', $row['id']); + $deleteStmt->execute(); + + return 'OK! 200'; + } else { + return 'You are not the owner of the paste ' . $row['uid']; + } + } + } else { + return 'The paste ' . $uid . ' does not exist'; + } + } + + // Generate a random unique UID for a new paste + public function generateUniqueUID() + { + $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; + $uid = ''; + + // Maximum number of retries to find an unused name + $maxRetries = 500; + $tries = $maxRetries; + + do { + if ($tries-- === 0) { + throw new Exception('Gave up trying to find an unused name', 500); + } + + for ($i = 0; $i < 8; $i++) { + $uid .= $chars[mt_rand(0, 61)]; + } + + $query = "SELECT COUNT(uid) FROM " . $this->table_name . " WHERE uid = :uid"; + $stmt = $this->conn->prepare($query); + $stmt->bindParam(':uid', $uid, PDO::PARAM_STR); + $stmt->execute(); + $result = $stmt->fetchColumn(); + } while ($result > 0); + + return $uid; + } + + // Get syntax highlight for a paste by UID + public function getSyntaxHighlightByUID($uid) + { + $query = "SELECT highlight FROM " . $this->table_name . " WHERE uid = :uid"; + $stmt = $this->conn->prepare($query); + $stmt->bindParam(':uid', $uid); + $stmt->execute(); + + if ($stmt->rowCount() > 0) { + $result = $stmt->fetch(PDO::FETCH_ASSOC); + return $result['highlight']; + } else { + return ""; + } + } + + // Get pastes by owner ID and exposure condition + public function getPastesByOwner($ownerID, $includePrivate = false) + { + $query = "SELECT * FROM " . $this->table_name . " WHERE owner = :ownerID"; + + if (!$includePrivate) { + $query .= " AND exposure = 0"; + } + + $query .= " ORDER BY id DESC"; + + $stmt = $this->conn->prepare($query); + $stmt->bindParam(":ownerID", $ownerID); + $stmt->execute(); + + return $stmt->fetchAll(PDO::FETCH_ASSOC); + } +} diff --git a/src/views/_layout.php b/src/views/_layout.php index 3eda230..358c543 100644 --- a/src/views/_layout.php +++ b/src/views/_layout.php @@ -1,4 +1,6 @@ no content

'; } @@ -12,19 +14,17 @@ if (!isset($content)) { '; - $dir = ""; - if (isset($_GET["user"]) || isset($_GET["page"]) && $_GET["page"] == "edit") $dir = "../"; - echo ''; + echo ''; echo ''; - echo ''; - echo ''; - echo ''; + echo ''; + echo ''; + echo ''; - echo ''; - echo ''; - echo ''; + echo ''; + echo ''; + echo ''; echo "