596 lines
20 KiB
PHP
596 lines
20 KiB
PHP
<?php
|
|
|
|
// It's good practice to use namespaces, e.g.:
|
|
// namespace VintageCoding\Models;
|
|
// namespace VintageCoding\Repositories;
|
|
|
|
require_once 'functions/db.php'; // For exec_stmt() and get_connection() (though get_connection is used by exec_stmt)
|
|
require_once 'functions/user.php'; // For User and Author classes
|
|
require_once 'functions/space.php';
|
|
|
|
// -- Data Transfer Object for Topics --
|
|
class Topic
|
|
{
|
|
public int $topicId;
|
|
public string $name;
|
|
|
|
public function __construct(int $topicId, string $name)
|
|
{
|
|
$this->topicId = $topicId;
|
|
$this->name = $name;
|
|
}
|
|
|
|
public function getId(): int
|
|
{
|
|
return $this->topicId;
|
|
}
|
|
|
|
public function getName(): string
|
|
{
|
|
return $this->name;
|
|
}
|
|
}
|
|
|
|
// -- Post Data Models (as previously defined, with setReadCount in Post) --
|
|
class Post
|
|
{
|
|
private int $space;
|
|
private ?int $id;
|
|
private User $creator;
|
|
private int $postType;
|
|
private ?int $status;
|
|
private int $seenCount;
|
|
private ?DateTime $createdAt;
|
|
private ?DateTime $updatedAt;
|
|
|
|
public function __construct(int $space = 2025, ?int $id = null, User $creator, int $postType, int $status)
|
|
{
|
|
error_log('Instantiating a post');
|
|
$this->space = $space;
|
|
$this->id = $id;
|
|
$this->creator = $creator;
|
|
$this->postType = $postType;
|
|
$this->status = $status;
|
|
|
|
$this->seenCount = 0;
|
|
}
|
|
|
|
public static function exists(int $id): bool
|
|
{
|
|
$stmt = 'SELECT count(id) FROM post WHERE id = ?';
|
|
$result = exec_stmt($stmt, 'i', $id)->fetch_assoc();
|
|
if ($result['count(id)'] == 1)
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
public static function retrieveFromDB(int $id): ?Post
|
|
{
|
|
$stmt = 'SELECT * FROM post WHERE id = ?';
|
|
$post = exec_stmt($stmt, 'i', $id)->fetch_assoc();
|
|
if ($post) {
|
|
$creator = User::retrieveFromDB($post['creator']);
|
|
|
|
switch ($post['postType']) {
|
|
case 1:
|
|
return new Essay($post['space'], $id, $creator, 1, $post['status'], $post['title'], $post['markdown'], $post['excerpt']);
|
|
case 2:
|
|
return new Moment($post['space'], $id, $creator, 2, $post['status'], $post['images'], $post['caption']);
|
|
case 3:
|
|
return new Thought($post['space'], $id, $creator, 3, $post['status'], $post['thought']);
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public static function getComposeHTML(): string
|
|
{
|
|
$user = unserialize($_SESSION['user']);
|
|
|
|
// TODO: Need to store the current space in SESSION and use that to auto-select a Space
|
|
// TODO: List the user's spaces or let them search for a space or quick select a favorited space
|
|
$html = '
|
|
<div class="med_width std_border center padding modalContent">
|
|
<h3 id="newPostLabel">New Thought</h3>
|
|
<form method="post" action="director.php" enctype="multipart/form-data">
|
|
<input type="hidden" name="formID" value="newPost">
|
|
<input type="hidden" name="redirect" value="" id="redirect">
|
|
<input type="hidden" name="postType" value="Thought" id="postType">
|
|
|
|
<div id="newThought" class="column">
|
|
<input type="text" name="thought" placeholder="Jot a Thought." autofocus id="thought">
|
|
</div>
|
|
|
|
<div id="newMoment" class="column" style="display: none;">
|
|
<input type="file" name="image" accept="image/png" id="momentImageUpload">
|
|
<input type="text" name="caption" placeholder="Caption goes here." id="caption">
|
|
</div>
|
|
|
|
<div id="newEssay" class="column" style="display: none;">
|
|
<input type="text" name="title" placeholder="Title" autofocus id="title">
|
|
<textarea name="markdown" placeholder="#Heading" id="markdown"></textarea>
|
|
<input type="text" name="excerpt" placeholder="A 2-3 sentence summary." id="excerpt">
|
|
</div>
|
|
|
|
<div class="column" id="postSpaces">
|
|
';
|
|
|
|
$spaces = $user->getAllSpaces();
|
|
foreach ($spaces as $s) {
|
|
$html .= '
|
|
<label class="form_checkbox_container">' . $s->getName() . ' <i class="nf ' . getSpaceIcon($s) . ' left_margin"></i>
|
|
<input type="radio" name="space" value="' . $s->getId() . '" id="space-' . $s->getId() . '">
|
|
<span class="checkmark"></span>
|
|
</label>
|
|
';
|
|
}
|
|
|
|
$html .= '
|
|
</div>
|
|
|
|
<input class="button" type="submit" value="Share" id="share">
|
|
</form>
|
|
<div class="line std_border"></div>
|
|
<div id="newModalNav" class="row space_between">
|
|
<span id="newNavThought" class="link">Thought</span>
|
|
<span id="newNavMoment" class="link">Moment</span>
|
|
<span id="newNavEssay" class="link">Essay</span>
|
|
</div>
|
|
</div>
|
|
';
|
|
|
|
return $html;
|
|
}
|
|
|
|
public static function getEditHTML($id)
|
|
{
|
|
$user = unserialize($_SESSION['user']);
|
|
$post = Post::retrieveFromDB($id);
|
|
if (!$post)
|
|
return '';
|
|
|
|
// TODO: Need to plumb this into the DB via AJAX.
|
|
// TODO: Need to store the current space in SESSION and use that to auto-select a Space
|
|
// TODO: List the user's spaces or let them search for a space or quick select a favorited space
|
|
$html = '
|
|
<div class="med_width std_border center padding modalContent">
|
|
<h3 id="editPostLabel">New Thought</h3>
|
|
<form method="post" action="director.php">
|
|
<input type="hidden" name="formID" value="editPost">
|
|
<input type="hidden" name="id" value="' . $id . '">
|
|
<input type="hidden" name="redirect" value="" id="redirect">
|
|
<input type="hidden" name="postType" value="' . $post->getPostType() . '" id="postType" value="' . $post->getPostType() . '">
|
|
<input type="hidden" name="space" value="' . $post->getSpace() . '">
|
|
';
|
|
|
|
switch ($post->getPostType()) {
|
|
case 1:
|
|
if (!is_a($post, 'Essay'))
|
|
return;
|
|
|
|
$html .= '
|
|
|
|
<div id="newEssay" class="column" style="display: none;">
|
|
<input type="text" name="title" placeholder="Title" autofocus id="title" value="' . $post->getTitle() . '">
|
|
<textarea name="markdown" placeholder="#Heading" id="markdown" value="' . $post->getMarkdown() . '"></textarea>
|
|
<input type="text" name="excerpt" placeholder="A 2-3 sentence summary." id="excerpt" value="' . $post->getExcerpt() . '">
|
|
</div>
|
|
|
|
<div class="column" id="postSpaces">
|
|
';
|
|
|
|
$spaces = $user->getAllSpaces();
|
|
foreach ($spaces as $s) {
|
|
$html .= '
|
|
<label class="form_checkbox_container">' . $s->getName() . ' <i class="nf ' . getSpaceIcon($s) . ' left_margin"></i>
|
|
<input type="radio" name="space" value="' . $s->getId() . '" id="space-' . $s->getId() . '"' . ($post->getSpace() == $s->getId() ? ' checked' : '') . '>
|
|
<span class="checkmark"></span>
|
|
</label>
|
|
';
|
|
}
|
|
|
|
$html .= '
|
|
</div>
|
|
';
|
|
break;
|
|
case 2:
|
|
if (!is_a($post, 'Moment'))
|
|
return;
|
|
|
|
$html .= '
|
|
<div id="newMoment" class="column" style="display: none;">
|
|
<input type="text" name="caption" placeholder="Caption goes here." autofocus id="caption" value="' . $post->getCaption() . '">
|
|
</div>
|
|
';
|
|
break;
|
|
case 3:
|
|
if (!is_a($post, 'Thought'))
|
|
return;
|
|
|
|
$html .= '
|
|
<div id="newThought" class="column">
|
|
<input type="text" name="thought" placeholder="Jot a Thought." autofocus id="thought" value="' . $post->getThought() . '">
|
|
</div>
|
|
';
|
|
break;
|
|
}
|
|
|
|
$html .= '
|
|
<input class="button" type="submit" value="Share" id="share">
|
|
</form>
|
|
<div class="line std_border"></div>
|
|
</div>
|
|
';
|
|
|
|
return $html;
|
|
}
|
|
|
|
public function setId(int $id): void
|
|
{
|
|
$this->id = $id;
|
|
}
|
|
|
|
public function getId(): int
|
|
{
|
|
return $this->id;
|
|
}
|
|
|
|
public function getCreator(): User
|
|
{
|
|
return $this->creator;
|
|
}
|
|
|
|
public function getPostType(): int
|
|
{
|
|
return $this->postType;
|
|
}
|
|
|
|
public function getSeenCount(): int
|
|
{
|
|
return $this->seenCount;
|
|
}
|
|
|
|
public function getCreatedAt(): ?DateTime
|
|
{
|
|
return $this->createdAt;
|
|
}
|
|
|
|
public function getUpdatedAt(): ?DateTime
|
|
{
|
|
return $this->updatedAt;
|
|
}
|
|
|
|
public function getStatus(): ?DateTime
|
|
{
|
|
return $this->status;
|
|
}
|
|
|
|
public function incrementSeenCount(): void
|
|
{
|
|
$this->seenCount++;
|
|
}
|
|
|
|
public function setStatus(?int $status): void
|
|
{
|
|
$this->status = $status;
|
|
}
|
|
|
|
public function setSpace(int $space): void
|
|
{
|
|
$this->space = $space;
|
|
}
|
|
|
|
public function getSpace(): int
|
|
{
|
|
if (!isset($this->space)) {
|
|
$stmt = 'SELECT space from spacePosts WHERE post = ?';
|
|
$rawSpace = exec_stmt($stmt, 'i', $this->id)->fetch_assoc();
|
|
}
|
|
return $this->space;
|
|
}
|
|
}
|
|
|
|
class Essay extends Post
|
|
{
|
|
private string $title;
|
|
private string $markdown;
|
|
private string $excerpt;
|
|
/* private array $files; */
|
|
|
|
public function __construct(int $space, ?int $id = null, User $creator, int $postType, int $status, string $title, string $markdown, string $excerpt)
|
|
{
|
|
parent::__construct($space, $id, $creator, 1, $postType, $status);
|
|
|
|
$this->title = $title;
|
|
$this->excerpt = $excerpt;
|
|
$this->markdown = $markdown;
|
|
|
|
if ($id < 0) {
|
|
parent::setId($id * -1);
|
|
$stmt = 'INSERT INTO post (id, space, creator, postType, status, title, markdown, excerpt) VALUES (?, ?, ?, ?, ?, ?, ?, ?)';
|
|
$space = isset($space) ? $space : $creator->getHomeSpace()->getId();
|
|
exec_stmt($stmt, 'iiiiisss', $id * -1, $space, $creator->getId(), 1, 2, $title, $markdown, $excerpt);
|
|
$stmt = 'INSERT INTO spacePosts (post, space) VALUES (?, ?)';
|
|
exec_stmt($stmt, 'ii', $id * -1, $space);
|
|
}
|
|
}
|
|
|
|
public static function edit(int $id, string $title, string $markdown, string $excerpt, int $space)
|
|
{
|
|
$post = Post::retrieveFromDB($id);
|
|
if (!is_a($post, 'Essay'))
|
|
return;
|
|
|
|
$post->setTitle($title);
|
|
$post->setMarkdown($markdown);
|
|
$post->setExcerpt($excerpt);
|
|
$post->setSpace($space);
|
|
|
|
$stmt = 'UPDATE post SET title = ?, markdown = ?, excerpt = ?, space = ? WHERE id = ?';
|
|
exec_stmt($stmt, 'sssii', $title, $markdown, $excerpt, $space, $id);
|
|
}
|
|
|
|
public function getCardHTML(): ?string
|
|
{
|
|
/* <a href="user.php?view=display&id=' . parent::getCreator()->getId() . '">@' . parent::getCreator()->getUsername() . '</a> */
|
|
$html = '
|
|
<div class="full_width std_border padding center top_margin bottom_margin">
|
|
<a href="spaces.php?view=essay&id=' . $this->getId() . '" class="divLink">
|
|
<div class="row space_between full_width">
|
|
<div class="column std_width">
|
|
<h4>' . $this->title . '</h4>
|
|
</div>
|
|
|
|
';
|
|
|
|
if (isset($_SESSION['user'])) {
|
|
$user = unserialize($_SESSION['user']);
|
|
if ($user->getId() == parent::getCreator()->getId()) {
|
|
$html .= '
|
|
<div class="dropdown" style="z-index: 1;">
|
|
<i class="nf nf-md-dots_horizontal"></i>
|
|
<div class="sm_border padding glass dropdownContent">
|
|
<a class="underline link" onclick="editPost(' . parent::getId() . ')">Edit</a>
|
|
<a class="underline link" onclick="deletePost(' . parent::getId() . ')">Delete</a>
|
|
</div>
|
|
</div>
|
|
';
|
|
}
|
|
}
|
|
|
|
$html .= '
|
|
</div>
|
|
<div class="line"></div>
|
|
<div class="row full_width">
|
|
<p>' . $this->excerpt . '</p>
|
|
</div>
|
|
</a>
|
|
</div>
|
|
';
|
|
|
|
return $html;
|
|
}
|
|
|
|
public function setTitle(string $title)
|
|
{
|
|
$this->title = $title;
|
|
}
|
|
|
|
public function getTitle(): ?string
|
|
{
|
|
return $this->title;
|
|
}
|
|
|
|
public function setMarkdown(string $markdown)
|
|
{
|
|
$this->markdown = $markdown;
|
|
}
|
|
|
|
public function getMarkdown(): ?string
|
|
{
|
|
return $this->markdown;
|
|
}
|
|
|
|
public function getHTML(): string
|
|
{
|
|
$parsedown = new Parsedown();
|
|
$parsedown->setSafeMode(true);
|
|
return $parsedown->parse($this->markdown);
|
|
}
|
|
|
|
public function setExcerpt(string $excerpt)
|
|
{
|
|
$this->excerpt = $excerpt;
|
|
}
|
|
|
|
public function getExcerpt(): ?string
|
|
{
|
|
return $this->excerpt;
|
|
}
|
|
}
|
|
|
|
class Moment extends Post
|
|
{
|
|
private ?string $caption;
|
|
private $image;
|
|
|
|
public function __construct(int $space, ?int $id = null, User $creator, int $postType, int $status, $image, string $caption)
|
|
{
|
|
parent::__construct($space, $id, $creator, $postType, $status);
|
|
$this->caption = $caption;
|
|
$this->image = $image;
|
|
|
|
if ($id < 0) {
|
|
if (!isset($image['tmp_name']))
|
|
return;
|
|
mkdir($_ENV['IMG_UPLOAD'] . ($id * -1));
|
|
move_uploaded_file($image['tmp_name'], $_ENV['IMG_UPLOAD'] . ($id * -1) . '/' . $image['name']);
|
|
|
|
$this->image = $image['name'];
|
|
|
|
$stmt = 'INSERT INTO post (id, space, creator, postType, status, images, caption) VALUES (?, ?, ?, ?, ?, ?, ?)';
|
|
parent::setId($id * -1);
|
|
$space = isset($space) ? $space : $creator->getHomeSpace()->getId();
|
|
exec_stmt($stmt, 'iiiiiss', $id * -1, $space, $creator->getId(), 2, 2, $this->image, $this->caption);
|
|
$stmt = 'INSERT INTO spacePosts (post, space) VALUES (?, ?)';
|
|
exec_stmt($stmt, 'ii', $id * -1, $space);
|
|
}
|
|
}
|
|
|
|
public function getCardHTML(): ?string
|
|
{
|
|
$html = '
|
|
<div class="std_border padding center full_width top_margin bottom_margin rel" id="post-' . parent::getId() . '">
|
|
<div class="row space_between full_width">
|
|
<a href="user.php?view=display&id=' . parent::getCreator()->getId() . '">@' . parent::getCreator()->getUsername() . '</a>
|
|
|
|
|
|
';
|
|
|
|
if (isset($_SESSION['user'])) {
|
|
$user = unserialize($_SESSION['user']);
|
|
if ($user->getId() == parent::getCreator()->getId()) {
|
|
$html .= '
|
|
<div class="dropdown" style="z-index: 1;">
|
|
<i class="nf nf-md-dots_horizontal"></i>
|
|
<div class="sm_border padding glass dropdownContent">
|
|
<a class="underline link" onclick="editPost(' . parent::getId() . ')">Edit</a>
|
|
<a class="underline link" onclick="deletePost(' . parent::getId() . ')">Delete</a>
|
|
</div>
|
|
</div>
|
|
';
|
|
}
|
|
}
|
|
|
|
// TODO: If multiple photos, use components/core/slideshow.php
|
|
$html .= '
|
|
</div>
|
|
<div class="line"></div>
|
|
<div class="column">
|
|
<img src="/data/img/' . parent::getId() . '/' . $this->image . '" class="margin sm_border" style="max-width: 100%; height: auto;">
|
|
<div class="line"></div>
|
|
<p class="margin">' . $this->caption . '</p>
|
|
</div>
|
|
</div>
|
|
';
|
|
|
|
return $html;
|
|
}
|
|
|
|
public static function edit(int $id, string $caption, int $space)
|
|
{
|
|
$post = Post::retrieveFromDB($id);
|
|
if (!is_a($post, 'Moment'))
|
|
return;
|
|
|
|
$post->setCaption($caption);
|
|
$post->setSpace($space);
|
|
|
|
$stmt = 'UPDATE post SET caption = ?, space = ? WHERE id = ?';
|
|
exec_stmt($stmt, 'sii', $caption, $space, $id);
|
|
}
|
|
|
|
public function getCaption(): ?string
|
|
{
|
|
return $this->caption;
|
|
}
|
|
|
|
public function getImages(): ?array
|
|
{
|
|
return $this->image;
|
|
}
|
|
|
|
public function setCaption(?string $caption): void
|
|
{
|
|
$this->caption = $caption;
|
|
}
|
|
|
|
public function setImages(?array $image): void
|
|
{
|
|
$this->image = $image;
|
|
}
|
|
}
|
|
|
|
class Thought extends Post
|
|
{
|
|
private ?string $thought;
|
|
|
|
public function __construct(int $space, ?int $id = null, User $creator, int $postType, int $status, string $thought)
|
|
{
|
|
parent::__construct($space, $id, $creator, $postType, $status);
|
|
$this->thought = $thought;
|
|
|
|
if ($id < 0) {
|
|
$stmt = 'INSERT INTO post (id, space, creator, postType, status, thought) VALUES (?, ?, ?, ?, ?, ?)';
|
|
parent::setId($id * -1);
|
|
$space = isset($space) ? $space : $creator->getHomeSpace()->getId();
|
|
exec_stmt($stmt, 'iiiiis', $id * -1, $space, $creator->getId(), 3, 2, $this->thought);
|
|
$stmt = 'INSERT INTO spacePosts (post, space) VALUES (?, ?)';
|
|
exec_stmt($stmt, 'ii', $id * -1, $space);
|
|
}
|
|
}
|
|
|
|
public static function edit(int $id, string $thought, int $space)
|
|
{
|
|
error_log('Updating post ' . $id . ' to have thought = ' . $thought);
|
|
$post = Post::retrieveFromDB($id);
|
|
if (!is_a($post, 'Thought'))
|
|
return;
|
|
|
|
$post->setThought($thought);
|
|
$post->setSpace($space);
|
|
|
|
$stmt = 'UPDATE post SET thought = ?, space = ? WHERE id = ?';
|
|
exec_stmt($stmt, 'sii', $thought, $space, $id);
|
|
}
|
|
|
|
public function getCardHTML(): ?string
|
|
{
|
|
$html = '
|
|
<div class="std_border padding center full_width top_margin bottom_margin rel" id="post-' . parent::getId() . '">
|
|
<div class="row space_between full_width">
|
|
<a href="user.php?view=display&id=' . parent::getCreator()->getId() . '">@' . parent::getCreator()->getUsername() . '</a>
|
|
|
|
|
|
';
|
|
|
|
if (isset($_SESSION['user'])) {
|
|
$user = unserialize($_SESSION['user']);
|
|
if ($user->getId() == parent::getCreator()->getId()) {
|
|
$html .= '
|
|
<div class="dropdown" style="z-index: 1;">
|
|
<i class="nf nf-md-dots_horizontal"></i>
|
|
<div class="sm_border padding glass dropdownContent">
|
|
<a class="underline link" onclick="editPost(' . parent::getId() . ')">Edit</a>
|
|
<a class="underline link" onclick="deletePost(' . parent::getId() . ')">Delete</a>
|
|
</div>
|
|
</div>
|
|
';
|
|
}
|
|
}
|
|
|
|
$html .= '
|
|
</div>
|
|
<div class="line"></div>
|
|
<div class="row full_width">
|
|
<p>' . $this->thought . '</p>
|
|
</div>
|
|
</div>
|
|
';
|
|
|
|
return $html;
|
|
}
|
|
|
|
public function getThought(): ?string
|
|
{
|
|
return $this->thought;
|
|
}
|
|
|
|
public function setThought(?string $thought): void
|
|
{
|
|
$this->thought = $thought;
|
|
}
|
|
}
|