1
|
|
|
<?php |
2
|
|
|
declare(strict_types=1); |
3
|
|
|
defined('BASEPATH') OR exit('No direct script access allowed'); |
4
|
|
|
|
5
|
|
|
class Blogger { |
6
|
|
|
|
7
|
|
|
/** |
8
|
|
|
* Code Igniter Instance |
9
|
|
|
* @var object |
10
|
|
|
*/ |
11
|
|
|
private $ci; |
12
|
|
|
/** |
13
|
|
|
* Code Igniter DB Forge instance reference for simplicity. |
14
|
|
|
* @var object |
15
|
|
|
*/ |
16
|
|
|
private $dbforge; |
17
|
|
|
/** |
18
|
|
|
* Current Blog Table Name. |
19
|
|
|
* @var string |
20
|
|
|
*/ |
21
|
|
|
private $table_name; |
22
|
|
|
/** |
23
|
|
|
* String prefixed with ever blog name. |
24
|
|
|
* @var string |
25
|
|
|
*/ |
26
|
|
|
const TABLE_PREFIX = "blogger_posts"; |
27
|
|
|
/** |
28
|
|
|
* Name of this package for simplicity. |
29
|
|
|
* @var string |
30
|
|
|
*/ |
31
|
|
|
const PACKAGE = "francis94c/blog"; |
32
|
|
|
/** |
33
|
|
|
* Name of the dependent package for markdown. |
34
|
|
|
* @var string |
35
|
|
|
*/ |
36
|
|
|
const MARKDOWN_PACKAGE = "francis94c/ci-parsedown"; |
37
|
|
|
/** |
38
|
|
|
* Blog post create action. |
39
|
|
|
* @var string |
40
|
|
|
*/ |
41
|
|
|
const CREATE = "create"; |
42
|
|
|
/** |
43
|
|
|
* Blog post create and publish action. |
44
|
|
|
* @var string |
45
|
|
|
*/ |
46
|
|
|
const CREATE_AND_PUBLISH = "createAndPublish"; |
47
|
|
|
/** |
48
|
|
|
* Blog post edit action. |
49
|
|
|
* @var string |
50
|
|
|
*/ |
51
|
|
|
const EDIT = "edit"; |
52
|
|
|
/** |
53
|
|
|
* Blog post publish action. |
54
|
|
|
* @var string |
55
|
|
|
*/ |
56
|
|
|
const PUBLISH = "publish"; |
57
|
|
|
/** |
58
|
|
|
* Blog post delete action. |
59
|
|
|
* @var string |
60
|
|
|
*/ |
61
|
|
|
const DELETE = "delete"; |
62
|
|
|
/** |
63
|
|
|
* Blog post abort acction. This is an action taken internally when other |
64
|
|
|
* actions fail. |
65
|
|
|
* @var string |
66
|
|
|
*/ |
67
|
|
|
const ABORT = "abortAction"; |
68
|
|
|
/** |
69
|
|
|
* Blog post no action. |
70
|
|
|
* @var string |
71
|
|
|
*/ |
72
|
|
|
const NO_ACTION = "no_action"; |
73
|
|
|
/** |
74
|
|
|
* Constructor |
75
|
|
|
* @param mixed $params associative array of parameters. See README.md |
76
|
|
|
*/ |
77
|
|
|
function __construct($params=null) { |
78
|
|
|
$this->ci =& /** @scrutinizer ignore-call */ get_instance(); |
79
|
|
|
$this->ci->load->database(); |
80
|
|
|
$this->table_name = self::TABLE_PREFIX . (isset($params["name"]) ? "_" . $params["name"] : ""); |
81
|
|
|
$this->ci->load->database(); |
82
|
|
|
$this->ci->load->splint(self::PACKAGE, "*BlogManager", "bmanager"); |
83
|
|
|
$this->ci->load->splint(self::MARKDOWN_PACKAGE, "+Parsedown", null, "parsedown"); |
84
|
|
|
$this->ci->bmanager->setBlogName(isset($params["name"]) ? $params["name"] : null); |
85
|
|
|
$this->ci->load->helper("url"); |
86
|
|
|
} |
87
|
|
|
/** |
88
|
|
|
* Installs a blog with the given table name and paramters. |
89
|
|
|
* |
90
|
|
|
* @param string $blogName Name of blog tabke to install. |
91
|
|
|
* |
92
|
|
|
* @param string $adminTableName Name of admi table to restrict post to. |
93
|
|
|
* |
94
|
|
|
* @param string $adminIdColumnName Name of the column to add a foreign |
95
|
|
|
* key constarint to the blog table with. |
96
|
|
|
* |
97
|
|
|
* @param int $adminIdColumnConstraint The column constarint or limit of |
98
|
|
|
* $adminIdColumnName. |
99
|
|
|
* |
100
|
|
|
* @return bool True on Success, False if Not. |
101
|
|
|
*/ |
102
|
|
|
public function install(string $blogName=null, string $adminTableName=null, string $adminIdColumnName=null, int $adminIdColumnConstraint=null): bool { |
103
|
|
|
$blogName = $blogName === null ? $this->table_name : self::TABLE_PREFIX . "_" . $blogName; |
104
|
|
|
$this->ci->load->dbforge(); |
105
|
|
|
$this->ci->dbforge->add_field("id"); |
106
|
|
|
$fields = array( |
107
|
|
|
"title" => array( |
108
|
|
|
"type" => "VARCHAR", |
109
|
|
|
"constraint" => 70, |
110
|
|
|
), |
111
|
|
|
"content" => array( |
112
|
|
|
"type" => "TEXT" |
113
|
|
|
), |
114
|
|
|
"date_published" => array( |
115
|
|
|
"type" => "TIMESTAMP", |
116
|
|
|
"null" => true |
117
|
|
|
), |
118
|
|
|
"published" => array( |
119
|
|
|
"type" => "TINYINT", |
120
|
|
|
"default" => 0 |
121
|
|
|
), |
122
|
|
|
"hits" => array( |
123
|
|
|
"type" => "INT", |
124
|
|
|
"constraint" => 7, |
125
|
|
|
"default" => 0 |
126
|
|
|
), |
127
|
|
|
"slug" => array( |
128
|
|
|
"type" => "VARCHAR", |
129
|
|
|
"constraint" => 80, |
130
|
|
|
"unique" => true |
131
|
|
|
) |
132
|
|
|
); |
133
|
|
|
$this->ci->dbforge->add_field($fields); |
134
|
|
|
$constrain = $adminTableName !== null && $adminIdColumnName !== null && |
135
|
|
|
$adminIdColumnConstraint !== null; |
136
|
|
|
if ($constrain) { |
137
|
|
|
$this->ci->dbforge->add_field( |
138
|
|
|
"poster_id INT($adminIdColumnConstraint), FOREIGN KEY (poster_id) REFERENCES $adminTableName($adminIdColumnName)"); |
139
|
|
|
} |
140
|
|
|
$this->ci->dbforge->add_field("date_created TIMESTAMP DEFAULT CURRENT_TIMESTAMP"); |
141
|
|
|
$attributes = array('ENGINE' => 'InnoDB'); |
142
|
|
|
if (!$this->ci->dbforge->create_table($blogName, true, $attributes)) return false; |
143
|
|
|
return true; |
144
|
|
|
} |
145
|
|
|
/** |
146
|
|
|
* Sets the name of the current blog table. |
147
|
|
|
* |
148
|
|
|
* @param string $name name of a blog table. |
149
|
|
|
* |
150
|
|
|
* @deprecated |
151
|
|
|
*/ |
152
|
|
|
public function setName(string $name): void { |
153
|
|
|
$this->table_name = self::TABLE_PREFIX . "_" . $name; |
154
|
|
|
$this->ci->bmanager->setBlogName($name != "" ? $name : null); |
155
|
|
|
} |
156
|
|
|
/** |
157
|
|
|
* Same as the deprecated setName. Sets the name of the current blog table. |
158
|
|
|
* |
159
|
|
|
* @param string $blog [description] |
160
|
|
|
*/ |
161
|
|
|
public function setBlog(string $blog): void { |
162
|
|
|
$this->table_name = self::TABLE_PREFIX . "_" . $blog; |
163
|
|
|
$this->ci->bmanager->setBlogName($blog != "" ? $blog : null); |
164
|
|
|
} |
165
|
|
|
/** |
166
|
|
|
* Gets the name of the blog. |
167
|
|
|
* @return string The name of the blog. |
168
|
|
|
*/ |
169
|
|
|
public function getName(): string { |
170
|
|
|
return $this->table_name; |
171
|
|
|
} |
172
|
|
|
/** |
173
|
|
|
* Loads/echoes the client side scripts needed for the blog to render it's |
174
|
|
|
* post editor and other views. |
175
|
|
|
* |
176
|
|
|
* @param bool $w3css If true, additionally loads the W3.CSS file for additional |
177
|
|
|
* styling. Defaults internally on Blogmanager to true |
178
|
|
|
*/ |
179
|
|
|
private function loadScripts(bool $w3css): void { |
180
|
|
|
$this->ci->load->splint(self::PACKAGE, "-header_scripts", array( |
181
|
|
|
"w3css" => $w3css |
182
|
|
|
)); |
183
|
|
|
} |
184
|
|
|
/** |
185
|
|
|
* Returns the W3.CSS client side script loading tag. |
186
|
|
|
* @return string W3.CSS link tag. |
187
|
|
|
*/ |
188
|
|
|
public function w3css(): string { |
189
|
|
|
return "<link rel=\"stylesheet\" href=\"https://www.w3schools.com/w3css/4/w3.css\">"; |
190
|
|
|
} |
191
|
|
|
/** |
192
|
|
|
* Returns the Fonts Awesome CSS link loading tag. |
193
|
|
|
* @return string Fonts Awesome CSS link loading tag. |
194
|
|
|
*/ |
195
|
|
|
public function fontsAwesome(): string { |
196
|
|
|
return "<link rel=\"stylesheet\" href=\"https://use.fontawesome.com/releases/v5.3.1/css/all.css\""; |
197
|
|
|
} |
198
|
|
|
/** |
199
|
|
|
* Echoes to the browser a 'SimpleMDE' markdown editor for editing post |
200
|
|
|
* contents, as part of a form. |
201
|
|
|
* |
202
|
|
|
* @param string $callback The URI callback that will be passed to the Code |
203
|
|
|
* Igniter form_open method when outputing the form. |
204
|
|
|
* The call back is where you should read the contents |
205
|
|
|
* of the submited form. |
206
|
|
|
* The contents of the form should be read or handled |
207
|
|
|
* by a call to the 'savePost($posterId)' function. |
208
|
|
|
* You don't need to worry about reading it your self. |
209
|
|
|
* |
210
|
|
|
* @param int $postId (Optional) The ID of the post whose content should |
211
|
|
|
* be present in the editor when loaded. provide this |
212
|
|
|
* parameter when you want to edit a post. |
213
|
|
|
* |
214
|
|
|
* @param bool $w3css If true, echoes the W3.CSS link tag as well. |
215
|
|
|
* |
216
|
|
|
* @return bool True if sucessfull without errors, false if not. |
217
|
|
|
*/ |
218
|
|
|
public function loadEditor(string $callback, int $postId=null, bool $w3css=true): bool { |
219
|
|
|
$this->loadScripts($w3css); |
220
|
|
|
$this->ci->load->helper("form"); |
221
|
|
|
$data = array( |
222
|
|
|
"callback" => "Admin/token", |
223
|
|
|
"type" => $postId === null ? "create" : "edit", |
224
|
|
|
"callback" => $callback |
225
|
|
|
); |
226
|
|
|
if ($postId !== null) { |
227
|
|
|
$data["id"] = $postId; |
228
|
|
|
$post = $this->getPost($postId, false); |
229
|
|
|
$data["title"] = $post["title"]; |
230
|
|
|
$data["content"] = $post["content"]; |
231
|
|
|
} |
232
|
|
|
$this->ci->load->splint("francis94c/blog", "-post_edit", $data); |
233
|
|
|
return true; |
234
|
|
|
} |
235
|
|
|
/** |
236
|
|
|
* Handles form data from the Editor loaded by a call to 'loadEditor'. |
237
|
|
|
* Traditionally, this function is to be called ath the controller function |
238
|
|
|
* specified by the callback URI provided to the loadEditor method. |
239
|
|
|
* |
240
|
|
|
* @param int $posterId ID of the poster. A valid admin ID from the table |
241
|
|
|
* specified as a foreign key constraint during the |
242
|
|
|
* installation of the selected blog. |
243
|
|
|
* |
244
|
|
|
* @return string The final action reached in processing the form |
245
|
|
|
* inputs. These are public string constants declared in |
246
|
|
|
* this file. |
247
|
|
|
*/ |
248
|
|
|
public function savePost(int $posterId=null): string { |
249
|
|
|
$action = $this->ci->security->xss_clean($this->ci->input->post("action")); |
250
|
|
|
switch ($action) { |
251
|
|
|
case "save": |
252
|
|
|
return $this->handleSavePost($posterId); |
253
|
|
|
case "publish": |
254
|
|
|
return $this->handlePublishPost($posterId); |
255
|
|
|
case "createAndPublish": |
256
|
|
|
if ($this->ci->bmanager->createAndPublishPost($this->ci->security->xss_clean($this->ci->input->post("title")), $this->ci->security->xss_clean($this->ci->input->post("editor")), $posterId) !== false) return self::CREATE_AND_PUBLISH; |
257
|
|
|
return self::ABORT; |
258
|
|
|
case "delete": |
259
|
|
|
if ($this->ci->bmanager->deletePost($this->ci->security->xss_clean($this->ci->input->post("id")))) return self::DELETE; |
260
|
|
|
return self::ABORT; |
261
|
|
|
default: |
262
|
|
|
return self::NO_ACTION; |
263
|
|
|
} |
264
|
|
|
} |
265
|
|
|
/** |
266
|
|
|
* [handleSavePost handles save pot actions; edit & create] |
267
|
|
|
* |
268
|
|
|
* @param int poster ID or Admin ID. |
|
|
|
|
269
|
|
|
* |
270
|
|
|
* @return string Action taken during the pocess; Blogger::CREATE Or Blogger::EDIT |
271
|
|
|
*/ |
272
|
|
|
private function handleSavePost(int $posterId=null): string { |
273
|
|
|
$id = $this->ci->security->xss_clean($this->ci->input->post("id")); |
274
|
|
|
if ($id != "") { |
275
|
|
|
if (!$this->ci->bmanager->savePost($this->ci->input->post("id"), $this->ci->security->xss_clean($this->ci->input->post("title")), $this->ci->security->xss_clean($this->ci->input->post("editor")), $posterId)) return self::ABORT; |
276
|
|
|
return self::EDIT; |
277
|
|
|
} else { |
278
|
|
|
if ($this->ci->bmanager->createPost($this->ci->security->xss_clean($this->ci->input->post("title")), $this->ci->security->xss_clean($this->ci->input->post("editor")), $posterId) == 0) return self::ABORT; |
279
|
|
|
return self::CREATE; |
280
|
|
|
} |
281
|
|
|
} |
282
|
|
|
/** |
283
|
|
|
* [handlePublishPost handles the publishing of a post using inputs from the |
284
|
|
|
* submited form.] |
285
|
|
|
* |
286
|
|
|
* @param int $posterId ID of the publishing Admin. |
287
|
|
|
|
288
|
|
|
* @return string Action reached while processing form inputs. |
289
|
|
|
*/ |
290
|
|
|
private function handlePublishPost(int $posterId=null): string { |
291
|
|
|
$id = $this->ci->security->xss_clean($this->ci->input->post("id")); |
292
|
|
|
if ($id == "") return self::ABORT; |
293
|
|
|
if (!$this->ci->bmanager->savePost($id, $this->ci->security->xss_clean($this->ci->input->post("title")), $this->ci->security->xss_clean($this->ci->input->post("editor")), $posterId)) return self::ABORT; |
294
|
|
|
if (!$this->ci->bmanager->publishPost($id, true)) return self::ABORT; |
295
|
|
|
return self::PUBLISH; |
296
|
|
|
} |
297
|
|
|
/** |
298
|
|
|
* getPosts get posts from the database by the given $page starting from the |
299
|
|
|
* value of 1 and returns $limit number of rows. |
300
|
|
|
* |
301
|
|
|
* @param int $page Page number starting from 1. |
302
|
|
|
* |
303
|
|
|
* @param int $limit Number of posts to return. |
304
|
|
|
* |
305
|
|
|
* @param bool $filter if true, returns only published posts, if false |
306
|
|
|
* return all posts. false by default. |
307
|
|
|
* |
308
|
|
|
* @param bool $hits If truem orders the returned posts by number of hits. |
309
|
|
|
* |
310
|
|
|
* @return array Array of posts for a given page. |
311
|
|
|
*/ |
312
|
|
|
public function getPosts(int $page, int $limit, bool $filter=false, bool $hits=false): array { |
313
|
|
|
return $this->ci->bmanager->getPosts($page, $limit, $filter, $hits); |
314
|
|
|
} |
315
|
|
|
/** |
316
|
|
|
* [renderPosts description] |
317
|
|
|
* @param [type] $view [description] |
|
|
|
|
318
|
|
|
* @param [type] $empty_view [description] |
319
|
|
|
* @param [type] $page [description] |
320
|
|
|
* @param [type] $limit [description] |
321
|
|
|
* @param boolean $filter [description] |
322
|
|
|
* @param boolean $hits [description] |
323
|
|
|
* @return [type] [description] |
|
|
|
|
324
|
|
|
*/ |
325
|
|
|
public function renderPostItems($view=null, $callback=null, $empty_view=null, $page=1, $limit=5, $filter=false, $hits=false, $slug=true) { |
326
|
|
|
if ($view == null || $empty_view == null) $this->ci->load->bind("francis94c/blog", $blogger); |
327
|
|
|
$posts = $this->getPosts($page, $limit, $filter, $hits); |
328
|
|
|
if (count($posts) == 0) { |
329
|
|
|
if ($empty_view == null) { $blogger->load->view("empty"); } else { |
330
|
|
|
$this->ci->load->view($empty_view); |
331
|
|
|
return true; |
332
|
|
|
} |
333
|
|
|
} |
334
|
|
|
$this->ci->load->helper("text"); |
335
|
|
|
foreach ($posts as $post) { |
336
|
|
|
$post["callback"] = $callback != null ? trim($callback, "/") . "/" . ($slug ? $post["slug"] : $post["id"]) : ""; |
337
|
|
|
$post["filter"] = $filter; |
338
|
|
|
$post["content"] = $this->ci->parsedown->text(ellipsize($post["content"], 300)); |
339
|
|
|
if ($view == null) {$blogger->load->view("post_list_item", $post); } else { |
340
|
|
|
$this->ci->load->view($view, $post); |
341
|
|
|
} |
342
|
|
|
} |
343
|
|
|
return true; |
344
|
|
|
} |
345
|
|
|
/** |
346
|
|
|
* [getRecentPosts description] |
347
|
|
|
* @param integer $limit [description] |
348
|
|
|
* @param boolean $filter [description] |
349
|
|
|
* @return [type] [description] |
|
|
|
|
350
|
|
|
*/ |
351
|
|
|
public function getRecentPosts($limit=5, $filter=false) { |
352
|
|
|
return $this->ci->bmanager->getRecentPosts($limit, $filter); |
353
|
|
|
} |
354
|
|
|
/** |
355
|
|
|
* [renderPost description] |
356
|
|
|
* @param [type] $post [description] |
|
|
|
|
357
|
|
|
* @param [type] $view [description] |
358
|
|
|
* @return [type] [description] |
|
|
|
|
359
|
|
|
*/ |
360
|
|
|
public function renderPost($post, $view=null) { |
361
|
|
|
if (!is_array($post)) $post = $this->ci->bmanager->getPost($post); |
362
|
|
|
if (!$post) return false; |
363
|
|
|
$post["content"] = $this->ci->parsedown->text($post["content"]); |
364
|
|
|
if ($view == null) { |
365
|
|
|
$this->ci->load->splint("francis94c/blog", "-post_item", $post); |
366
|
|
|
} else { |
367
|
|
|
$this->ci->load->view($view, $post); |
368
|
|
|
} |
369
|
|
|
return true; |
370
|
|
|
} |
371
|
|
|
/** |
372
|
|
|
* [metaOg description] |
373
|
|
|
* @param [type] $post [description] |
|
|
|
|
374
|
|
|
* @return [type] [description] |
|
|
|
|
375
|
|
|
*/ |
376
|
|
|
public function metaOg($post) { |
377
|
|
|
$data = array(); |
378
|
|
|
$data["title"] = $post["title"]; |
379
|
|
|
$data["description"] = substr($post["content"], 0, 154); |
380
|
|
|
if (isset($post["share_image"])) $data["image_link"] = $post["share_image"]; |
381
|
|
|
$data["url"] = current_url(); |
|
|
|
|
382
|
|
|
return $this->ci->load->splint(self::PACKAGE, "-meta_og", $data, true); |
383
|
|
|
} |
384
|
|
|
/** |
385
|
|
|
* [getPostsCount description] |
386
|
|
|
* @return [type] [description] |
|
|
|
|
387
|
|
|
*/ |
388
|
|
|
public function getPostsCount() { |
389
|
|
|
return $this->ci->bmanager->getPostsCount(); |
390
|
|
|
} |
391
|
|
|
/** |
392
|
|
|
* [getPost description] |
393
|
|
|
* @param [type] $postId [description] |
|
|
|
|
394
|
|
|
* @return [type] [description] |
|
|
|
|
395
|
|
|
*/ |
396
|
|
|
public function getPost($postId, $hit=true) { |
397
|
|
|
return $this->ci->bmanager->getPost($postId, $hit); |
398
|
|
|
} |
399
|
|
|
/** |
400
|
|
|
* [getHits description] |
401
|
|
|
* @param [type] $postId [description] |
|
|
|
|
402
|
|
|
* @return [type] [description] |
|
|
|
|
403
|
|
|
*/ |
404
|
|
|
public function getHits($postId) { |
405
|
|
|
return $this->ci->bmanager->getHits($postId); |
406
|
|
|
} |
407
|
|
|
/** |
408
|
|
|
* [publishPost description] |
409
|
|
|
* @param [type] $postId [description] |
|
|
|
|
410
|
|
|
* @param [type] $publish [description] |
411
|
|
|
* @return [type] [description] |
|
|
|
|
412
|
|
|
*/ |
413
|
|
|
public function publishPost($postId, $publish) { |
414
|
|
|
return $this->ci->bmanager->publishPost($postId, $publish); |
415
|
|
|
} |
416
|
|
|
/** |
417
|
|
|
* [deletePost description] |
418
|
|
|
* @param [type] $postId [description] |
|
|
|
|
419
|
|
|
* @return [type] [description] |
|
|
|
|
420
|
|
|
*/ |
421
|
|
|
public function deletePost($postId) { |
422
|
|
|
return $this->ci->bmanager->deletePost($postId); |
423
|
|
|
} |
424
|
|
|
/** |
425
|
|
|
* [searchPosts description] |
426
|
|
|
* @param [type] $words [description] |
|
|
|
|
427
|
|
|
* @param [type] $page [description] |
428
|
|
|
* @param integer $limit [description] |
429
|
|
|
* @param boolean $filter [description] |
430
|
|
|
* @return [type] [description] |
|
|
|
|
431
|
|
|
*/ |
432
|
|
|
public function searchPosts($words, $page, $limit=0, $filter=false) { |
433
|
|
|
return $this->ci->bmanager->searchPosts($words, $page, $limit, $filter); |
434
|
|
|
} |
435
|
|
|
} |
436
|
|
|
|
The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g.
excluded_paths: ["lib/*"]
, you can move it to the dependency path list as follows:For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths