aboutsummaryrefslogtreecommitdiff
path: root/lib/posts.php
diff options
context:
space:
mode:
Diffstat (limited to 'lib/posts.php')
-rw-r--r--lib/posts.php306
1 files changed, 218 insertions, 88 deletions
diff --git a/lib/posts.php b/lib/posts.php
index 1537749..8ffb92b 100644
--- a/lib/posts.php
+++ b/lib/posts.php
@@ -1,9 +1,202 @@
<?php
+class Post extends model {
+
+ const DB_TABLE = 'posts';
+
+ public int $id;
+ public string $title;
+ public string $md;
+ public string $html;
+ public string $tocHtml;
+ public string $text;
+ public int $ts;
+ public int $updateTs;
+ public bool $visible;
+ public bool $toc;
+ public string $shortName;
+
+ function edit(array $fields) {
+ $cur_ts = time();
+ if (!$this->visible && $fields['visible'])
+ $fields['ts'] = $cur_ts;
+
+ $fields['update_ts'] = $cur_ts;
+
+ if ($fields['md'] != $this->md) {
+ $fields['html'] = markup::markdownToHtml($fields['md']);
+ $fields['text'] = markup::htmlToText($fields['html']);
+ }
+
+ if ((isset($fields['toc']) && $fields['toc']) || $this->toc) {
+ $fields['toc_html'] = markup::toc($fields['md']);
+ }
+
+ parent::edit($fields);
+ $this->updateImagePreviews();
+ }
+
+ function updateHtml() {
+ $html = markup::markdownToHtml($this->md);
+ $this->html = $html;
+
+ DB()->query("UPDATE posts SET html=? WHERE id=?", $html, $this->id);
+ }
+
+ function updateText() {
+ $html = markup::markdownToHtml($this->md);
+ $text = markup::htmlToText($html);
+ $this->text = $text;
+
+ DB()->query("UPDATE posts SET text=? WHERE id=?", $text, $this->id);
+ }
+
+ function getDescriptionPreview(int $len): string {
+ if (mb_strlen($this->text) >= $len)
+ return mb_substr($this->text, 0, $len-3).'...';
+ return $this->text;
+ }
+
+ function getFirstImage(): ?Upload {
+ if (!preg_match('/\{image:([\w]{8})/', $this->md, $match))
+ return null;
+ return uploads::getUploadByRandomId($match[1]);
+ }
+
+ function getUrl(): string {
+ return $this->shortName != '' ? "/{$this->shortName}/" : "/{$this->id}/";
+ }
+
+ function getDate(): string {
+ return date('j M', $this->ts);
+ }
+
+ function getYear(): int {
+ return (int)date('Y', $this->ts);
+ }
+
+ function getFullDate(): string {
+ return date('j F Y', $this->ts);
+ }
+
+ function getUpdateDate(): string {
+ return date('j M', $this->updateTs);
+ }
+
+ function getFullUpdateDate(): string {
+ return date('j F Y', $this->updateTs);
+ }
+
+ function getHtml(bool $is_retina, string $theme): string {
+ $html = $this->html;
+ $html = markup::htmlImagesFix($html, $is_retina, $theme);
+ return $html;
+ }
+
+ function getToc(): ?string {
+ return $this->toc ? $this->tocHtml : null;
+ }
+
+ function isUpdated(): bool {
+ return $this->updateTs && $this->updateTs != $this->ts;
+ }
+
+ /**
+ * @return Tag[]
+ */
+ function getTags(): array {
+ $db = DB();
+ $q = $db->query("SELECT tags.* FROM posts_tags
+ LEFT JOIN tags ON tags.id=posts_tags.tag_id
+ WHERE posts_tags.post_id=?
+ ORDER BY posts_tags.tag_id", $this->id);
+ return array_map('Tag::create_instance', $db->fetchAll($q));
+ }
+
+ /**
+ * @return int[]
+ */
+ function getTagIds(): array {
+ $ids = [];
+ $db = DB();
+ $q = $db->query("SELECT tag_id FROM posts_tags WHERE post_id=? ORDER BY tag_id", $this->id);
+ while ($row = $db->fetch($q)) {
+ $ids[] = (int)$row['tag_id'];
+ }
+ return $ids;
+ }
+
+ function setTagIds(array $new_tag_ids) {
+ $cur_tag_ids = $this->getTagIds();
+ $add_tag_ids = array_diff($new_tag_ids, $cur_tag_ids);
+ $rm_tag_ids = array_diff($cur_tag_ids, $new_tag_ids);
+
+ $db = DB();
+ if (!empty($add_tag_ids)) {
+ $rows = [];
+ foreach ($add_tag_ids as $id)
+ $rows[] = ['post_id' => $this->id, 'tag_id' => $id];
+ $db->multipleInsert('posts_tags', $rows);
+ }
+
+ if (!empty($rm_tag_ids))
+ $db->query("DELETE FROM posts_tags WHERE post_id=? AND tag_id IN(".implode(',', $rm_tag_ids).")", $this->id);
+
+ $upd_tag_ids = array_merge($new_tag_ids, $rm_tag_ids);
+ $upd_tag_ids = array_unique($upd_tag_ids);
+ foreach ($upd_tag_ids as $id)
+ tags::recountTagPosts($id);
+ }
+
+ /**
+ * @param bool $update Whether to overwrite preview if already exists
+ * @return int
+ * @throws Exception
+ */
+ function updateImagePreviews(bool $update = false): int {
+ $images = [];
+ if (!preg_match_all('/\{image:([\w]{8}),(.*?)}/', $this->md, $matches))
+ return 0;
+
+ for ($i = 0; $i < count($matches[0]); $i++) {
+ $id = $matches[1][$i];
+ $w = $h = null;
+ $opts = explode(',', $matches[2][$i]);
+ foreach ($opts as $opt) {
+ if (str_contains($opt, '=')) {
+ list($k, $v) = explode('=', $opt);
+ if ($k == 'w')
+ $w = (int)$v;
+ else if ($k == 'h')
+ $h = (int)$v;
+ }
+ }
+ $images[$id][] = [$w, $h];
+ }
+
+ if (empty($images))
+ return 0;
+
+ $images_affected = 0;
+ $uploads = uploads::getUploadsByRandomId(array_keys($images), true);
+ foreach ($uploads as $u) {
+ foreach ($images[$u->randomId] as $s) {
+ list($w, $h) = $s;
+ list($w, $h) = $u->getImagePreviewSize($w, $h);
+ if ($u->createImagePreview($w, $h, $update, $u->imageMayHaveAlphaChannel()))
+ $images_affected++;
+ }
+ }
+
+ return $images_affected;
+ }
+
+}
+
class posts {
- public static function getPostsCount(bool $include_hidden = false): int {
- $db = getDb();
+ static function getCount(bool $include_hidden = false): int {
+ $db = DB();
$sql = "SELECT COUNT(*) FROM posts";
if (!$include_hidden) {
$sql .= " WHERE visible=1";
@@ -11,14 +204,14 @@ class posts {
return (int)$db->result($db->query($sql));
}
- public static function getPostsCountByTagId(int $tag_id, bool $include_hidden = false): int {
- $db = getDb();
+ static function getCountByTagId(int $tag_id, bool $include_hidden = false): int {
+ $db = DB();
if ($include_hidden) {
$sql = "SELECT COUNT(*) FROM posts_tags WHERE tag_id=?";
} else {
$sql = "SELECT COUNT(*) FROM posts_tags
- LEFT JOIN posts ON posts.id=posts_tags.post_id
- WHERE posts_tags.tag_id=? AND posts.visible=1";
+ LEFT JOIN posts ON posts.id=posts_tags.post_id
+ WHERE posts_tags.tag_id=? AND posts.visible=1";
}
return (int)$db->result($db->query($sql, $tag_id));
}
@@ -26,8 +219,8 @@ class posts {
/**
* @return Post[]
*/
- public static function getPosts(int $offset = 0, int $count = -1, bool $include_hidden = false): array {
- $db = getDb();
+ static function getList(int $offset = 0, int $count = -1, bool $include_hidden = false): array {
+ $db = DB();
$sql = "SELECT * FROM posts";
if (!$include_hidden)
$sql .= " WHERE visible=1";
@@ -41,11 +234,11 @@ class posts {
/**
* @return Post[]
*/
- public static function getPostsByTagId(int $tag_id, bool $include_hidden = false): array {
- $db = getDb();
+ static function getPostsByTagId(int $tag_id, bool $include_hidden = false): array {
+ $db = DB();
$sql = "SELECT posts.* FROM posts_tags
- LEFT JOIN posts ON posts.id=posts_tags.post_id
- WHERE posts_tags.tag_id=?";
+ LEFT JOIN posts ON posts.id=posts_tags.post_id
+ WHERE posts_tags.tag_id=?";
if (!$include_hidden)
$sql .= " AND posts.visible=1";
$sql .= " ORDER BY posts.ts DESC";
@@ -53,8 +246,8 @@ class posts {
return array_map('Post::create_instance', $db->fetchAll($q));
}
- public static function add(array $data = []): int|bool {
- $db = getDb();
+ static function add(array $data = []): int|bool {
+ $db = DB();
$html = \markup::markdownToHtml($data['md']);
$text = \markup::htmlToText($html);
@@ -70,64 +263,41 @@ class posts {
$id = $db->insertId();
- $post = posts::get($id);
+ $post = self::get($id);
$post->updateImagePreviews();
return $id;
}
- public static function delete(Post $post): void {
+ static function delete(Post $post): void {
$tags = $post->getTags();
- $db = getDb();
+ $db = DB();
$db->query("DELETE FROM posts WHERE id=?", $post->id);
$db->query("DELETE FROM posts_tags WHERE post_id=?", $post->id);
foreach ($tags as $tag)
- self::recountPostsWithTag($tag->id);
+ tags::recountTagPosts($tag->id);
}
- public static function getTagIds(array $tags): array {
- $found_tags = [];
- $map = [];
-
- $db = getDb();
- $q = $db->query("SELECT id, tag FROM tags
- WHERE tag IN ('".implode("','", array_map(function($tag) use ($db) { return $db->escape($tag); }, $tags))."')");
- while ($row = $db->fetch($q)) {
- $found_tags[] = $row['tag'];
- $map[$row['tag']] = (int)$row['id'];
- }
-
- $notfound_tags = array_diff($tags, $found_tags);
- if (!empty($notfound_tags)) {
- foreach ($notfound_tags as $tag) {
- $db->insert('tags', ['tag' => $tag]);
- $map[$tag] = $db->insertId();
- }
- }
-
- return $map;
- }
-
- public static function get(int $id): ?Post {
- $db = getDb();
+ static function get(int $id): ?Post {
+ $db = DB();
$q = $db->query("SELECT * FROM posts WHERE id=?", $id);
return $db->numRows($q) ? new Post($db->fetch($q)) : null;
}
- public static function getPostByName(string $short_name): ?Post {
- $db = getDb();
+ static function getByName(string $short_name): ?Post {
+ $db = DB();
$q = $db->query("SELECT * FROM posts WHERE short_name=?", $short_name);
return $db->numRows($q) ? new Post($db->fetch($q)) : null;
}
- public static function getPostsById(array $ids, bool $flat = false): array {
+ static function getPostsById(array $ids, bool $flat = false): array {
if (empty($ids)) {
return [];
}
- $db = getDb();
+ $db = DB();
$posts = array_fill_keys($ids, null);
$q = $db->query("SELECT * FROM posts WHERE id IN(".implode(',', $ids).")");
@@ -148,44 +318,4 @@ class posts {
return $posts;
}
- public static function getAllTags(bool $include_hidden = false): array {
- $db = getDb();
- $field = $include_hidden ? 'posts_count' : 'visible_posts_count';
- $q = $db->query("SELECT * FROM tags WHERE $field > 0 ORDER BY $field DESC, tag");
- return array_map('Tag::create_instance', $db->fetchAll($q));
- }
-
- public static function getTag(string $tag): ?Tag {
- $db = getDb();
- $q = $db->query("SELECT * FROM tags WHERE tag=?", $tag);
- return $db->numRows($q) ? new Tag($db->fetch($q)) : null;
- }
-
- /**
- * @param int $tag_id
- */
- public static function recountPostsWithTag($tag_id) {
- $db = getDb();
- $count = $db->result($db->query("SELECT COUNT(*) FROM posts_tags WHERE tag_id=?", $tag_id));
- $vis_count = $db->result($db->query("SELECT COUNT(*) FROM posts_tags
- LEFT JOIN posts ON posts.id=posts_tags.post_id
- WHERE posts_tags.tag_id=? AND posts.visible=1", $tag_id));
- $db->query("UPDATE tags SET posts_count=?, visible_posts_count=? WHERE id=?",
- $count, $vis_count, $tag_id);
- }
-
- public static function splitStringToTags(string $tags): array {
- $tags = trim($tags);
- if ($tags == '') {
- return [];
- }
-
- $tags = preg_split('/,\s+/', $tags);
- $tags = array_filter($tags, function($tag) { return trim($tag) != ''; });
- $tags = array_map('trim', $tags);
- $tags = array_map('mb_strtolower', $tags);
-
- return $tags;
- }
-
-}
+} \ No newline at end of file