id = $id; $this->user = $user; $this->name = $name; $this->image = Config::getStoragePath() . $image; $this->content = $content; $this->postedAt = new DateTime($postedAt); } /* * Statics */ /** * Get a post by ID. * * Also get creator (`User` object). * * @param int $id Post ID * * @throws NotFound Post not found * @throws NotFound Creator of post was not found */ public static function getByID(int $id): Post { $db = Database::getInstance(); $stmt = $db->prepare( "SELECT * FROM egb_gaestebuch WHERE id = :ID" ); $stmt->bindValue(":ID", $id); $stmt->execute(); $data = $stmt->fetch(); if (!$data) throw new Exception("NotFound"); $user = User::getByID($data["benutzer_id"]); return new Post($data["id"], $user, null, null, $data["beitrag"], $data["zeitstempel"]); } /** * Create a new post. * * @param User $user Creator of post * @param string $content Post content * @param int $limit Limit for posts list to calculate number of pages * * @return array Number of pages after creation (in accordance with `limit`) and created post */ public static function create(User $user, string $content, int $limit): array { $content = substr(trim($content), 0, 250); $db = Database::getInstance(); $stmt = $db->prepare( "INSERT INTO egb_gaestebuch(benutzer_id, beitrag) VALUES(:USR, :CON)" ); $stmt->bindValue(":USR", $user->getID()); $stmt->bindValue(":CON", nl2br(htmlspecialchars($content))); $stmt->execute(); $lastId = $db->lastInsertId(); $stmt = $db->prepare( "SELECT COUNT(*) FROM egb_gaestebuch" ); $stmt->execute(); $count = $stmt->fetch(PDO::FETCH_COLUMN, 0); return [ "pages" => intdiv($count, $limit + 1) + 1, "post" => Post::getByID($lastId) ]; } /** * List of posts * * @param int $page Current page (offset) * @param int $limit Posts per page * @param bool $authed If `true`, include full `User` object. Defaults to `false` * * @return array Number of pages and posts of selected page */ public static function list(int $page, int $limit, bool $authed = false): array { $db = Database::getInstance(); $stmt = $db->prepare( "SELECT COUNT(*) FROM egb_gaestebuch" ); $stmt->execute(); $count = $stmt->fetch(PDO::FETCH_COLUMN, 0); $stmt = $db->prepare( "SELECT * FROM egb_gaestebuch LIMIT $limit OFFSET " . ($page * $limit) ); $stmt->execute(); $data = $stmt->fetchAll(); $list = array_map( function ($item) use ($authed) { $user = User::getByID($item["benutzer_id"]); return new Post($item["id"], $authed ? $user : null, !$authed ? $user->getUsername() : null, !$authed ? $user->getImage() : null, $item["beitrag"], $item["zeitstempel"]); }, $data ); return ["pages" => intdiv($count, $limit + 1) + 1, "data" => $list]; } /* * Members */ /** * Update post * * Does nothing if new `content` is empty * * @param ?string $content New content * * @throws Failed Failed to update content */ public function update(?string $content): Post { $db = Database::getInstance(); // Make sure we do all changes or none $db->beginTransaction(); $failed = []; $reason = []; if (!empty($content)) { $content = substr(trim($content), 0, 250); $stmt = $db->prepare("UPDATE egb_gaestebuch SET beitrag = :CON WHERE id = :ID"); $stmt->bindValue(":CON", nl2br(htmlspecialchars($content))); $stmt->bindValue(":ID", $this->id); try { if (!$stmt->execute()) { $failed = ["content"]; $reason = ["generic"]; } } catch (Exception $e) { $failed = ["content"]; if ($e->getCode() === "23000") { $pdoErr = $stmt->errorInfo()[1]; $reason = ["SQL: $pdoErr"]; } else $reason = ["{$e->getCode()}"]; } } if (count($failed) > 0) { // We failed, go back $db->rollBack(); throw ApiError::failedUpdate($failed, $reason); } // Commit the changes $db->commit(); return Post::getByID($this->id); } /** * Delete post * * @param int $limit Limit of list for which the returned pages is calculated. * * @return array Returns deleted post and resulting amount of pages for a given limit. */ public function delete(int $limit): array { $db = Database::getInstance(); $stmt = $db->prepare("DELETE FROM egb_gaestebuch WHERE id = :ID"); $stmt->bindValue(":ID", $this->id); $stmt->execute(); $stmt = $db->prepare( "SELECT COUNT(*) FROM egb_gaestebuch" ); $stmt->execute(); $count = $stmt->fetch(PDO::FETCH_COLUMN, 0); return ["pages" => intdiv($count, $limit + 1) + 1, "data" => $this]; } /* * Getters */ /** * Get post ID */ public function getId(): int { return $this->id; } /** * Get post creator */ public function getUser(): User { return $this->user; } /** * Get post content */ public function getContent(): string { return $this->content; } /** * Get time when post was created */ public function getPostedAt(): DateTime { return $this->postedAt; } /* * JSON */ public function jsonSerialize(): array { $user = $this->user ? $this->user : [ "username" => $this->name, "image" => $this->image, ]; return [ 'id' => $this->id, 'user' => $user, 'content' => $this->content, 'postedAt' => $this->postedAt, ]; } }