]> git.bts.cx Git - cx.git/blob - cx/lib/posts.php
988d00eb008c457b873b67876d33f581213b9bba
[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, $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, false, $draft, $title, $data, 1);
98 }
99
100 function cx_posts_update_post($post_id, $title, $slug, $date, $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_draft = ?,
116 post_title = ?,
117 post_data = ?
118 WHERE post_id == ?;';
119 //LIMIT 1;';
120 cx_db_exec($sql, $update_time, $slug, $date, $draft, $title, $data, $post_id);
121 }
122
123 function cx_posts_delete_post($post_id) {
124 $sql = 'DELETE FROM posts
125 WHERE post_id == ?;';
126 //LIMIT 1;';
127 cx_db_exec($sql, $post_id);
128 }
129
130 function cx_posts_get(int $limit = 0, bool $include_drafts = false) {
131 $sql = 'SELECT
132 post_id,
133 post_slug,
134 post_date,
135 post_is_draft,
136 post_title,
137 post_data
138 FROM posts
139 WHERE post_is_page == FALSE';
140
141 if ($include_drafts == false) {
142 $sql .= ' AND post_is_draft == FALSE';
143 }
144
145 $sql .= ' ORDER BY post_date DESC';
146
147 if ($limit > 0) {
148 $sql .= ' LIMIT ' . $limit;
149 }
150
151 $sql .= ';';
152
153 foreach (cx_db_query($sql) as $post) {
154 $p = new Post($post);
155 yield $p;
156 }
157 }
158
159 function cx_posts_find_post($post_id) {
160 $sql = 'SELECT
161 post_id,
162 post_slug,
163 post_date,
164 post_is_draft,
165 post_title,
166 post_data
167 FROM posts
168 WHERE post_is_page == FALSE
169 AND post_id == ?
170 LIMIT 1;';
171
172 foreach (cx_db_query($sql, $post_id) as $post) {
173 $p = new Post($post);
174 return $p;
175 }
176
177 return null;
178 }
179
180 function cx_posts_find_post_id($post_slug) {
181 $sql = 'SELECT
182 post_id
183 FROM posts
184 WHERE post_slug == ?
185 LIMIT 1;';
186
187 foreach (cx_db_query($sql, $post_slug) as $post) {
188 return $post['post_id'];
189 }
190
191 return null;
192 }
193
194 function cx_pages_get() {
195 $sql = 'SELECT
196 post_id,
197 post_slug,
198 post_date,
199 post_is_draft,
200 post_title,
201 post_data
202 FROM posts
203 WHERE post_is_page == TRUE
204 AND post_is_draft == FALSE
205 ORDER BY post_creation_time DESC;';
206
207 foreach (cx_db_query($sql) as $post) {
208 $p = new Post($post);
209 yield $p;
210 }
211 }
212
213 cx_setup_register(1, function() {
214 cx_db_exec('CREATE TABLE posts (
215 post_id INTEGER PRIMARY KEY,
216 post_site_id INTEGER,
217 post_creation_time INTEGER,
218 post_update_time INTEGER,
219 post_slug STRING,
220 post_date INTEGER,
221 post_is_page BOOLEAN,
222 post_is_draft BOOLEAN,
223 post_title STRING,
224 post_data BLOB,
225 post_data_version INTEGER,
226
227 FOREIGN KEY(post_site_id) REFERENCES sites(site_id)
228 );');
229 });