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