Blogger::renderPostItems()   B
last analyzed

Complexity

Conditions 9
Paths 38

Size

Total Lines 19
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 5
Bugs 0 Features 0
Metric Value
cc 9
eloc 14
c 5
b 0
f 0
nc 38
nop 8
dl 0
loc 19
rs 8.0555

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

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
   * [getBlogManager Returns the BlogManager Model object.]
174
   * 
175
   * @return BlogManager BlogManager Model Object.
176
   */
177
  public function &getBlogManager(): BlogManager {
178
    return $this->ci->bmanager;
179
  }
180
  /**
181
   * Loads/echoes the client side scripts needed for the blog to render it's
182
   * post editor and other views.
183
   *
184
   * @param  bool $w3css If true, additionally loads the W3.CSS file for additional
185
   *                     styling. Defaults internally on Blogmanager to true
186
   */
187
  private function loadScripts(bool $w3css): void {
188
    $this->ci->load->splint(self::PACKAGE, "-header_scripts", array(
189
      "w3css" => $w3css
190
    ));
191
  }
192
  /**
193
   * Returns the W3.CSS client side script loading tag.
194
   * @return string W3.CSS link tag.
195
   */
196
  public function w3css(): string {
197
    return "<link rel=\"stylesheet\" href=\"https://www.w3schools.com/w3css/4/w3.css\">";
198
  }
199
  /**
200
   * Returns the Fonts Awesome CSS link loading tag.
201
   * @return string Fonts Awesome CSS link loading tag.
202
   */
203
  public function fontsAwesome(): string {
204
    return "<link rel=\"stylesheet\" href=\"https://use.fontawesome.com/releases/v5.3.1/css/all.css\"/>";
205
  }
206
  /**
207
   * Echoes to the browser a 'SimpleMDE' markdown editor for editing post
208
   * contents, as part of a form.
209
   *
210
   * @param  string  $callback The URI callback that will be passed to the Code
211
   *                           Igniter form_open method when outputing the form.
212
   *                           The call back is where you should read the contents
213
   *                           of the submited form.
214
   *                           The contents of the form should be read or handled
215
   *                           by a call to the 'savePost($posterId)' function.
216
   *                           You don't need to worry about reading it your self.
217
   *
218
   * @param  int     $postId   (Optional) The ID of the post whose content should
219
   *                           be present in the editor when loaded. provide this
220
   *                           parameter when you want to edit a post.
221
   *
222
   * @param  bool    $w3css    If true, echoes the W3.CSS link tag as well.
223
   *
224
   * @return bool              True  if sucessfull without errors, false if not.
225
   */
226
  public function loadEditor(string $callback, int $postId=null, bool $w3css=true): bool {
227
    $this->loadScripts($w3css);
228
    $this->ci->load->helper("form");
229
    $data = array(
230
      "callback" => "Admin/token",
231
      "type"     => $postId === null ? "create" : "edit",
232
      "callback" => $callback
233
    );
234
    if ($postId !== null) {
235
      $data["id"] = $postId;
236
      $post = $this->getPost($postId, false);
237
      $data["title"] = $post["title"];
238
      $data["content"] = $post["content"];
239
    }
240
    $this->ci->load->splint("francis94c/blog", "-post_edit", $data);
241
    return true;
242
  }
243
  /**
244
   * Handles form data from the Editor loaded by a call to 'loadEditor'.
245
   * Traditionally, this \function is to be called ath the controller function
246
   * specified by the callback URI provided to the loadEditor method.
247
   *
248
   * @param  int $posterId ID of the poster. A valid admin ID from the table
249
   *                       specified as a foreign key constraint during the
250
   *                       installation of the selected blog.
251
   *
252
   * @return string        The final action reached in processing the form
253
   *                       inputs. These are public string constants declared in
254
   *                       this file.
255
   */
256
  public function savePost(int $posterId=null): string {
257
    $action = $this->ci->security->xss_clean($this->ci->input->post("action"));
258
    switch ($action) {
259
      case "save":
260
        return $this->handleSavePost($posterId);
261
      case "publish":
262
        return $this->handlePublishPost($posterId);
263
      case "createAndPublish":
264
        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;
265
        return self::ABORT;
266
      case "delete":
267
        if ($this->ci->bmanager->deletePost($this->ci->security->xss_clean($this->ci->input->post("id")))) return self::DELETE;
268
        return self::ABORT;
269
      default:
270
        return self::NO_ACTION;
271
    }
272
  }
273
  /**
274
   * [handleSavePost handles save pot actions; edit & create]
275
   *
276
   * @param  int     $posterId  Poster ID or Admin ID.
277
   *
278
   * @return string             Action taken during the pocess; Blogger::CREATE Or Blogger::EDIT
279
   */
280
  private function handleSavePost(int $posterId=null): string {
281
    $id = $this->ci->security->xss_clean($this->ci->input->post("id"));
282
    if ($id != "") {
283
      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;
284
      return self::EDIT;
285
    } else {
286
      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;
287
      return self::CREATE;
288
    }
289
  }
290
  /**
291
   * [handlePublishPost handles the publishing of a post using inputs from the
292
   *  submited form.]
293
   *
294
   * @param  int    $posterId ID of the publishing Admin.
295
296
   * @return string           Action reached while processing form inputs.
297
   */
298
  private function handlePublishPost(int $posterId=null): string {
299
    $id = $this->ci->security->xss_clean($this->ci->input->post("id"));
300
    if ($id == "") return self::ABORT;
301
    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;
302
    if (!$this->ci->bmanager->publishPost($id, true)) return self::ABORT;
303
    return self::PUBLISH;
304
  }
305
  /**
306
   * getPosts get posts from the database by the given $page starting from the
307
   * value of 1 and returns $limit number of rows.
308
   *
309
   * @param  int     $page   Page number starting from 1.
310
   *
311
   * @param  int     $limit  Number of posts to return.
312
   *
313
   * @param  bool    $filter if true, returns only published posts, if false
314
   *                         return all posts. false by default.
315
   *
316
   * @param  bool    $hits   If truem orders the returned posts by number of hits.
317
   *
318
   * @return array           Array of posts for a given page.
319
   */
320
  public function getPosts(int $page, int $limit, bool $filter=false, bool $hits=false): array {
321
    return $this->ci->bmanager->getPosts($page, $limit, $filter, $hits);
322
  }
323
  /**
324
   * [renderPosts render post items by page number, max page count, and specified
325
   * view files.]
326
   * @param  string  $view       Custom view per post summary to use, from
327
   *                             end-user application context.
328
   *
329
   * @param  string  $callback   Callback URI that should render a full post for
330
   *                             each of the post items. This callback URI will
331
   *                             have the ID of each respective post, appended to
332
   *                             the end of it for each of the post itesm.
333
   *
334
   * @param  string  $empty_view View to load if blog has no posts, form end-user context.
335
   *
336
   * @param  int     $page       Page Number of pot list.
337
   *
338
   * @param  int     $limit      Max post summary per page.
339
   *
340
   * @param  boolean $filter     If true, ommits un-published posts.
341
   *
342
   * @param  boolean $hits       If true, orders returned posts by hits.
343
   *
344
   * @return bool                True if successful, false if not.
345
   */
346
  public function renderPostItems(string $view=null, string $callback=null, string $empty_view=null, int $page=1, int $limit=5, bool $filter=false, bool $hits=false, bool $slug=true): bool {
347
    if ($view === null || $empty_view === null) $this->ci->load->bind("francis94c/blog", $blogger);
348
    $posts = $this->getPosts($page, $limit, $filter, $hits);
349
    if (count($posts) == 0) {
350
      if ($empty_view === null) { $blogger->load->view("empty"); } else {
351
        $this->ci->load->view($empty_view);
352
        return true;
353
      }
354
    }
355
    $this->ci->load->helper("text");
356
    foreach ($posts as $post) {
357
      $post["callback"] = $callback !== null ? trim($callback, "/") . "/" . ($slug ? $post["slug"] : $post["id"]) : "";
358
      $post["filter"] = $filter;
359
      $post["content"] = $this->ci->parsedown->text(ellipsize($post["content"], 300));
360
      if ($view === null) {$blogger->load->view("post_list_item", $post); } else {
361
        $this->ci->load->view($view, $post);
362
      }
363
    }
364
    return true;
365
  }
366
  /**
367
   * [getRecentPosts gets most recent post, limits number returned with $limit.]
368
   *
369
   * @param  int  $limit  Number of Posts.
370
   *
371
   * @param  bool $filter If true, returns only published posts.
372
   *
373
   * @return array        Array of posts ordered by ID (Most recent first).
374
   */
375
  public function getRecentPosts(int $limit=5, bool $filter=false): array {
376
    return $this->ci->bmanager->getRecentPosts($limit, $filter);
377
  }
378
  /**
379
   * [renderPost renders a single blog post. uses it's default view if not
380
   * provided a $view]
381
   *
382
   * @param  array|int|string $post A post array, ID or Slug.
383
   *
384
   * @param  string           $view An alternate view to use for the body of the
385
   *                                post.
386
   *
387
   * @return bool             True if successful, false if not.
388
   */
389
  public function renderPost($post, string $view=null): bool {
390
    if (!is_array($post)) $post = $this->ci->bmanager->getPost($post);
391
    if (!$post) return false;
392
    $post["content"] = $this->ci->parsedown->text($post["content"]);
393
    if ($view === null) {
394
      $this->ci->load->splint("francis94c/blog", "-post_item", $post);
395
    } else {
396
      $this->ci->load->view($view, $post);
397
    }
398
    return true;
399
  }
400
  /**
401
   * [metaOg A utility \function that generates Open Graph HTML tags from a post
402
   * array. This \function should be hit from the controller method that loads a
403
   * post for correct results as there's a call to the 'current_url' of Code
404
   * Igniter's url helper here.]
405
   *
406
   * @param  array   $post Post array.
407
   *
408
   * @return string        Open Graph HTML Meta Tags.
409
   */
410
  public function metaOg(array $post): string {
411
    $data = array();
412
    $data["title"] = $post["title"];
413
    $data["description"] = substr($post["content"], 0, 154);
414
    if (isset($post["share_image"])) $data["image_link"] = $post["share_image"];
415
    $data["url"] = current_url();
416
    // Return Meta OG View String.
417
    return $this->ci->load->splint(self::PACKAGE, "-meta_og", $data, true);
418
  }
419
  /**
420
   * [getPostsCount gets total number of posts in the current blog]
421
   *
422
   * TODO: Get for a given blog.
423
   *
424
   * @param  bool $filter If true, counts only published posts. True by default.
425
   *
426
   * @return int          Posts count.
427
   */
428
  public function getPostsCount(bool $filter=true): int {
429
    return $this->ci->bmanager->getPostsCount($filter);
430
  }
431
  /**
432
   * [getPost gets a post array.]
433
   *
434
   * @param  int    $postId ID of the post to retrieve.
435
   *
436
   * @param  bool   $hit    Increment the post's hit count.
437
   *
438
   * @return array          An associative array of a single post.
439
   */
440
  public function getPost($postId, $hit=true) {
441
    return $this->ci->bmanager->getPost($postId, $hit);
442
  }
443
  /**
444
   * [getHits gets the number of hits for a particular post.]
445
   *
446
   * @param  int    $postId Post ID.
447
   *
448
   * @return int            Number of hits (Times viewed or read).
449
   */
450
  public function getHits(int $postId): int {
451
    return $this->ci->bmanager->getHits($postId);
452
  }
453
  /**
454
   * [publishPost Publish or Un Publish a Post.]
455
   * @param  int    $postId  Post ID
456
   * @param  bool   $publish Publish Or Un-Publish
457
   * @return bool            True if operation was successful, False if not.
458
   */
459
  public function publishPost(int $postId, bool $publish): bool {
460
    return $this->ci->bmanager->publishPost($postId, $publish);
461
  }
462
  /**
463
   * [deletePost Deletes a Post.]
464
   *
465
   * @param  int    $postId Post ID
466
   *
467
   * @return bool           True if successful, false if not.
468
   */
469
  public function deletePost(int $postId): bool {
470
    return $this->ci->bmanager->deletePost($postId);
471
  }
472
  /**
473
   * [searchPosts Searches through posts in the blog/database.]
474
   *
475
   * @param  string  $words  Word/Phrase to search for in Title and Content
476
   *                         fields.
477
   *
478
   * @param  int     $page   Page Number to retrive from result. Default is 1
479
   *
480
   * @param  int     $limit  The max number peer page. Default is 5.
481
   *
482
   * @param  bool    $filter If true, returns only matched pulished posts, else
483
   *                         returns all matched posts.
484
   *
485
   * @return array           Array of matched posts.
486
   */
487
  public function searchPosts(string $words, int $page=1, int $limit=5, bool $filter=false): array {
488
    return $this->ci->bmanager->searchPosts($words, $page, $limit, $filter);
489
  }
490
}
491