]> git.bts.cx Git - cx.git/blob - cx/lib/posts.php
64374333e6636212486f084cd7c838c6016a2b96
[cx.git] / cx / lib / posts.php
1 <?php
2
3 cx_require('lib', 'db.php');
4 cx_require('lib', 'setup.php');
5 cx_require('lib', 'markdown.php');
6
7 class PostMetadata {
8         public $hero_image;
9         public $hero_image_alt;
10
11         public function __construct($dict) {
12                 $this->hero_image = isset($dict['post_hero_image']) ? $dict['post_hero_image'] : null;
13                 $this->hero_image_alt = isset($dict['post_hero_image_alt']) ? $dict['post_hero_image_alt'] : null;
14         }
15 }
16
17 class Post {
18         public $id;
19         public $title;
20         public $slug;
21         public $date;
22         public $is_draft;
23         public $data;
24         public $html_content;
25         public $html_excerpt;
26
27         public function __construct($dict) {
28                 $this->id = $dict['post_id']; // FIXME, hide when not used?
29                 $this->title = $dict['post_title'];
30                 $this->slug = $dict['post_slug'];
31                 $this->date = $dict['post_date'];
32                 $this->is_draft = $dict['post_is_draft'];
33                 $this->data = $dict['post_data'];
34                 $this->html_content = cx_markdown_generate_html($this->data);
35                 $this->html_excerpt = null;
36
37                 // Read more...
38                 $segments = explode('---', $this->data, 2);
39                 if (count($segments) > 1) {
40                         $this->html_excerpt = cx_markdown_generate_html($segments[0]);
41                 }
42         }
43
44         public function get_metadata() {
45                 $data = [];
46
47                 $doc = new DOMDocument();
48                 $doc->loadHTML($this->html_content);
49
50                 $image_tag = $doc->getElementsByTagName('img')[0];
51
52                 if ($image_tag != null) {
53                         $data['post_hero_image'] = $image_tag->getAttribute('src');
54                         $data['post_hero_image_alt'] = htmlspecialchars($image_tag->getAttribute('alt'));
55                 }
56
57                 return new PostMetadata($data);
58         }
59 }
60
61 function cx_post_make_slug($title) {
62         $alnum_title = preg_replace('/[^A-Za-z0-9 ]?/', '', $title);
63         
64         $slug_components = explode(' ', $alnum_title, 10);
65         $slug_components = array_filter($slug_components);
66         $slug_components = array_values($slug_components); // re-index
67
68         $slug = join('-', $slug_components);
69         $slug = strtolower($slug);
70
71         return $slug;
72 }
73
74 function cx_posts_add_post($site_id, $title, $slug, $date, $page, $draft, $data) {
75         $creation_time = $update_time = time();
76         
77         if ($slug == null) {
78                 $slug = cx_post_make_slug($title);
79         }
80
81         if ($date == null) {
82                 $date = $update_time;
83         }
84
85         $sql = 'INSERT INTO posts (
86                         post_site_id,
87                         post_creation_time,
88                         post_update_time,
89                         post_slug,
90                         post_date,
91                         post_is_page,
92                         post_is_draft,
93                         post_title,
94                         post_data,
95                         post_data_version)
96                 VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?);';
97         cx_db_exec($sql, $site_id, $creation_time, $update_time, $slug, $date, $page, $draft, $title, $data, 1);
98 }
99
100 function cx_posts_update_post($post_id, $title, $slug, $date, $page, $draft, $data) {
101         $update_time = time();
102         
103         if ($slug == null) {
104                 $slug = cx_post_make_slug($title);
105         }
106
107         if ($date == null) {
108                 $date = $update_time;
109         }
110
111         $sql = 'UPDATE posts
112                 SET post_update_time = ?,
113                 post_slug = ?,
114                 post_date = ?,
115                 post_is_page = ?,
116                 post_is_draft = ?,
117                 post_title = ?,
118                 post_data = ?
119                 WHERE post_id == ?;';
120                 //LIMIT 1;';
121         cx_db_exec($sql, $update_time, $slug, $date, $page, $draft, $title, $data, $post_id);
122 }
123
124 function cx_posts_delete_post($post_id) {
125         $sql = 'DELETE FROM posts
126                 WHERE post_id == ?;';
127                 //LIMIT 1;';
128         cx_db_exec($sql, $post_id);
129 }
130
131 function cx_posts_get(int $limit = 0, int $offset = 0, bool $include_drafts = false) {
132         $sql = 'SELECT
133                 post_id,
134                 post_slug,
135                 post_date,
136                 post_is_draft,
137                 post_title,
138                 post_data
139                 FROM posts
140                 WHERE post_is_page == FALSE';
141         
142         if ($include_drafts == false) {
143                 $sql .= ' AND post_is_draft == FALSE';
144         }
145
146         $sql .= ' ORDER BY post_date DESC';
147         
148         if ($limit > 0) {
149                 $sql .= ' LIMIT ' . $limit;
150         }
151         
152         if ($offset > 0) {
153                 $sql .= ' OFFSET ' . $offset;
154         }
155
156         $sql .= ';';
157
158         foreach (cx_db_query($sql) as $post) {
159                 $p = new Post($post);
160                 yield $p;
161         }
162 }
163
164 function cx_posts_count(bool $include_drafts = false) {
165         $sql = 'SELECT
166                 COUNT(post_id) AS _count
167                 FROM posts
168                 WHERE post_is_page == FALSE';
169         
170         if ($include_drafts == false) {
171                 $sql .= ' AND post_is_draft == FALSE';
172         }
173
174         $sql .= ';';
175
176
177         foreach (cx_db_query($sql) as $count_details) {
178                 return $count_details['_count'];
179         }
180
181         return 0;
182 }
183
184 function cx_posts_find_post($post_id) {
185         $sql = 'SELECT
186                 post_id,
187                 post_slug,
188                 post_date,
189                 post_is_draft,
190                 post_title,
191                 post_data
192                 FROM posts
193                 WHERE post_id == ?
194                 LIMIT 1;';
195
196         foreach (cx_db_query($sql, $post_id) as $post) {
197                 $p = new Post($post);
198                 return $p;
199         }
200
201         return null;
202 }
203
204 function cx_posts_find_article_id($post_slug) {
205         $sql = 'SELECT
206                 post_id
207                 FROM posts
208                 WHERE post_slug == ?
209                 AND post_is_page == FALSE
210                 AND post_is_draft == FALSE
211                 LIMIT 1;';
212
213         foreach (cx_db_query($sql, $post_slug) as $post) {
214                 return $post['post_id'];
215         }
216
217         return null;
218 }
219
220 function cx_posts_find_page_id($post_slug) {
221         $sql = 'SELECT
222                 post_id
223                 FROM posts
224                 WHERE post_slug == ?
225                 AND post_is_page == TRUE
226                 AND post_is_draft == FALSE
227                 LIMIT 1;';
228
229         foreach (cx_db_query($sql, $post_slug) as $post) {
230                 return $post['post_id'];
231         }
232
233         return null;
234 }
235
236 function cx_pages_get() {
237         $sql = 'SELECT
238                 post_id,
239                 post_slug,
240                 post_date,
241                 post_is_draft,
242                 post_title,
243                 post_data
244                 FROM posts
245                 WHERE post_is_page == TRUE
246                 AND post_is_draft == FALSE
247                 ORDER BY post_creation_time DESC;';
248
249         foreach (cx_db_query($sql) as $post) {
250                 $p = new Post($post);
251                 yield $p;
252         }
253 }
254
255 cx_setup_register(1, function() {
256         cx_db_exec('CREATE TABLE posts (
257                         post_id INTEGER PRIMARY KEY,
258                         post_site_id INTEGER,
259                         post_creation_time INTEGER,
260                         post_update_time INTEGER,
261                         post_slug STRING,
262                         post_date INTEGER,
263                         post_is_page BOOLEAN,
264                         post_is_draft BOOLEAN,
265                         post_title STRING,
266                         post_data BLOB,
267                         post_data_version INTEGER,
268
269                         FOREIGN KEY(post_site_id) REFERENCES sites(site_id)
270                 );');
271 });